about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/Octans/CLI.rakumod57
-rw-r--r--lib/Octans/Puzzle.rakumod78
-rw-r--r--resources/sample_input4
3 files changed, 86 insertions, 53 deletions
diff --git a/lib/Octans/CLI.rakumod b/lib/Octans/CLI.rakumod
index 24ef59f..46b1afd 100644
--- a/lib/Octans/CLI.rakumod
+++ b/lib/Octans/CLI.rakumod
@@ -1,23 +1,25 @@
 use Octans::Puzzle;
 use Octans::WordSearch;
 
-proto MAIN (|) is export {unless so @*ARGS {say $*USAGE; exit;}; {*}}
-multi sub MAIN(Bool :$version) is hidden-from-USAGE {
+# If no arguments are passed then run USAGE & exit.
+proto MAIN (|) is export {unless so @*ARGS {USAGE(); exit;}; {*}}
+
+multi sub MAIN (Bool :$version) is hidden-from-USAGE {
     say "Octans v" ~ $?DISTRIBUTION.meta<version>;
 }
 
 multi sub MAIN (
-    Str $url?, #= url for Algot's crossword
+    Str $path?, #= path to the crossword (file or url)
     Str :$dict = (%?RESOURCES<mwords/354984si.ngl> //
                   "/usr/share/dict/words").Str, #= dictionary file
     Bool :s($sample), #= run the sample puzzle
     Bool :v($verbose), #= increase verbosity
     Bool :$version, #= print version
 ) {
-    # Print usage & exit if both sample & url are not passed.
-    unless ($sample or $url) {
-        say $*USAGE;
-        exit 0;
+    # Print usage & exit if both sample & path are not passed.
+    unless ($sample or $path) {
+        USAGE();
+        exit;
     }
 
     # @dict holds the sorted dictionary. Only consider words >= 7
@@ -27,22 +29,22 @@ multi sub MAIN (
     # @puzzle holds the puzzle.
     #
     # @gray-squares holds the list of indexes of valid starting
-    # positions in the puzzle.
+    # positions in the puzzle. ($y, $x)
     my (@puzzle, @gray-squares);
 
     # Set the sample puzzle if requested.
     if $sample {
-        @puzzle = [
-            [<n a t k>],
-            [<i m e c>],
-            [<a r d e>],
-            [<t e c h>]
-        ];
-        @gray-squares = [3, 0], [2, 0]; # $y, $x
+        parse-puzzle(
+            < n a t k
+              i m e c
+              a* r d e
+              t* e c h >,
+            @puzzle, @gray-squares
+        );
     }
 
-    # Get the puzzle from $url if it's passed.
-    get-puzzle($url, @puzzle, @gray-squares) with $url;
+    # Get the puzzle from $path if it's passed.
+    get-puzzle($_, @puzzle, @gray-squares) with $path;
 
     if $verbose {
         # Don't print path if using the dictionary included with the
@@ -85,11 +87,11 @@ multi sub MAIN (
                 for ^@puzzle.elems -> $y {
                     print " " x 3;
                     for ^@puzzle[$y].elems -> $x {
-                        print " ", (@visited[$y][$x] ??
-                                    (%π’»π’Άπ“ƒπ’Έπ“Ž-π’Έπ’½π’Άπ“‡π“ˆ{@puzzle[$y][$x]}
-                                     // @puzzle[$y][$x]) !!
-                                    @puzzle[$y][$x]
-                                   );
+                        print " ", (
+                        @visited[$y][$x] ??
+                        (%π’»π’Άπ“ƒπ’Έπ“Ž-π’Έπ’½π’Άπ“‡π“ˆ{@puzzle[$y][$x]} // @puzzle[$y][$x]) !!
+                        @puzzle[$y][$x]
+                    );
                     }
                     print "\n";
                 }
@@ -97,3 +99,14 @@ multi sub MAIN (
         }
     }
 }
+
+# Modify USAGE to include input file format.
+sub USAGE {
+    say $*USAGE;
+    say "\nInput file format:
+
+    n a t k
+    i m e c
+    a* r d e
+    t* e c h";
+}
diff --git a/lib/Octans/Puzzle.rakumod b/lib/Octans/Puzzle.rakumod
index a35c409..96a4870 100644
--- a/lib/Octans/Puzzle.rakumod
+++ b/lib/Octans/Puzzle.rakumod
@@ -4,7 +4,7 @@ use WWW;
 
 # get-puzzle returns the @puzzle along with it's @gray-squares.
 sub get-puzzle (
-    Str $url,
+    Str $path,
 
     # @puzzle will hold the puzzle grid.
     @puzzle,
@@ -13,42 +13,58 @@ sub get-puzzle (
     # marks them with an asterisk ("*") after the character.
     @gray-squares
 ) is export {
-    # $toot_url will hold the url that we'll call to get the toot data.
-    my Str $toot_url;
-
-    # User can pass 2 types of links, either it will be the one when they
-    # view it from their local instance or the one they get from Algot's
-    # profile. We set $toot_url from it.
-    if $url.match("web/statuses") -> $match {
-        $toot_url = $match.replace-with("api/v1/statuses");
+    # @raw_puzzle will hold the puzzle before parsing.
+    my @raw-puzzle;
+
+    # Read the puzzle from file if it exists.
+    if $path.IO.f {
+        @raw-puzzle = $path.IO.lines.words;
     } else {
-        $toot_url = "https://mastodon.art/api/v1/statuses/" ~ $url.split("/")[*-1];
+        # $url will hold the url that we'll call to get the toot data.
+        my Str $url;
+
+        # User can pass 2 types of links, either it will be the one
+        # when they view it from their local instance or the one they
+        # get from Algot's profile. We set $url from it.
+        if $path.match("web/statuses") -> $match {
+            $url = $match.replace-with("api/v1/statuses");
+        } else {
+            $url = "https://mastodon.art/api/v1/statuses/" ~ $path.split("/")[*-1];
+        }
+
+        # jget just get's the url & decodes the json. We access the
+        # description field of 1st media attachment.
+        if (jget($url)<media_attachments>[0]<description> ~~
+
+            # This regex gets the puzzle in $match.
+            / [[(\w [\*]?) \s*] ** 4] ** 4 $/) -> $match {
+
+            @raw-puzzle = $match[0];
+        }
     }
+    parse-puzzle(@raw-puzzle, @puzzle, @gray-squares);
+}
 
+# parse-puzzle parses the puzzle from @raw-puzzle. It's assumed to be
+# a 4x4 grid.
+sub parse-puzzle (
+    @raw-puzzle, @puzzle, @gray-squares
+) is export {
     # @gray-squares should be empty.
     @gray-squares = ();
 
-    # jget just get's the url & decodes the json. We access the
-    # description field of 1st media attachment.
-    if (jget($toot_url)<media_attachments>[0]<description> ~~
-
-        # This regex gets the puzzle in $match.
-        / [[(\w [\*]?) \s*] ** 4] ** 4 $/) -> $match {
-
-        # We have each character of the puzzle stored in $match. It's
-        # assumed that it'll be a 4x4 grid.
-        for 0 .. 3 -> $y {
-            for 0 .. 3 -> $x {
-                with $match[0][($y * 4) + $x].Str.lc -> $char {
-
-                    # If it ends with an asterisk then we push the
-                    # position to @gray-squares.
-                    if $char.ends-with("*") {
-                        @puzzle[$y][$x] = $char.comb[0];
-                        push @gray-squares, [$y, $x];
-                    } else {
-                        @puzzle[$y][$x] = $char;
-                    }
+    # We have each character of the puzzle stored in @raw-puzzle.
+    for 0 .. 3 -> $y {
+        for 0 .. 3 -> $x {
+            with @raw-puzzle[($y * 4) + $x].Str.lc -> $char {
+
+                # If it ends with an asterisk then we push the
+                # position to @gray-squares.
+                if $char.ends-with("*") {
+                    @puzzle[$y][$x] = $char.comb[0];
+                    push @gray-squares, [$y, $x];
+                } else {
+                    @puzzle[$y][$x] = $char;
                 }
             }
         }
diff --git a/resources/sample_input b/resources/sample_input
new file mode 100644
index 0000000..5362ab6
--- /dev/null
+++ b/resources/sample_input
@@ -0,0 +1,4 @@
+p* a c t
+c* f e i
+o n f o
+y r e n