{$s=eval join'+',@d=grep!($n%$_),1.. ++$n-1;eval{w(@d,$n)if$s>$n};print$n ,$/if$@=~/!/;redo}sub w{my$s=pop|| die;my$t=pop||die'!';eval{w(@_,$s-$t )},$@=~/!/||die if$t<=$s;w(@_,$s)} #### { $s=eval join'+', @d = grep !($n%$_), 1..++$n-1; eval { w(@d, $n) if $s > $n}; print $n,$/ if $@ =~ /!/; redo } sub w{ my $s = pop || die; my $t = pop || die '!'; eval { w( @_, $s-$t) }, $@ =~ /!/ || die if $t <= $s; w( @_, $s) } #### { $s=eval join'+', @d = grep !($n%$_), 1..++$n-1; eval { w(@d, $n) if $s > $n}; print $n,$/ if $@ =~ /!/; redo } #### sub w{ my $s = pop || die; my $t = pop || die '!'; eval { w( @_, $s-$t) }, $@ =~ /!/ || die if $t <= $s; w( @_, $s) } #### w(1,2,3,4,6, 12); w(1,2,3,4, 6); w(1,2,3, 2); w(1,2, 2); die (2 == 2), therefore 12 is semiperfect #### w(1,7,11,14,18, 21) w(1,7,11,14, 3) #21 - 18 becomes new product, toss onto the end # 14 > 3, ignore it, continue w(1,7,11, 3) # 11 > 3, ignore it, continue w(1,7, 3) # 7 > 3, ignore it, continue w(1, 3) # 1 <= 3, subtract from 3, continue w(2) #pop off our sum (2), and our test digit. Oops! #No test digit, die with a bang, we failed. #hops all the way back up to here, throws away 18, and continues. #it has determined there is no subset that contains 18 and adds to 21. w(1,7,11,14, 21) w(1,7,11, 7) #21 - 14 becomes new product, toss onto the end # 11 > 7, ignore it, continue w(1,7, 7) # 7 <= 7, subtract it from 7, continue w(1, 0) #pops off the sum, which is 0 in this case, so we've succeeded. "die" with no bang -> success!