fork download
  1. #!/usr/bin/perl
  2. use 5.016;
  3. use warnings;
  4. use List::Util qw(reduce);
  5.  
  6. my $table = [ map{ [ split // ] } split(/\n/, <<'EOF') ];
  7. WVERTICALL
  8. ROOAFFLSAB
  9. ACRILIATOA
  10. NDODKONWDC
  11. DRKESOODDK
  12. OEEPZEGLIW
  13. MSIIHOAERA
  14. ALRKRRIRER
  15. KODIDEDRCD
  16. HELWSLEUTH
  17. EOF
  18.  
  19. my @words = split /\n/, <<'EOF';
  20. WEEK
  21. FIND
  22. RANDOM
  23. SLEUTH
  24. BACKWARD
  25. VERTICAL
  26. DIAGONAL
  27. WIKIPEDIA
  28. HORIZONTAL
  29. WORDSEARCH
  30. EOF
  31.  
  32. sub rest { [ @{$_[0]}[1 .. $#{$_[0]}] ] }
  33. sub equal { defined $_[0] and $_[0] eq $_[1] }
  34.  
  35. sub f {
  36. my ($x, $y, $dx, $dy, $words, $str) = @_;
  37.  
  38. return ((@{$str} < 1) ?
  39. 1 :
  40. ((($x >= 0) and ($y >= 0) and equal($words->[$y]->[$x], $str->[0])) ?
  41. f($x + $dx, $y + $dy, $dx, $dy, $words, rest($str)) :
  42. 0
  43. )
  44. );
  45. }
  46.  
  47. sub g {
  48. my ($words) = @_;
  49.  
  50. my @dir = (
  51. [-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]
  52. );
  53.  
  54. my %initial;
  55. foreach my $y (0 .. $#{$words}){
  56. foreach my $x (0 .. $#{$words->[$y]}){
  57. push(@{$initial{$words->[$y]->[$x]}}, [$x, $y]);
  58. }
  59. }
  60.  
  61. return sub {
  62. my $str = [ split //, shift ];
  63. return reduce {
  64. (grep{ f(@{$b}, @{$_}, $words, $str) } @dir) ? [ @{$a}, $b ] : $a
  65. } [], @{$initial{$str->[0]}}
  66. };
  67. }
  68.  
  69. use Data::Dumper;
  70. local $Data::Dumper::Terse = 1;
  71. local $Data::Dumper::Indent = 0;
  72.  
  73. my $g = g($table);
  74. say Dumper([ map{ [ $_, $g->($_) ] } @words ]);
  75.  
Success #stdin #stdout 0.03s 5260KB
stdin
Standard input is empty
stdout
[['WEEK',[]],['FIND',[[4,1]]],['RANDOM',[[0,1]]],['SLEUTH',[[4,9]]],['BACKWARD',[[9,1]]],['VERTICAL',[[1,0]]],['DIAGONAL',[[6,8]]],['WIKIPEDIA',[[3,9]]],['HORIZONTAL',[[0,9]]],['WORDSEARCH',[[0,0]]]]