字谜平方数
作者:Andrei Osipov
https://projecteuler.net/problem=98
将单词 CARE 中的每个字母分别替换为 1、2、9 和 6,我们可以得到一个平方数:1296 = 36²。值得注意的是,使用相同的数字替换,其字谜 RACE 也能构成一个平方数:9216 = 96²。我们将 CARE(和 RACE)称为平方字谜词对,并进一步规定不允许出现前导零,也不允许不同的字母具有相同的数字值。
使用 words.txt https://projecteuler.net/project/resources/p098_words.txt(一个包含近两千个常用英语单词的 16K 文本文件),找出所有平方字谜词对(回文词不视为自身的字谜)。
由任何此类词对成员构成的最大平方数是多少?
注意:所有形成的字谜都必须包含在给定的文本文件中。
use v6;
sub correspond([$word1, $word2], [$num1, $num2]) {
$word2.trans($word1 => ~$num1) eq $num2 &&
$num2.trans( ~$num1 => $word1) eq $word2;
}
sub anagrams(@x) {
my %aux;
my %result;
%aux{$_.comb.sort.join}.push: $_
for @x;
for %aux.kv -> $k, @v {
next if +@v < 2; ;
%result{@v[0].chars}.push:
+@v == 2
?? @v.item
!! |@v.combinations(2).map(*.item);
}
%result;
}
sub MAIN(Bool :$verbose = False,
Str :$file = $*SPEC.catdir($*PROGRAM-NAME.IO.dirname, 'words.txt')) {
die "$file is missing" unless $file.IO.e;
my @words = sort unique $file.IO.slurp.split: / <[,"]>+ /;
my %words = anagrams(@words);
my $longest-word = %words.keys.max;
my %squares = anagrams(
(1 ... (10**($longest-word + 1).sqrt)) »**» 2
);
say max do for 3 ... $longest-word -> \size {
next unless %words{size};
|do for @(%words{size}) -> @pair {
next unless %squares{size};
|do for @(%squares{size}) -> @nums {
if correspond(@pair, @nums) {
$verbose and say "@pair[] => @nums[]" ;
max @nums;
}
}
}
}
}
Perl 6 示例