Add 2020 for nim stuff

This commit is contained in:
Daniel Flanagan 2020-12-02 21:33:18 -06:00
parent 4dffda42ca
commit ad83cc84d8
Signed by: lytedev
GPG Key ID: 5B2020A0F9921EF4
10 changed files with 120 additions and 0 deletions

2
2020/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
*.log

14
2020/aoc2020.nimble Normal file
View File

@ -0,0 +1,14 @@
# Package
version = "0.1.0"
author = "Daniel Flanagan"
description = "@lytedev's Advent of Code 2020 code"
license = "MIT"
srcDir = "src"
bin = @["aoc2020"]
binDir = "build"
# Dependencies
requires "nim >= 1.4.0"

3
2020/config.nims Normal file
View File

@ -0,0 +1,3 @@
switch "define", "ssl"
switch "path", "src/"

2
2020/makefile Normal file
View File

@ -0,0 +1,2 @@
run:
nimble run

5
2020/readme.md Normal file
View File

@ -0,0 +1,5 @@
# Advent of Code 2020
This year, I've decided to tinker around with [`nim`][nim].
Enjoy the mess!

11
2020/src/aoc2020.nim Normal file
View File

@ -0,0 +1,11 @@
import day_loader, tables
proc solve_all() {.used.} =
for (_, solver) in solvers.pairs():
echo solver()
proc solve_for_day(n: int) {.used.} =
echo solvers[n]()
when isMainModule:
solve_for_day(2)

30
2020/src/day1.nim Normal file
View File

@ -0,0 +1,30 @@
import sets, streams, strutils, options
# Day 1
let day1TargetSum = 2020
proc part1*(strm: Stream): Option[int] =
var targets = initHashSet[int]()
for line in strm.lines():
let n = parseInt line
if targets.contains(day1TargetSum - n):
return some((day1TargetSum - n) * n)
else:
targets.incl n
proc part2*(strm: Stream): Option[int] =
# this works exactly the same as the previous algorithm, except we simply
# permute once more
# TODO: if I was really cool, I could split the shared functionality into
# a shared proc
var nums: seq[int]
for line in strm.lines():
nums.add parseInt line
for n in nums:
var iset = initHashSet[int]()
let nTargetSum = day1TargetSum - n
for n2 in nums:
if iset.contains(nTargetSum - n2):
return some(n * n2 * (nTargetSum - n2))
iset.incl n2

7
2020/src/day2.nim Normal file
View File

@ -0,0 +1,7 @@
import streams
proc part1*(strm: Stream): string =
"ayy"
proc part2*(strm: Stream): string =
"ayy"

18
2020/src/day_loader.nim Normal file
View File

@ -0,0 +1,18 @@
import input_requestor, os, macros, strformat, tables
macro loadDays(): untyped =
var solver_str = "var solvers = {\n"
result = newStmtList()
for day in 1..2:
let module = fmt"day{day}"
if fileExists joinPath("src/", &"{module}.nim"):
result.add parseStmt fmt"from {module} import nil"
solver_str = solver_str & &"""
{day}: proc(): (string, string) = (
$(day{day}.part1(getInputFileStreamForDay({day}))),
$(day{day}.part2(getInputFileStreamForDay({day})))
),
"""
result.add parseStmt (solver_str & "\n}.newTable()\nexport solvers")
loadDays()

View File

@ -0,0 +1,28 @@
import httpclient, strformat, os, logging, streams
var fileLog = newFileLogger("aoc2020.log")
var consoleLog = newConsoleLogger()
addHandler(consoleLog)
addHandler(fileLog)
let cacheDir = joinPath(getEnv("XDG_CACHE_HOME", expandTilde("~/.cache")), "/aoc2020-cache")
createDir(cacheDir)
# TODO: add login capabilities via `pass` for auto-cookie-retrieval?
proc requestAocContentAuthed(url: string): TaintedString =
let cookie = getEnv("ADVENT_OF_CODE_AUTH_COOKIE", readFile(expandTilde("~/.advent-of-code-auth-cookie")))
let client = newHttpClient()
client.headers = newHttpHeaders({"cookie": cookie})
client.getContent(url)
proc getInputFileStreamForDay*(day: int): FileStream =
# retrieve the input and dump it to a file if we don't have it yet
let cacheFile = joinPath(cacheDir, fmt"/day-{day}.aoc-input")
if not fileExists(cacheFile):
let url = fmt"https://adventofcode.com/2020/day/{day}/input"
writeFile(cacheFile, requestAocContentAuthed(url).string)
openFileStream(cacheFile)
proc getInputForDay*(day: int): string =
getInputFileStreamForDay(day).readAll()