--- Day 2: Rock Paper Scissors ---
--- Part 1 ---
parsing input
func toGames(inp: seq[string]): seq[(int, int)] =
inp.mapIt((ord(it[0]) - ord('A'), ord(it[2]) - ord('X')))
let games = day.filename.lines.toSeq.toGames
echo games[0..2]
@[(2, 2), (1, 1), (2, 0)]
solving part 1
func score1(game: (int, int)): int =
# win: you: 2 (scissors), other: 1 (paper) -> you - other = 1 -> + 1 mod 3 = 2 -> *3 = 6
# draw: you - other = 0 -> + 1 mod 3 = 1 -> *3 = 3
# lose: you: 0 (rock), other: 1 (paper) -> you - other = -1 -> + 1 mod 3 = 0 -> *3 = 0
((game[1] - game[0] + 4) mod 3)*3 + game[1] + 1 # outcome + what you play
func part1(games:seq[(int, int)]): int =
sum games.mapIt(score1 it)
# 1 mistake (-1 mod 3 -> -1)
echo part1 games
11386
Notes:
- assumed by mistake that
mod N
always maps to 0..(N-1), instead it can take negative values - also learned python's modulo operator
%
is different than nim'smod
- python equivalent mod is available in math module as
floorMod
- both modulo operator are defined as remainders of integer division
but nim uses
system.div
(rounds towards zero) while python's usesfloorDiv
(rounds down)
These were the examples I used to debug:
#example 1
echo "A Y\nB X\nC Z".split("\n").toGames.part1 # ok 15
echo "A Y\nB X\nC Z".split("\n").toGames.mapIt(score1 it) # ok 8, 1, 6
# new example
echo "A Z\nB Y\nC X".split("\n").toGames.part1
echo "A Z\nB Y\nC X".split("\n").toGames.mapIt(score1 it)
15 @[8, 1, 6] 15 @[3, 5, 7]
--- Part 2 ---
func score2(game: (int, int)): int =
let you = (game[1] - 1 + game[0] + 3) mod 3
# Y draw 1: same as game[0]
# X lose 0: 1 less than game0
#debugEcho (you, game[0]), score1 (game[0], you)
score1 (game[0], you)
func part2(games: seq[(int, int)]): int = sum games.mapIt(score2 it)
#example 1
echo "A Y\nB X\nC Z".split("\n").toGames.part2 # ok 12
echo part2 games
12 13600
Notes:
- first mistake I had to debug, I inverted you and game[0] when computing score
- second mistake: I initially forgot parentheses in you expression