-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathchallenge.nim
81 lines (63 loc) · 1.85 KB
/
challenge.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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]