about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2021-11-18 16:43:05 +0530
committerAndinus <andinus@nand.sh>2021-11-18 16:43:05 +0530
commit03745f7ce6b53054560f1c35d256de00c1113fd8 (patch)
treeda6133c620d95715c56e761fe23df7ba55a079d2
parent71ff6400dc3aef9ceb6c71f0d102f5b9ff40bab8 (diff)
downloadfornax-03745f7ce6b53054560f1c35d256de00c1113fd8.tar.gz
Copy neighbors subroutine
-rw-r--r--algorithms/raku/DFS.raku59
1 files changed, 57 insertions, 2 deletions
diff --git a/algorithms/raku/DFS.raku b/algorithms/raku/DFS.raku
index 4789ce9..0cc7207 100644
--- a/algorithms/raku/DFS.raku
+++ b/algorithms/raku/DFS.raku
@@ -1,5 +1,3 @@
-use Octans::Neighbors;
-
 subset File of Str where *.IO.f;
 
 # Cells as defined by fornax format.
@@ -67,3 +65,60 @@ sub dfs(
         }
     }
 }
+
+# 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. We
+# don't need this caching here since every cell will be visited only
+# once. This subroutine was taken from Octans::Neighbors.
+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] {
+        # Don't re-compute neighbors.
+        unless @neighbors[$y][$x] {
+            # Set it to an empty array because otherwise if it has no
+            # neighbors then it would've be recomputed everytime
+            # neighbors() was called.
+            @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];
+}