#!/usr/bin/perl -w use strict; my $time = time(); my (%tri,@pos,@pos1,@pos2,@pos3); # make hash of tiangular numbers 5 digits or less # the 447th has 6 digits so we don't map past 446 map{$tri{.5*$_*($_+1)}=1}1..446; # find all possible matches for 'three' # these are 5 digits long, but last two digits are the same # this allows us to limit the search for my $key(keys %tri){ push @pos,$1 if $key =~/(\d\d\d(\d)\2)/; } # let's see how many possibilities we have print "Initially we have ".@pos." possibles for \$t\$h\$r\$e\$e\n"; print "$_\n" for @pos; # find all possible matches for 'ten' within constraint # of $t and $e possibilities generated above, we are looking for 'n' for (@pos) { my($t,$h,$r,$e)=split'',$_; for my $n(0..9) { push @pos1, "$t$h$r$e$n" if defined $tri{"$t$e$n"} } } # let's see how many possibilities we have left print "\nNext we have ".@pos1." possibles for \$t\$h\$r\$e\$n\n"; print "$_\n" for @pos1; #now look at 'one' in same way, we are looking for 'o' for (@pos1) { my($t,$h,$r,$e,$n)=split'',$_; for my $o(0..9) { push @pos2, "$t$h$r$e$n$o" if defined $tri{"$o$n$e"} } } # let's see how many possibilities we have left print "\nNow we have ".@pos2." possibles for \$t\$h\$r\$e\$n\$o\n"; print "$_\n" for @pos2; # remove dulicates where digits for $t$h$r$e$n$o are not unique # I'm sure there is something more elegant but this works for (@pos2) { $_ =~ /(.)(.)(.)(.)(.)(.)/; push @pos3,$_ if $_=~m/[^$2$3$4$5$6][^$1$3$4$5$6][^$1$2$4$5$6][^$1$2$3$5$6][^$1$2$3$4$6][^$1$2$3$4$5]/; } # let's see how many possibilities we have left print "\nAfter removing cases where we have duplicate digits\n"; print "we have ".@pos3." possible matches for \$t\$h\$r\$e\$n\$o\n"; print "$_\n" for @pos3; # find the solution for my $pos(@pos3) { # get the remaining digits available for 'six' # we erase the 6 digits we are currently using # for t h r e n o my $remaining = '0123456789'; for (split'',$pos) {$remaining =~ s/$_//;} # look at the remaining cases print "\nBrute forcing\n"; print "If \$t\$h\$r\$e\$n\$o\ is $pos then \$s\$i\$x must come from $remaining\n\n"; # brute force possibilities for six, it's only 4 digits my @rem = split'',$remaining; for my $s(@rem){ i: for my $i(@rem){ next i if $i==$s; x: for my $x(@rem) { next x if $x==$i or $x==$s; if (defined $tri{"$s$i$x"}){ my($t,$h,$r,$e,$n,$o)=split'',$pos; # prove we are right! print "\nfound solution\n"; print "###################################\n"; print "one $o$n$e " if defined $tri{"$o$n$e"}; print "three $t$h$r$e$e " if defined $tri{"$t$h$r$e$e"}; print "six $s$i$x " if defined $tri{"$s$i$x"}; print "ten $t$e$n\n" if defined $tri{"$t$e$n"}; print "###################################\n\n"; } else {print "No match \$s\$i\$x -> $s$i$x\n"} } } } } $time = time()-$time; print "\nElapsed $time seconds\n";