adventOfCode/challenges/2022/02-rockPaperScissors/nim/challenge.nim
AKP 0f6d020d3c
Add Nim solutions for day 2 and 3
Signed-off-by: AKP <tom@tdpain.net>
2022-12-03 13:01:43 +00:00

81 lines
1.9 KiB
Nim

import std/strutils
import std/tables
import std/sequtils
type Match = (char, char)
const
rock = 'A'
paper = 'B'
scissors = 'C'
lose = 'X'
draw = 'Y'
win = 'Z'
scores = {
rock: 1,
paper: 2,
scissors: 3,
win: 6,
lose: 0,
draw: 3,
}.toTable
magicBeans = [scissors, rock, paper, scissors, rock].toSeq
outcomeOffsets = {
win: 1,
lose: -1,
draw: 0,
}.toTable
proc indexOf[T](x: seq[T], v: T): int = indexOf(x, v, 0, x.len)
proc indexOf[T](x: seq[T], v: T, start: int): int = indexOf(x, v, start, x.len)
proc indexOf[T](x: seq[T], v: T, start: int, stop: int): int =
for i in start..<stop:
if x[i] == v:
return i
raise newException(ValueError, "item not found in supplied sequence")
proc parse(instr: string): seq[Match] =
for x in instr.strip.splitlines():
result.add((x[0], x[2]))
proc partOne*(instr: string): int =
var inp = parse(instr)
for i in 0..<inp.len:
inp[i][1] = case inp[i][1]:
of 'X':
rock
of 'Y':
paper
of 'Z':
scissors
else:
raise newException(ValueError, "unknown value " & $inp[i][1])
for m in inp:
result += scores[m[1]]
if m[0] == m[1]:
result += scores[draw]
else:
let opponent = magicBeans.indexOf(m[1], 1)
let ours = magicBeans.indexOf(m[0], opponent - 1, opponent + 2)
if opponent - ours == outcomeOffsets[win]:
result += scores[win]
proc partTwo*(instr: string): int =
let inp = parse(instr)
for m in inp:
result += scores[m[1]]
let our_move = magicBeans[magicBeans.indexOf(m[0], 1) + outcomeOffsets[
m[1]]]
result += scores[our_move]