diff options
author | Andinus <andinus@nand.sh> | 2021-01-19 18:20:23 +0530 |
---|---|---|
committer | Andinus <andinus@nand.sh> | 2021-01-19 18:20:23 +0530 |
commit | 5bb0f224483fbc1d57fd1c5a2f4a22dd7263ecd6 (patch) | |
tree | 1623478ad72521793c499522a88bf258a39f6464 /lib/Neighbors.rakumod | |
parent | a5fd4afc258afe61adc298101cf2665e0dfb6b9f (diff) | |
download | octans-5bb0f224483fbc1d57fd1c5a2f4a22dd7263ecd6.tar.gz |
Re-implement octans, move subroutines to respective modules
Initially it went over the list of words & checked if they exist in the grid. This was very slow. Currently it walks the grid & checks if the current string exist in the dictionary. This is faster for these reasons: • The dictionary is sorted, we perform binary range search on the dictionary to return the list of all words that start with specific string. • Starting positions are limited. If the dictionary wasn't sorted then this probably would've been
Diffstat (limited to 'lib/Neighbors.rakumod')
-rw-r--r-- | lib/Neighbors.rakumod | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/Neighbors.rakumod b/lib/Neighbors.rakumod new file mode 100644 index 0000000..41cb35d --- /dev/null +++ b/lib/Neighbors.rakumod @@ -0,0 +1,53 @@ +unit module Neighbors; + +# neighbors returns the neighbors of given index. Neighbors are cached +# in @neighbors array. This way we don't have to compute them +# everytime neighbors subroutine is called for the same position. +sub neighbors ( + @puzzle, Int $y, Int $x --> List +) is export { + # @directions is holding a list of directions we can move in. It's + # used later for neighbors subroutine. + state List @directions = ( + # $y, $x + ( +1, +0 ), # bottom + ( -1, +0 ), # top + ( +0, +1 ), # left + ( +0, -1 ), # right + ); + + # @neighbors holds the neighbors of given position. + state Array @neighbors; + + if @puzzle[$y][$x] { + + # If we've already computed the neighbors then no need to do + # it again. + unless @neighbors[$y][$x] { + my Int $pos-x; + my Int $pos-y; + + # Starting from the intital position of $y, $x we move to + # each direction according to the values specified in + # @directions array. In this case we're just trying to + # move in 4 directions (top, bottom, left & right). + DIRECTION: for @directions -> $direction { + $pos-y = $y + $direction[0]; + $pos-x = $x + $direction[1]; + + # If movement in this direction is out of puzzle grid + # boundary then move on to next direction. + next DIRECTION unless @puzzle[$pos-y][$pos-x]; + + # If neighbors exist in this direction then add them + # to @neighbors[$y][$x] array. + push @neighbors[$y][$x], [$pos-y, $pos-x]; + } + } + } else { + # If it's out of boundary then return no neighbor. + @neighbors[$y][$x] = []; + } + + return @neighbors[$y][$x]; +} |