From 337356b3adb1fe10874fb1ea42a5da24963d9881 Mon Sep 17 00:00:00 2001 From: Andinus Date: Fri, 22 Jan 2021 13:24:29 +0530 Subject: Initial commit --- lib/Tucana/CLI.rakumod | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 lib/Tucana/CLI.rakumod (limited to 'lib/Tucana') diff --git a/lib/Tucana/CLI.rakumod b/lib/Tucana/CLI.rakumod new file mode 100644 index 0000000..b791d50 --- /dev/null +++ b/lib/Tucana/CLI.rakumod @@ -0,0 +1,66 @@ +unit module Tucana::CLI; + +use Octans::Neighbors; + +# If no arguments are passed then run USAGE & exit. +proto MAIN (|) is export {unless so @*ARGS {say $*USAGE; exit;}; {*}} + +multi sub MAIN (Bool :$version) { + say "Tucana v" ~ $?DISTRIBUTION.meta; +} + +multi sub MAIN ( + Str $word, #= word for the puzzle + Bool :v($verbose), #= increase verbosity +) { + my @puzzle := generate-puzzle($word); + " $_".say for @puzzle; +} + +# generate-puzzle generates a 3x3 puzzle with $word in there. +sub generate-puzzle ( + Str $word, +) { + my @puzzle := [ + [<_ _ _ _>], + [<_ _ _ _>], + [<_ _ _ _>], + [<_ _ _ _>], + ]; + + my Int ($y, $x) = edges(@puzzle).pick; + @puzzle[$y][$x] = $word.comb[0]; + + my @visited; + @visited[$y][$x] = True; + + my Int $count = 1; + while $count < $word.chars { + neighbor: for neighbors(@puzzle, $y, $x).pick(*) -> ($pos-y, $pos-x) { + next neighbor if @visited[$pos-y][$pos-x]; + @visited[$pos-y][$pos-x] = True; + + @puzzle[$pos-y][$pos-x] = $word.comb[$count]; + ($y, $x) = ($pos-y, $pos-x); + last neighbor; + } + + $count++; + } + + return @puzzle; +} + +# edges takes a 2d grid & returns the list of edges, i.e. squares with +# < 4 neighbors. +sub edges ( + @puzzle --> List +) { + my List @edges; + for 0 .. @puzzle.end -> $y { + for 0 .. @puzzle[$y].end -> $x { + push @edges, ($y, $x) if neighbors(@puzzle, $y, $x).elems < 4; + } + } + return @edges; +} -- cgit 1.4.1-2-gfad0