diff options
| author | rir <rirans@comcast.net> | 2025-08-30 12:00:55 -0400 |
|---|---|---|
| committer | rir <rirans@comcast.net> | 2025-08-30 12:01:10 -0400 |
| commit | d24aee7bfe3441c6cfc9c1f3f8ad6a5a9b68de61 (patch) | |
| tree | d88ea924378bff177acebc18be2bbcceea26ff6e | |
| parent | abe00897569078e604adaecef75941fa70176dd1 (diff) | |
| download | perlweeklychallenge-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.raku | 153 |
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; |
