Since others are posting, here is my original code. It
uses a slightly different tactic, which I hoped would
be a bit of an optimization (though I don't think it
actually was) When I generate my triangular numbers, I
also calculate a "pattern mask", i.e.
THREE => 'abcdd'
55345 => 'aabca'
66456 => 'aabca'
98766 => 'abcdd' (aha, same as THREE's)
So: wordmask('THREE') eq wordmask(98766);
This was supposed to eliminate running repeated regexes
against the same numbers. Anyway, it complicates the code a bit and others have submitted faster solutions using
the same basic algorithm.
Anyway here is the code:
#!/usr/bin/perl
use strict;
# Calculate some "masks" outside the loops
my (%nummasks,%wordmasks);
map{my $k=.5*$_*($_+1); $nummasks{$k}=wordmask($k)}1..446; # ok, this
+line was tweaked from another poster
map{$wordmasks{$_}=wordmask($_)}('ONE','THREE','SIX','TEN');
# Loop through the THREE candidates
for my $three (keys %nummasks) {
next unless $nummasks{$three} eq $wordmasks{'THREE'};
my @three = split(//,$three);
# Loop through the TEN candidates
for my $ten (keys %nummasks) {
next unless $nummasks{$ten} eq $wordmasks{'TEN'};
my @ten = split(//,$ten);
next unless $ten[0] == $three[0] && $ten[1] == $three[3];
my %used = map{$_,1} (@three);
next if $used{$ten[2]};
# Loop through the ONE candidates
for my $one (keys %nummasks) {
next unless $nummasks{$one} eq $wordmasks{'ONE'};
my @one = split(//,$one);
next unless $one[1] == $ten[2] && $one[2] == $ten[1];
my %used = map{$_,1} (@three,@ten);
next if $used{$one[0]};
# Find a SIX and we've solved it
for my $six (keys %nummasks) {
next unless $nummasks{$six} eq $wordmasks{'SIX'};
my @six = split(//,$six);
my %used = map{$_,1} (@three,@ten,@one);
next if $used{$six[0]} || $used{$six[1]} || $used{$six[2]};
print "ONE:\t$one\nTHREE:\t$three\nSIX:\t$six\nTEN:\t$ten\n";
}
}
}
}
sub wordmask { # generate a "pattern mask", 56675 => abbca
my $mask = shift;
my $letter = 'a';
while ($mask =~ /([^a-z])/) {
$mask =~ s/$1/$letter/g;
$letter++;
}
return $mask;
}
$ time ./abigails.pl
ONE = 435; THREE = 17955; SIX = 820; TEN = 153.
0.06user 0.00system 0:00.07elapsed 83%CPU
$ time ./mine.pl
ONE: 435
THREE: 17955
SIX: 820
TEN: 153
0.25user 0.01system 0:00.26elapsed 98%CPU
So, Abigail's beats mine by a factor of about 4.5!
-Blake