Watch
1
0
Fork
You've already forked advent-of-code
0
advent-of-code/2023/day06.nim
2023-12-05 21:32:21 -08:00

77 lines
1.8 KiB
Nim

import std/enumerate
import std/math
import std/sequtils
import std/sets
import std/strscans
import std/strutils
import std/sugar
import std/tables
type Race = tuple
time: int
distance: int
func parseRaces(text: string): seq[Race] =
let lines = text.strip.splitLines
let times = lines[0].splitWhitespace
let distances = lines[1].splitWhitespace
assert(times[0] == "Time:")
assert(distances[0] == "Distance:")
for (time, distance) in zip(times[1..^1], distances[1..^1]):
result.add (time.parseInt, distance.parseInt)
func distance_traveled(race: Race, hold_ms: int): int =
let travel_time = max(0, race.time - hold_ms)
let speed = hold_ms
speed * travel_time
func min_win(race: Race): int =
var hold_ms = 0
while hold_ms < race.time:
let dist = race.distance_traveled(hold_ms)
if dist > race.distance:
return hold_ms
inc hold_ms
func max_win(race: Race): int =
var hold_ms = race.time - 1
while hold_ms > 0:
let dist = race.distance_traveled(hold_ms)
if dist > race.distance:
return hold_ms
dec hold_ms
func win_count(race: Race): int =
let min_ms = race.min_win
let max_ms = race.max_win
len(min_ms .. max_ms)
proc dbg[T](v: T): T = (echo(v); v)
proc part1(): int =
let text = readFile("input/day06.txt")
let races = parseRaces(text)
result = 1
for race in races:
result *= race.win_count
func parseRaceUnkerned(text: string): Race =
let lines = text.strip.splitLines
let times = lines[0].splitWhitespace
let distances = lines[1].splitWhitespace
assert(times[0] == "Time:")
assert(distances[0] == "Distance:")
let time = times[1..^1].join("").parseInt
let distance = distances[1..^1].join("").parseInt
(time, distance)
proc part2(): int =
let text = readFile("input/day06.txt")
let race = parseRaceUnkerned(text)
race.win_count
echo part1()
echo part2()