diff options
| author | Archargelod <archargelod@gmail.com> | 2024-04-07 22:49:46 +0800 |
|---|---|---|
| committer | Archargelod <archargelod@gmail.com> | 2024-04-07 22:49:46 +0800 |
| commit | f0a59983d7ca27d1303de7ace94007491afc60a2 (patch) | |
| tree | ee7050d14b0af506b084c67490b2ae05cb921e20 /challenge-052 | |
| parent | 0495c7534995083a63370f8e93d3834bbe1f054d (diff) | |
| download | perlweeklychallenge-club-f0a59983d7ca27d1303de7ace94007491afc60a2.tar.gz perlweeklychallenge-club-f0a59983d7ca27d1303de7ace94007491afc60a2.tar.bz2 perlweeklychallenge-club-f0a59983d7ca27d1303de7ace94007491afc60a2.zip | |
weeks 49-52, 263 in Nim
Diffstat (limited to 'challenge-052')
| -rw-r--r-- | challenge-052/archargelod/README | 1 | ||||
| -rwxr-xr-x | challenge-052/archargelod/nim/ch_1.nim | 16 | ||||
| -rwxr-xr-x | challenge-052/archargelod/nim/ch_2.nim | 83 |
3 files changed, 100 insertions, 0 deletions
diff --git a/challenge-052/archargelod/README b/challenge-052/archargelod/README new file mode 100644 index 0000000000..6cd57e1074 --- /dev/null +++ b/challenge-052/archargelod/README @@ -0,0 +1 @@ +Solution by archargelod diff --git a/challenge-052/archargelod/nim/ch_1.nim b/challenge-052/archargelod/nim/ch_1.nim new file mode 100755 index 0000000000..06d42d9975 --- /dev/null +++ b/challenge-052/archargelod/nim/ch_1.nim @@ -0,0 +1,16 @@ +#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off + +proc isStepping*(number: int): bool = + let digits = $number + for i, c in digits: + if i == 0: continue + if abs(c.ord - digits[i-1].ord) != 1: + return false + true + + +when isMainModule: + echo "All Stepping Numbers between 100 and 999: " + for i in 100..999: + if i.isStepping(): + stdout.write i, ", " diff --git a/challenge-052/archargelod/nim/ch_2.nim b/challenge-052/archargelod/nim/ch_2.nim new file mode 100755 index 0000000000..9e5f6f2b26 --- /dev/null +++ b/challenge-052/archargelod/nim/ch_2.nim @@ -0,0 +1,83 @@ +#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off +import std/[deques] + +type + Player = enum + P1, P2 + Game = object + piles: Deque[int] + turn: Player + scores: tuple[p1, p2: int] + Node = ref object + gameState: Game + l, r: Node + DecisionTree = object + head: Node + +proc `$`(n: Node): string = + $(n.l.gameState.scores, n.r.gameState.scores) + +proc buildTree(node: var Node) = + if node.gameState.piles.len == 0: + return + + node.l = Node(gameState: node.gameState) + node.r = Node(gameState: node.gameState) + + if node.gameState.turn == P1: + node.l.gamestate.turn = P2 + node.r.gamestate.turn = P2 + node.l.gameState.scores.p1 += node.l.gameState.piles.popFirst() + node.r.gameState.scores.p1 += node.r.gameState.piles.popLast() + else: + node.l.gamestate.turn = P1 + node.r.gamestate.turn = P1 + node.l.gameState.scores.p2 += node.l.gameState.piles.popFirst() + node.r.gameState.scores.p2 += node.r.gameState.piles.popLast() + + buildTree(node.l) + buildTree(node.r) + +proc minimax(node: Node, maxiPlayer: bool): int = + if node.gameState.piles.len == 0: + if node.gameState.scores.p1 > node.gameState.scores.p2: + return node.gameState.scores.p1 + elif node.gameState.scores.p1 < node.gameState.scores.p2: + return -1 * node.gameState.scores.p2 + else: + return int(0) + + if maxiPlayer: + var bestVal = int.low + let val = minimax(node.l, false) + let val2 = minimax(node.r, false) + bestVal = max(bestVal, max(val, val2)) + return bestVal + else: + var bestVal = int.high + let val = minimax(node.l, true) + let val2 = minimax(node.r, true) + bestVal = min(bestVal, min(val, val2)) + return bestVal + +proc maxWinScore*(player: Player, piles: openArray[int]): int = + var tree = DecisionTree( + head: Node( + gamestate: Game( + piles: piles.toDeque, + turn: P1, + scores: (0, 0) + ) + ) + ) + buildTree(tree.head) + minimax(tree.head, player == P1) + +when isMainModule: + import std/unittest + + suite "Lucky Winner": + test "First player can force win with score 306": + let score = P1.maxWinScore([100, 50, 1, 10, 5, 20, 200, 2]) + check score > 0 + check score == 306 |
