# Word search

```perl
my $rows = 10;
my $cols = 10;

my $message = q:to/END/;
    .....R....
    ......O...
    .......S..
    ........E.
    T........T
    .A........
    ..C.......
    ...O......
    ....D.....
    .....E....
    END

my %dir =
    '→' => (1,0),
    '↘' => (1,1),
    '↓' => (0,1),
    '↙' => (-1,1),
    '←' => (-1,0),
    '↖' => (-1,-1),
    '↑' => (0,-1),
    '↗' => (1,-1)
;

my @ws = $message.comb(/<print>/);

my $path = './unixdict.txt'; # or wherever

my @words = $path.IO.slurp.words.grep( { $_ !~~ /<-[a..z]>/ and 2 < .chars < 11 } ).pick(*);
my %index;
my %used;

while @ws.first( * eq '.') {

    # find an unfilled cell
    my $i = @ws.grep( * eq '.', :k ).pick;

    # translate the index to x / y coordinates
    my ($x, $y) = $i % $cols, floor($i / $rows);

    # find a word that fits
    my $word = find($x, $y);

    # Meh, reached an impasse, easier to just throw it all
    # away and start over rather than trying to backtrack.
    restart, next unless $word;

    %used{"$word"}++;

    # Keeps trying to place an already used word, choices
    # must be limited, start over
    restart, next if %used{$word} > 15;

    # Already used this word, try again
    next if %index{$word.key};

    # Add word to used word index
    %index ,= $word;

    # place the word into the grid
    place($x, $y, $word);

}

display();

sub display {
    put flat "    ", 'ABCDEFGHIJ'.comb;
    .put for (^10).map: { ($_).fmt("  %2d"), @ws[$_ * $cols .. ($_ + 1) * $cols - 1] }
    put "\n  Words used:";
    my $max = 1 + %index.keys.max( *.chars ).chars;
    for %index.sort {
        printf "%{$max}s %4s %s  ", .key, .value.key, .value.value;
        print "\n" if $++ % 2;
    }
    say "\n"
}

sub restart {
    @ws = $message.comb(/<print>/);
    %index = ();
    %used = ();
}

sub place ($x is copy, $y is copy, $w) {
    my @word = $w.key.comb;
    my $dir  = %dir{$w.value.value};
    @ws[$y * $rows + $x] = @word.shift;
    while @word {
        ($x, $y) »+=« $dir;
        @ws[$y * $rows + $x] = @word.shift;
    }
 }

sub find ($x, $y) {
    my @trials = %dir.keys.map: -> $dir {
            my $space = '.';
            my ($c, $r) = $x, $y;
            loop {
                ($c, $r) »+=« %dir{$dir};
                last if 9 < $r|$c;
                last if 0 > $r|$c;
                my $l = @ws[$r * $rows + $c];
                last if $l ~~ /<:Lu>/;
                $space ~= $l;
            }
            next if $space.chars < 3;
            [$space.trans( '.' => ' ' ),
            ("{'ABCDEFGHIJ'.comb[$x]} {$y}" => $dir)]
        };

    for @words.pick(*) -> $word {
        for @trials -> $space {
            next if $word.chars > $space[0].chars;
            return ($word => $space[1]) if compare($space[0].comb, $word.comb)
        }
    }
}

sub compare (@s, @w) {
    for ^@w {
        next if @s[$_] eq ' ';
        return False if @s[$_] ne @w[$_]
    }
    True
}
```

#### Output:

```
     A B C D E F G H I J
   0 b y e e a R s w u k
   1 r g e n p f O s e s
   2 d i n l e i i S t i
   3 r e b i l a c e E f
   4 T g t a d a g n l T
   5 d A a t d o w a i d
   6 g i C n a n a l r c
   7 a o g O p a l p r f
   8 p g n p D d a i o a
   9 c r u s h E s p t d

  Words used:
     aaa  G 8 ↖    afield  E 0 ↘  
   alley  F 4 ↖       bye  A 0 →  
 caliber  G 3 ←     crush  A 9 →  
     dan  F 8 ↑       dig  A 5 ↘  
    epic  D 0 ↘       fad  J 7 ↓  
    fisk  J 3 ↑       gap  A 6 ↓  
   geigy  B 4 ↑       get  G 4 ↗  
     gnp  B 8 →       goa  C 7 ←  
    lane  H 6 ↑       law  G 7 ↑  
     nag  D 6 ↖       nne  D 1 ↙  
    odin  F 5 ↖       orr  I 8 ↑  
  paddle  E 7 ↑    picnic  E 1 ↘  
     pip  H 9 ↑       rib  A 1 ↘  
     sir  G 9 ↗       sst  G 0 ↘  
    tail  D 5 ↑       ted  C 4 ↖  
     tor  I 9 ↑      usia  I 0 ↙  
     wei  H 0 ↘  
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://trizen.gitbook.io/perl6-rosettacode/programming_tasks/w/word_search.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
