#!/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";