#!/usr/bin/perl
use strict;
use warnings;
# steve the gambler problem solution
# http://www.destraynor.com/serendipity/index.php?/archives/113-Steve-the-Gambler-Caught-by-the-IRS.html
#
# pretty naive, unoptimized, no-error checking implementation
#
# given : list of values (@num array)
# required : find $nnum values such that they add up to zero.
#
# dmitry@river:~/workspace$ time ./irs.pl
# 1000
# Result: -50 -21 13 171 14 -42 -58 -65 38
#
# real 0m0.023s
# user 0m0.016s
# sys 0m0.008s
my @num = (-50,-21,13,171,14,-42,-58,109,4,7,-23,-44,-98,-121,101, 33,87,-121,-40,-65,43,54,-45,-12,-12,38,25,3,7,8);
my $nnum = 9;
my $tot = 0;
sub f
{
# where we.re at in the array
my $index = shift;
# current list of possible values
my $a_ref = shift;
# stats, total number of iterations
$tot++;
unless ($tot % 1000)
{
print .$totn.;
}
# if the list of possible values is over the required length, might as well terminate.
if (scalar(@$a_ref) > $nnum)
{
return $a_ref;
}
# keep looking for a solution until we hit the end of the array
while ($index < scalar(@num))
{
# add the next possible element to the list of values
push @$a_ref, $num[$index];
# solve the sub problem
f(++$index, $a_ref);
# see whether we have a solution
my $sum = 0;
map { $sum += $_; } @$a_ref;
if ($sum == 0 && scalar(@$a_ref) == $nnum)
{
return @$a_ref;
}
# nope, the last value we added in this frame will not get us where we need to go
# so discard it.
pop @$a_ref;
}
return @$a_ref;
}
my $ref = [];
f(0, $ref);
print .Result: @{$ref} n.;
- View this file Here (Right Click and save As)