098 Anagramic squares.pl 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Website: https://github.com/trizen
  5. # https://projecteuler.net/problem=98
  6. use 5.010;
  7. use strict;
  8. use warnings;
  9. # usage: perl script.pl < p098_words.txt
  10. my @list = eval("(" . do { local $/; <> } . ")");
  11. my %anagrams;
  12. foreach my $word (@list) {
  13. push @{$anagrams{join '', sort split //, $word}}, $word;
  14. }
  15. my %squares;
  16. foreach my $i (1 .. 1000) { # first tried with 1..9999999
  17. my $s = $i**2;
  18. push @{$squares{length($s)}}, $s;
  19. }
  20. foreach my $key (
  21. map { $_->[1] }
  22. sort { $b->[0] <=> $a->[0] }
  23. map { [length($_), $_] }
  24. keys %anagrams
  25. ) {
  26. my $len = length($key);
  27. my @words = @{$anagrams{$key}};
  28. foreach my $sq (@{$squares{$len}}) {
  29. for my $i (0 .. $#words - 1) {
  30. my $word = $words[$i];
  31. my %table;
  32. @table{split //, $word} = split(//, $sq);
  33. do {
  34. my %seen;
  35. grep { !$seen{$_}++ } values %table;
  36. } == $len or next;
  37. for my $j ($i + 1 .. $#words) {
  38. my @chars = split(//, $words[$j]);
  39. next if $table{$chars[0]} eq '0';
  40. my $n = join('', @table{@chars});
  41. if (index(sqrt($n), '.') == -1) {
  42. say "$sq -- $n ($words[$i], $words[$j])";
  43. }
  44. }
  45. }
  46. }
  47. }