aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrir <rirans@comcast.net>2025-08-30 12:00:55 -0400
committerrir <rirans@comcast.net>2025-08-30 12:01:10 -0400
commitd24aee7bfe3441c6cfc9c1f3f8ad6a5a9b68de61 (patch)
treed88ea924378bff177acebc18be2bbcceea26ff6e
parentabe00897569078e604adaecef75941fa70176dd1 (diff)
downloadperlweeklychallenge-club-d24aee7bfe3441c6cfc9c1f3f8ad6a5a9b68de61.tar.gz
perlweeklychallenge-club-d24aee7bfe3441c6cfc9c1f3f8ad6a5a9b68de61.tar.bz2
perlweeklychallenge-club-d24aee7bfe3441c6cfc9c1f3f8ad6a5a9b68de61.zip
Two more solutions to 335-2
-rw-r--r--challenge-335/0rir/raku/ch-2.raku153
1 files changed, 143 insertions, 10 deletions
diff --git a/challenge-335/0rir/raku/ch-2.raku b/challenge-335/0rir/raku/ch-2.raku
index 86066bfa38..daa90d93d4 100644
--- a/challenge-335/0rir/raku/ch-2.raku
+++ b/challenge-335/0rir/raku/ch-2.raku
@@ -1,6 +1,6 @@
#!/usr/bin/env raku
# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ «␤ » ∴ 🐧
-use v6.d;
+use v6.e.PREVIEW;
use Test;
=begin comment
@@ -57,11 +57,11 @@ Game Board:
[ _ _ A ]
=end comment
-constant \EARLY = 4;
-constant \DONE = 9;
-constant \PENDING = 'Pending';
-constant \DRAW = 'Draw';
-
+constant \EARLY = 4; # too early to have a winner
+constant \DONE = 9; # only 9 elems can be used
+constant \PENDING = 'Pending'; # meaning of !DONE and no winner
+constant \DRAW = 'Draw'; # no victor in DONE data
+constant \_ = '_'; # empty tic
my @Test =
([0,0],[2,0],[1,1],[2,1],[2,2]), 'A', # -> SE
@@ -73,15 +73,16 @@ my @Test =
([0,0],[2,1],[1,0],[1,1],[2,0]), 'A', # -> S
([1,1],[1,2],[2,2],[0,0],[2,1],[2,0],[0,1]), 'A',
;
-plan +@Test ÷ 2;
+plan 3 × +@Test ÷ 2;
+
+# Version the first ===============================================
-constant \_ = '_'; # empty tic
my @player = <A B>;
my @board[3;3];
# Could not get binding twixt array elems to work.
-# Return True if $player has 3 in a row.
+# Return True if $player has 3 in a row, column, or slant.
sub win-q( @b, $player, $r, $c -->Bool) {
return True if (@b[$r;0],@b[$r;1],@b[$r;2]).all eq $player; # row
@@ -118,8 +119,140 @@ sub task( @move -->Str) {
}
}
+# Version the second, requires v6.e.PREVIEW ===========================
+
+=begin comment
+This is PWC 335 Task 2 as I initially planned to write it with a larger
+array with all elems bound to the tic-tac-toe board array. I wanted to
+play with binding array positions.
+
+This is not as clean as I had hoped.
+
+My idea of mapping of the @b (board) to the @r (review) missed the literal
+corner cases, which added four more diagonals of three.
+
+Also my use of side effects and embedded subs implicitly accessing outer
+vars seems odd.
+=end comment
+
+sub task-bind-ary( @move -->Str) {
+
+ return PENDING if @move ≤ EARLY;
+
+ # set up
+ my @b[3;3];
+ my @g[5;5];
+
+ for 0..2 -> \i { for 0..2 -> \j { @b[i;j] = _ ; }}
+
+ # Bind elems of @g, the ground, to the @b, the board.
+
+ # @b idx @g indices
+ my @bind =
+ [0,0], [1,1, 1,4, 4,1, 4,4],
+ [0,1], [1,2, 4,2,],
+ [0,2], [1,3, 1,0, 4,0, 4,3],
+ [1,0], [2,1, 2,4,],
+ [1,1], [2,2,],
+ [1,2], [2,3, 2,0,],
+ [2,0], [3,1, 0,1, 0,4, 3,4],
+ [2,1], [3,2, 0,2,],
+ [2,2], [3,3, 0,0, 0,3, 3,0];
+
+ for @bind -> @sq, @alias {
+ my (\ro, \co) = @sq;
+ for @alias -> \r, \c {
+ @g[r;c] := @b[ro;co];
+ }
+ }
+
+ my $i = 0;
+ # The current player
+ sub player( -->Str) { $i %% 2 ?? 'A' !! 'B' }
+
+ ### Enter early moves
+ while $i < EARLY {
+ my (\r, \c) = enter-move;
+ ++$i;
+ }
+ # Return indices for checking against @g
+ sub enter-move(-->List) {
+ my ($r,$c) = @move[$i];
+ @b[$r;$c] = player;
+ return ( ++$r, ++$c);
+ }
+
+ ### Enter and check moves
+ while $i < min DONE, @move {
+ my (\r, \c) = enter-move;
+ if win-q( r, c) {
+ return player;
+ }
+ ++$i;
+ } # Did current tic or big X win?
+ sub win-q( \r, \c -->Bool) {
+ return ? any( N(r,c),E(r,c), Ne, Nw);
+ }
+ sub E( \r,\c) { @g[r;c] eq @g[r ;c-1] eq @g[r ;c+1]} # |
+ sub N( \r,\c) { @g[r;c] eq @g[r-1;c ] eq @g[r+1;c ]} # _
+ sub Nw() { @g[2;2] eq @g[1 ;1 ] eq @g[3 ;3 ]} # \
+ sub Ne() { @g[2;2] eq @g[1 ;3 ] eq @g[3 ;1 ]} # /
+
+ return DRAW if $i == DONE;
+ return PENDING;
+}
+
+# Version the third ===================================================
+
+=begin comment
+This is another approach to PWC 335 Task 2.
+
+Return pending if arg list is too short.
+View the tic-tac-toe grid as locations 'a'... 'i'.
+Convert the matrix indices to locations.
+Iter over input list (while toggling A and B) inserting loca to a player's set.
+Compare A's set, then B's, to list of winning sets.
+If no winner, check move counter to choose pending or draw.
+=end comment
+
+my @win = do for <a b c>, <d e f>, <g h i>, <a d g>,
+ <b e h>, <c f i>, <a e i>, <c e g> -> $s {
+ $s.Set;
+ };
+
+sub coords2id( @a -->Str) { <a b c d e f g h i>[ @a[0] × 3 + @a[1]]; }
+
+multi task-set( @coord where * ≤ EARLY -->Str) { PENDING }
+
+multi task-set( @coord where * < 10 -->Str) {
+
+ my SetHash $a;
+ my SetHash $b;
+ my @tic = $a, $b;
+
+ my $player = 1; # set Player B
+
+ my $i = 0;
+ for @coord -> @c {
+ last if $i == DONE;
+ $player = (!$player);
+ @tic[$player]{coords2id( @c)} = True; # take location
+ ++$i;
+ }
+
+ return 'A' if @tic[0] ⊇ any @win;
+ return 'B' if @tic[1] ⊇ any @win;
+
+ return PENDING if $i < DONE;
+ return DRAW;
+}
+
+# Testing ===========================================================
+
for @Test -> @in, $exp {
- is task( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()";
+ is task( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()";
+ is task-bind-ary( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()";
+ is task-set( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()";
}
done-testing;