Word search: Difference between revisions
Content added Content deleted
Line 1,628: | Line 1,628: | ||
rime (9,6)(6,9) cat (9,2)(9,0) |
rime (9,6)(6,9) cat (9,2)(9,0) |
||
act (2,0)(0,2) |
act (2,0)(0,2) |
||
</pre> |
|||
=={{header|Perl}}== |
|||
<lang perl>#!/usr/bin/perl |
|||
use strict; # http://www.rosettacode.org/wiki/Word_search |
|||
use warnings; |
|||
use Path::Tiny; |
|||
use List::Util qw( shuffle ); |
|||
my $size = 10; |
|||
my $s1 = $size + 1; |
|||
$_ = <<END; |
|||
.....R.... |
|||
......O... |
|||
.......S.. |
|||
........E. |
|||
T........T |
|||
.A........ |
|||
..C....... |
|||
...O...... |
|||
....D..... |
|||
.....E.... |
|||
END |
|||
my @words = shuffle path('/usr/share/dict/words')->slurp =~ /^[a-z]{3,7}$/gm; |
|||
my @played; |
|||
my %used; |
|||
for my $word ( (@words) x 5 ) |
|||
{ |
|||
my ($pat, $start, $end, $mask, $nulls) = find( $word ); |
|||
defined $pat or next; |
|||
$used{$word}++ and next; # only use words once |
|||
$nulls //= ''; |
|||
my $expand = $word =~ s/\B/$nulls/gr; |
|||
my $pos = $start; |
|||
if( $start > $end ) |
|||
{ |
|||
$pos = $end; |
|||
$expand = reverse $expand; |
|||
} |
|||
substr $_, $pos, length $mask, |
|||
(substr( $_, $pos, length $mask ) & ~ "$mask") | "$expand"; |
|||
push @played, join ' ', $word, $start, $end; |
|||
tr/.// > 0 or last; |
|||
} |
|||
print " 0 1 2 3 4 5 6 7 8 9\n\n"; |
|||
my $row = 0; |
|||
print s/(?<=.)(?=.)/ /gr =~ s/^/ $row++ . ' ' /gemr; |
|||
print "\nNumber of words: ", @played . "\n\n"; |
|||
my @where = map |
|||
{ |
|||
my ($word, $start, $end) = split; |
|||
sprintf "%11s %s", $word, $start < $end |
|||
? "(@{[$start % $s1]},@{[int $start / $s1]})->" . |
|||
"(@{[$end % $s1 - 1]},@{[int $end / $s1]})" |
|||
: "(@{[$start % $s1 - 1]},@{[int $start / $s1]})->" . |
|||
"(@{[$end % $s1]},@{[int $end / $s1]})"; |
|||
} sort @played; |
|||
print splice(@where, 0, 3), "\n" while @where; |
|||
tr/.// and die "incomplete"; |
|||
sub find |
|||
{ |
|||
my ($word) = @_; |
|||
my $n = length $word; |
|||
my $nm1 = $n - 1; |
|||
my %pats; |
|||
for my $space ( 0, $size - 1 .. $size + 1 ) |
|||
{ |
|||
my $nulls = "\0" x $space; |
|||
my $mask = "\xff" . ($nulls . "\xff") x $nm1; # vert |
|||
my $gap = qr/.{$space}/s; |
|||
while( /(?=(.(?:$gap.){$nm1}))/g ) |
|||
{ |
|||
my $pat = ($1 & $mask) =~ tr/\0//dr; |
|||
$pat =~ tr/.// or next; |
|||
my $pos = "$-[1] $+[1]"; |
|||
$word =~ /$pat/ or reverse($word) =~ /$pat/ or next; |
|||
push @{ $pats{$pat} }, "$pos $mask $nulls"; |
|||
} |
|||
} |
|||
for my $key ( sort keys %pats ) |
|||
{ |
|||
if( $word =~ /^$key$/ ) |
|||
{ |
|||
my @all = @{ $pats{$key} }; |
|||
return $key, split ' ', $all[ rand @all ]; |
|||
} |
|||
elsif( (reverse $word) =~ /^$key$/ ) |
|||
{ |
|||
my @all = @{ $pats{$key} }; |
|||
my @parts = split ' ', $all[ rand @all ]; |
|||
return $key, @parts[ 1, 0, 2, 3] |
|||
} |
|||
} |
|||
return undef; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
0 1 2 3 4 5 6 7 8 9 |
|||
0 b s g b n R t p r y |
|||
1 t u k c r o O i p n |
|||
2 t u t y h e d S p a |
|||
3 r j m s i i a a E g |
|||
4 T e a g a n p d l T |
|||
5 m A l i y p g p s b |
|||
6 c i C o l e l m y a |
|||
7 b o n O r i l e a w |
|||
8 w e p i D u n l s l |
|||
9 c a l m s E b g s s |
|||
Number of words: 26 |
|||
alb (8,7)->(6,9) anyone (6,3)->(1,8) bawl (9,5)->(9,8) |
|||
breads (3,0)->(8,5) but (0,0)->(2,2) calms (0,9)->(4,9) |
|||
chippy (3,1)->(8,6) cop (0,6)->(2,8) elm (5,6)->(7,6) |
|||
glib (3,4)->(0,7) gut (2,0)->(0,2) jailing (1,3)->(7,9) |
|||
mini (0,5)->(3,8) nag (9,1)->(9,3) nodal (4,0)->(8,4) |
|||
pew (2,8)->(0,8) ppr (8,2)->(8,0) pry (7,0)->(9,0) |
|||
rel (0,3)->(2,5) role (4,7)->(1,4) rub (4,7)->(6,9) |
|||
sapless (3,3)->(9,9) skying (1,0)->(6,5) tip (6,0)->(8,2) |
|||
tum (0,1)->(2,3) yells (4,5)->(8,9) |
|||
</pre> |
</pre> |
||