I was shown those three problems the other day on http://www.itasoftware.com/careers/programmers.php, and spent a decent amount of time solving them. My solution for 9 nines ran in about 15 seconds on my celeron system here. I've also answered the other two problems, and was verified by the CTO of ITA Software for all 3.
#!/usr/bin/perl use strict; use Data::Dumper; $|++; my %PossibleTotals = (); %{$PossibleTotals{1}} = (9, "9"); %{$PossibleTotals{2}} = (9+9, "(9+9)", 9-9, "(9-9)", 9*9, "(9*9)", 9/9 +, "(9/9)"); foreach my $WhichNine (3..9) { print "Working $WhichNine\n"; for (my $Count = 1; $Count <= $WhichNine / 2; $Count++) { # print "Doing $Count, $WhichNine - $Count\n"; foreach my $Column1 (keys %{$PossibleTotals{$Count}}) { foreach my $Column2 (keys %{$PossibleTotals{$WhichNine - +$Count}}) { ${$PossibleTotals{$WhichNine}}{$Column1 + $Column2} = + "(" . ${$PossibleTotals{$Count}}{$Column1} . "+" . +${$PossibleTotals{$WhichNine - $Count}}{$Column2} . ")"; ${$PossibleTotals{$WhichNine}}{abs($Column1 - $Column +2)} = "(" . ${$PossibleTotals{$Count}}{$Column1} . "-" . +${$PossibleTotals{$WhichNine-$Count}}{$Column2} . ")"; ${$PossibleTotals{$WhichNine}}{$Column1 * $Column2} = + "(" . ${$PossibleTotals{$Count}}{$Column1} . "*" . +${$PossibleTotals{$WhichNine-$Count}}{$Column2} . ")"; ${$PossibleTotals{$WhichNine}}{sprintf("%.15f", $Colu +mn1 / $Column2)} = "(" . ${$PossibleTotals{$Count}}{$Column1} . "/" . +${$PossibleTotals{$WhichNine-$Count}}{$Column2} . ")" if ($Column2 != + 0); ${$PossibleTotals{$WhichNine}}{sprintf("%.15f", $Colu +mn2 / $Column1)} = "(" . ${$PossibleTotals{$WhichNine-$Count}}{$Column +2} . "/" . ${$PossibleTotals{$Count}}{$Column1} . ")" if ($Column1 != + 0); } } } } print "finished calculating\n"; my (@FoundNumbers) = (); my %TempHash = (); foreach (keys %{$PossibleTotals{9}}) { {$TempHash{int($_)} = 1 if (($_ < 10000) && (int($_) == sprintf("% +.7f", $_))); print "$_ : ${$PossibleTotals{9}}{$_}\n" if $_ =~ /^19[45]\./; } (@FoundNumbers) = sort {$a<=>$b} keys (%TempHash); my $Count = 0; while (@FoundNumbers) { my $Number = shift(@FoundNumbers); if (($Count == $Number) && (${$PossibleTotals{9}}{$Number} =~ /[9\ +D]{9}/g)) { print "$Number = " .${$PossibleTotals{9}}{$Number} . "\n"; } else { print "The first number missed is $Number\n"; last; } $Count++; }

Replies are listed 'Best First'.
Re (tilly) 1: As per Tilly, The 9 nines solution
by tilly (Archbishop) on Feb 07, 2002 at 07:06 UTC
    Well actually I was thinking more like...
    #! /usr/bin/perl use strict; use Getopt::Std; getopts('v'); use vars qw($opt_v @find_in); # Set up my array of hashes of how to find various numbers with # n 9's. @find_in =( {}, # None of size 0! { 9 => '9' }, # 2 with 1 9 map {}, 2..9 ); foreach my $i (1..9) { print "Searching depth $i\n" if $opt_v; my $find_in_a = $find_in[$i]; foreach my $j (1..$i) { next if 9 < $i + $j; print " Searching combinations of $i, $j\n" if $opt_v; my $find_in_b = $find_in[$j]; my $find_in_sum = $find_in[ $i+$j ]; foreach my $val_a (keys %$find_in_a) { my $expr_a = $find_in_a->{$val_a}; foreach my $val_b (keys %$find_in_b) { my $expr_b = $find_in_b->{$val_b}; $find_in_sum->{$val_a + $val_b} = "($expr_a + $expr_b)"; $find_in_sum->{$val_a * $val_b} = "($expr_a * $expr_b)"; if ($val_a < $val_b) { $find_in_sum->{$val_b - $val_a} = "($expr_b - $expr_a)"; } else { $find_in_sum->{$val_a - $val_b} = "($expr_a - $expr_b)"; } if (0 != $val_b) { $find_in_sum->{$val_a / $val_b} = "($expr_a / $expr_b)"; } if (0 != $val_a) { $find_in_sum->{$val_b / $val_a} = "($expr_b / $expr_a)"; } } } } } my $ans = 0; while (exists $find_in[9]{$ans}) { print "$ans\t$find_in[9]{$ans}\n" if $opt_v; $ans++; } print "ANSWER: $ans\n";
    There are several optimizations here, primarily the (ab)use of the fact that there is a +- symmetry in values reached, so you can actually avoid worrying about the negative values you can reach. (You know that they are mirrored on the positive side.)

    You can optimize further by not tracking information about the expressions that lead to specific values. But not as much as you would expect. You can optimize more by switching languages to use data structures that avoid stringification of values...

Re: As per Tilly, The 9 nines solution
by BeernuT (Pilgrim) on Feb 06, 2002 at 23:57 UTC
    I am having a hard time getting this code to work. seems to be a problem with
    foreach keys (%{$PossibleTotals{9}} { {$TempHash{int($_)} = 1 if (($_ < 10000) && (int($_) == sprintf("% +.7f", $_))); print "$_ : ${$PossibleTotals{9}}{$_}\n" if $_ =~ /^19[45]\./; }
    Error msg: Missing $ on loop variable at ./nine line 31.

    -bn most likely better written as
    foreach (keys %{$PossibleTotals{9}) {

    but still has problems running under use strict;
    -bn
    better yet. let me give you a piece of code without a typo :)

    foreach (keys %{$PossibleTotals{9}}) { $TempHash{int($_)} = 1 if (($_ < 10000) && (int($_) == sprintf +("%.7f", $_))); print "$_ : ${$PossibleTotals{9}}{$_}\n" if $_ =~ /^19[45]\./; }

    so what it looks like is a missplaced (, a missing ) and an extra {

    -bn