aboutsummaryrefslogtreecommitdiff
path: root/challenge-052
diff options
context:
space:
mode:
authorArchargelod <archargelod@gmail.com>2024-04-07 22:49:46 +0800
committerArchargelod <archargelod@gmail.com>2024-04-07 22:49:46 +0800
commitf0a59983d7ca27d1303de7ace94007491afc60a2 (patch)
treeee7050d14b0af506b084c67490b2ae05cb921e20 /challenge-052
parent0495c7534995083a63370f8e93d3834bbe1f054d (diff)
downloadperlweeklychallenge-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/README1
-rwxr-xr-xchallenge-052/archargelod/nim/ch_1.nim16
-rwxr-xr-xchallenge-052/archargelod/nim/ch_2.nim83
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