Watch
1
0
Fork
You've already forked advent-of-code
0
advent-of-code/2023/day15.nim
2023-12-14 23:48:25 -08:00

113 lines
2.3 KiB
Nim

import std/algorithm
import std/deques
import std/enumerate
import std/math
import std/options
import std/sequtils
import std/sets
import std/strscans
import std/strutils
import std/sugar
import std/tables
import std/terminal
proc dbg[T](v: T): T = (echo(v); v)
func empty[T](v: seq[T]): bool = v.len == 0
proc split[T](v: seq[T], pred: proc(elt: T): bool {.noSideEffect.}): seq[seq[T]] =
var current: seq[T]
for elt in v:
if pred(elt):
result.add current
current = @[]
else:
current.add elt
result.add current
func join[T](parts: seq[seq[T]], sep: T): seq[T] =
if parts.len > 0:
result &= parts[0]
for part in parts[1..^1]:
result.add sep
result &= part
type Op = enum
Dash
Equals
func parseOp(c: char): Op =
case c:
of '-': Dash
of '=': Equals
else: result
type Step = tuple
text: string
label: string
op: Op
num: int
func parseStep(text: string): Step =
result.text = text
if scanf(text, "$+=$i$.", result.label, result.num):
result.op = Equals
return
if scanf(text, "$+-$.", result.label):
result.op = Dash
return
type Init = tuple
steps: seq[Step]
func parseInit(text: string): Init =
result.steps = text.strip.split(',').map(parseStep)
func hash(text: string): int =
for c in text:
result = ((result + c.ord) * 17) mod 256
proc part1(input: string): int =
let text = readFile(input)
let init = parseInit(text)
init.steps.mapIt(it.text.hash).sum
type HASHMAP = object
boxes: array[0..255, OrderedTable[string, int]]
func remove(h: var HASHMAP, label: string) =
let box = label.hash
h.boxes[box].del label
func insert(h: var HASHMAP, label: string, focusLength: int) =
var box = label.hash
h.boxes[box][label] = focusLength
func exec(h: var HASHMAP, step: Step) =
case step.op:
of Dash: h.remove(step.label)
of Equals: h.insert(step.label, step.num)
func power(h: HASHMAP): int =
for (i, box) in enumerate(h.boxes):
for (j, focalLength) in enumerate(box.values):
result.inc (i + 1) * (j + 1) * focalLength
proc part2(input: string): int =
let text = readFile(input)
let init = parseInit(text)
var hashmap: HASHMAP
for step in init.steps:
hashmap.exec step
hashmap.power
echo part1("input/test.txt")
echo part1("input/day15.txt")
echo part2("input/test.txt")
echo part2("input/day15.txt")