wesley.kueppo's blog

WeirdNumber.pl

Again another simple and naive approach.

We first need to get the list of divisors of $n then iterate through these divisors to find if they exist a subset whose sum of it elements equals $n.

Prerequisite

  1. Get the list of divisors.
sub get_divisors {
	my($number, @fdiv, @sdiv) = (shift);

	if ($number > 3) {
		foreach (2..sqrt $number) {
			if ($number % $_ == 0) {
				push @sdiv, $number / $_;
				push @fdiv, $_ if ($number / $_ != $_);
			}
		}
	}

	(1, @fdiv, reverse @sdiv)
}

WeirdNumber.pl

#!/usr/bin/env perl

use strict;
use warnings;

### HELPER
# Find all divisors of $n
sub get_divisors {
	my($number, @fdiv, @sdiv) = (shift);

	if ($number > 3) {
		foreach (2..sqrt $number) {
			if ($number % $_ == 0) {
				push @sdiv, $number / $_;
				push @fdiv, $_ if ($number / $_ != $_);
			}
		}
	}

	(1, @fdiv, reverse @sdiv)
}

### MAIN
sub is_weird {
	my(@track, @subset) = ();
	my($number, $sum) = (shift, 0);
	my @divisors = get_divisors $number;

	$sum += $_ foreach (@divisors);
	if ($sum > $number) {
		my $now = 0;
		LOOP: {
			foreach (@divisors) {
				if ($now + $_ == $number) {
					$now += $_;
					push @subset, $_;
					last;
				} elsif ($now + $_ < $number) {
					$now += $_;
					push @subset, $_;
					push @track, $_;
				} else {
					# Backtracking
					$now = $_;
					@subset = ($_);
					foreach (reverse @track) {
						if ($now + $_ < $number) {
							$now += $_;
							push @subset, $_;
						} elsif ($now + $_ == $number) {
							$now += $_;
							push @subset, $_;
							last LOOP;
						}
					}
					@track = ($_);
				}
			}
		}
		if ($now == $number) {
			print "Output: 1\n";
			print "proper divisors: @divisors\n";
			print "subset: @subset => sum = $number\n";
		 } else {
			print "Output: 0\n";
			print "proper divisors: @divisors\n";
			print "No subset of these sums to $number\n";
		 }
	} else {
		print "Output: 1\n";
		print "Total sum of the divisors = $sum < $number\n";
	}
}

print "Input: ";
my $input = <STDIN>;
is_weird $input;

#mathematics #perl #theweeklychallenge #weirdnumbers