字谜平方数
作者: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; } } } } }