diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-08-31 13:13:15 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-31 13:13:15 +0100 |
| commit | f2a523b4b34995415e06e52fa247af852ad011cf (patch) | |
| tree | 4f2465ff7d321458015023e8c07708cf4c1ef201 | |
| parent | 1cda67fc152a1c71cf521ffe30c5f503959c81a1 (diff) | |
| parent | 551a847730016426f7f0c7c3f5772770cfb214f7 (diff) | |
| download | perlweeklychallenge-club-f2a523b4b34995415e06e52fa247af852ad011cf.tar.gz perlweeklychallenge-club-f2a523b4b34995415e06e52fa247af852ad011cf.tar.bz2 perlweeklychallenge-club-f2a523b4b34995415e06e52fa247af852ad011cf.zip | |
Merge pull request #12596 from 0rir/work
336 nand more on 334
| -rw-r--r-- | challenge-335/0rir/raku/ch-2.raku | 153 | ||||
| -rw-r--r-- | challenge-336/0rir/raku/ch-1.raku | 72 | ||||
| -rw-r--r-- | challenge-336/0rir/raku/ch-2.raku | 89 |
3 files changed, 304 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; diff --git a/challenge-336/0rir/raku/ch-1.raku b/challenge-336/0rir/raku/ch-1.raku new file mode 100644 index 0000000000..c500589b2d --- /dev/null +++ b/challenge-336/0rir/raku/ch-1.raku @@ -0,0 +1,72 @@ +#!/usr/bin/env raku +# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ « » ∴ 🐧 +use v6.e.PREVIEW; +use lib $?FILE.IO.cleanup.parent(2).add("lib"); +use Test; + +=begin comment +336-1: Equal Group Submitted by: Mohammad Sajid Anwar +You are given an array of integers. + +Write a script to return true if the given array can be divided into one or more groups: each group must be of the same size as the others, with at least two members, and with all members having the same value. + + +Example 1 +Input: @ints = (1,1,2,2,2,2) +Output: true + +Groups: (1,1), (2,2), (2,2) + +Example 2 +Input: @ints = (1,1,1,2,2,2,3,3) +Output: false + +Groups: (1,1,1), (2,2,2), (3,3) + +Example 3 +Input: @ints = (5,5,5,5,5,5,7,7,7,7,7,7) +Output: true + +Groups: (5,5,5,5,5,5), (7,7,7,7,7,7) + +Example 4 +Input: @ints = (1,2,3,4) +Output: false + +Example 5 +Input: @ints = (8,8,9,9,10,10,11,11) +Output: true + +Groups: (8,8), (9,9), (10,10), (11,11) + +=end comment + +my @Test = + (1,1,2,2,2,2), True, + (1,1,1,2,2,2,3,3), False, + (5,5,5,5,5,5,7,7,7,7,7,7), True, + (1,2,3,4), False, + (8,8,9,9,10,10,11,11), True, + + (1,1,2,2), True, + (1,1,1), True, + (1,1), True, + (1,), False, + (), False, +; +plan +@Test ÷ 2; + +multi task( @a where (@a ~~ Empty or @a == 1) ) { False } +multi task( @a -->Bool:D) { + my BagHash[Int] $bh; + ++$bh{$_} for @a; + (my $m = $bh.values.min) > 1 and so $bh.values.all %% $m; +} + +for @Test -> @in, $exp { + is task( @in), $exp, "{$exp // $exp.^name()} <- @in.raku()"; +} +done-testing; +my @int = 8,8,9,9,10,10,11,11 ; +say "\nInput: @int = ({@int.join( ', ')})\nOutput: &task( @int)" + diff --git a/challenge-336/0rir/raku/ch-2.raku b/challenge-336/0rir/raku/ch-2.raku new file mode 100644 index 0000000000..28c2b49423 --- /dev/null +++ b/challenge-336/0rir/raku/ch-2.raku @@ -0,0 +1,89 @@ +#!/usr/bin/env raku +# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ « » ∴ 🐧 +use v6.e.PREVIEW; +use Test; + +=begin comment +336-2: Final Score Submitted by: Mohammad Sajid Anwar + +You are given an array of scores by a team. + +Write a script to find the total score of the given team. The score can be any integer, +, C or D. The + adds the sum of previous two scores. The score C invalidates the previous score. The score D will double the previous score. + + +Example 1 +Input: @scores = ("5","2","C","D","+") +Output: 30 + +Example 2 +Input: @scores = ("5","-2","4","C","D","9","+","+") +Output: 27 + +Round 1: 5 +Round 2: 5 + (-2) +Round 3: 5 + (-2) + 4 +Round 4: 5 + (-2) (invalidate the previous score 4) +Round 5: 5 + (-2) + (-4) (double the previous score -2) +Round 6: 5 + (-2) + (-4) + 9 +Round 7: 5 + (-2) + (-4) + 9 + 5 (sum of previous two scores) +Round 8: 5 + (-2) + (-4) + 9 + 5 + 14 (sum of previous two scores) + +Total Scores: 27 + +Example 3 +Input: @scores = ("7","D","D","C","+","3") +Output: 45 + +Example 4 +Input: @scores = ("-5","-10","+","D","C","+") +Output: -55 + +Example 5 +Input: @scores = ("3","6","+","D","C","8","+","D","-2","C","+") +Output: 128 + +=end comment + +my @Test = +# # @in $exp + ("5","2","C","D","+"), 30, + ("5","-2","4","C","D","9","+","+"), 27, + ("7","D","D","C","+","3"), 45, + ("-5","-10","+","D","C","+"), -55, + ("3","6","+","D","C","8","+","D","-2","C","+"), 128, + + ('1', '1'), 2, +; +plan +@Test; + +grammar Final-score { + rule TOP { ^ <number> [[ <plus> |<double>|<cancel>] | <number> ]+ $ } + token number { [ '+' | '-'] ? \d+ } + token plus { '+' } + token double { 'D' } + token cancel { 'C' } +} + +class Fs { + has @.score = [0,]; + method TOP( $/) { $/.make: @.score.sum; } + method number( $/) { @.score.push: $/.Int; } + method plus( $/) { @.score.push: (@.score[*-2,*-1]).sum; } + method double( $/) { @.score.push: (@.score[*-1].Int × 2).Int; } + method cancel( $/) { @.score.pop; } +} + +sub task( $a --> Int) { + my $m = Final-score.parse: $a.join( ' '), :actions(Fs.new); + $m.made.Str.Int; +} + +for @Test -> $code, $exp { + my $m = Final-score.parse: $code.join( ' '); + is $m.Str, $code.join(' '), 'parses'; + is task($code), $exp, "$exp <- $code.raku()"; +} +done-testing; +my @score = "-5","-10","+","D","C","+"; + +say qq{\nInput: @score = ["{@score.join: '","' }"]\nOutput: }, task @score; |
