adventofcode/2023/day03.nim
2023-12-06 20:15:20 +01:00

67 lines
1.7 KiB
Nim

import std/[math, strutils]
type
Number = object
x1, x2, y: int
value: int
Symbol = object
x, y: int
symbol: char
Schematic = object
numbers: seq[Number]
symbols: seq[Symbol]
func parse(input: string): Schematic =
let lines = input.splitLines()
for y, line in lines:
var nums: string
for x, ch in line:
if ch.isDigit():
nums = nums & ch
if nums.len > 0:
if x+1 == line.len or not line[x+1].isDigit():
let number = Number(x1: x-nums.len+1, x2: x, y: y,
value: nums.parseInt())
result.numbers.add(number)
nums = ""
continue
if ch != '.':
let symbol = Symbol(x: x, y: y, symbol: ch)
result.symbols.add(symbol)
func isAdjacent(n: Number, s: Symbol): bool =
(n.y - 1 <= s.y and s.y <= n.y + 1 and
n.x1 - 1 <= s.x and s.x <= n.x2 + 1)
func partNumbers(schematic: Schematic): seq[int] =
for number in schematic.numbers:
for symbol in schematic.symbols:
if number.isAdjacent(symbol):
result.add(number.value)
func gearRatios(schematic: Schematic): seq[int] =
for symbol in schematic.symbols:
if symbol.symbol != '*':
continue
block findNumbers:
var partNumbers: seq[int]
for number in schematic.numbers:
if number.isAdjacent(symbol):
partNumbers.add(number.value)
if partNumbers.len > 2:
break findNumbers
if partNumbers.len == 2:
result.add(partNumbers[0] * partNumbers[1])
proc p1(input: string) =
echo parse(input).partNumbers().sum()
proc p2(input: string) =
echo parse(input).gearRatios().sum()
when isMainModule:
let input = stdin.readAll()
p1(input)
p2(input)