This commit is contained in:
Daniel Flanagan 2021-12-07 11:13:30 -06:00
parent 4be929622f
commit bebcd21df8
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
2 changed files with 28 additions and 27 deletions

View file

@ -1,4 +1,4 @@
import std/[streams, sequtils, strutils, sugar, strformat, times, httpclient, os] import std/[streams, sequtils, strutils, sugar, strformat, times, httpclient, os, options]
const YEAR = getEnv("AOC_YEAR", "2021").parseInt() const YEAR = getEnv("AOC_YEAR", "2021").parseInt()
proc getCookie(): string = "~/.advent-of-code-auth-cookie".expandTilde().readFile() proc getCookie(): string = "~/.advent-of-code-auth-cookie".expandTilde().readFile()
@ -35,3 +35,19 @@ template time*(i: string, body: untyped): untyped =
when not defined(release): when not defined(release):
echo "NOTE: This is not a real measurement of performance. Compile in release mode with -d:release for best performance." echo "NOTE: This is not a real measurement of performance. Compile in release mode with -d:release for best performance."
# jkp: {(stop - start) * 1000} ms to calculate solution: {result}" # jkp: {(stop - start) * 1000} ms to calculate solution: {result}"
proc doDay*[T](
day: int,
inputLoader: int -> T,
part1: T -> int,
part2: T -> int,
testInput: T,
expectedPart1: int,
expectedPart2: int): void =
let input = day.inputLoader()
time(&"day {day} part 1"): echo input.part1()
time(&"day {day} part 2"): echo input.part2()
when not defined(release):
doAssert testInput.part1() == expectedPart1
doAssert testInput.part2() == expectedPart2

View file

@ -1,33 +1,18 @@
import std/[strutils, sequtils, tables, strformat] import std/[strutils, sequtils, strformat]
import ./common import ./common
proc crabsDistance(input: string): int = proc crabFuel(input: string): int =
let crabs = input.split(',').map(parseInt)
result = int.high() result = int.high()
var max_try = 0 var maxCrab = crabs.foldl(max(a, b), 0)
let dists = input.split(',').map(parseInt) for t in 0..maxCrab: result = min(crabs.foldl(a + abs(b - t), 0), result)
for d in dists:
if d > max_try: max_try = d
for t in 0..max_try:
let fuel = dists.foldl(a + abs(b - t), 0)
if fuel < result: result = fuel
proc f(n: int): int = toSeq(0..abs(n)).foldl(a + b, 0) proc triangleNumber(n: int): int = int((n * (n + 1)) / 2)
proc crabsBigDistance(input: string): int = proc crabMoreFuel(input: string): int =
let crabs = input.split(',').map(parseInt)
result = int.high() result = int.high()
var max_try = 0 var maxCrab = crabs.foldl(max(a, b), 0)
let dists = input.split(',').map(parseInt) for t in 0..maxCrab: result = min(crabs.foldl(a + (b - t).abs().triangleNumber(), 0), result)
for d in dists:
if d > max_try: max_try = d
for t in 0..max_try:
let fuel = dists.foldl(a + f(b - t), 0)
if fuel < result: result = fuel
let input = 7.loadInputText() doDay(7, loadInputText, crabFuel, crabMoreFuel, "16,1,2,0,4,2,7,1,2,14", 37, 168)
time("day 7 part 1"): echo input.crabsDistance()
time("day 7 part 2"): echo input.crabsBigDistance()
when not defined(release):
let testInput = "16,1,2,0,4,2,7,1,2,14"
doAssert testInput.crabsDistance() == 37
doAssert testInput.crabsBigDistance() == 168