Day 2 implementation

This commit is contained in:
Daniel Flanagan 2020-12-03 09:54:58 -06:00
parent 3dd7542619
commit 2439761d36
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
6 changed files with 60 additions and 18 deletions

View file

@ -8,4 +8,4 @@ proc solve_for_day(n: int) {.used.} =
echo solvers[n]() echo solvers[n]()
when isMainModule: when isMainModule:
solve_for_day(2) solve_all()

View file

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

View file

@ -1,7 +1,32 @@
import streams import streams, strutils, sequtils, re, options
proc part1*(strm: Stream): string = type PasswordPolicy = tuple[min: int, max: int, keyChar: char]
"ayy"
proc part2*(strm: Stream): string = proc isValidPassword(str: string, pp: PasswordPolicy): bool =
"ayy" let count = str.count pp.keyChar
(pp.min <= count) and (count <= pp.max)
proc isValidPasswordPart2(str: string, pp: PasswordPolicy): bool =
(str[pp.min - 1] == pp.keyChar) xor (pp.keyChar == str[pp.max - 1])
let parsePasswordPolicyRe = re"^(\d+)-(\d+) (.): (.*)$"
proc parsePasswordPolicy(str: string): (PasswordPolicy, string) =
var matches: array[4, string]
if match(str, parsePasswordPolicyRe, matches):
return ((min: parseInt(matches[0]), max: parseInt(matches[1]), keyChar: matches[2][0]), matches[3])
iterator asPasswordPolicies(s: Stream): (PasswordPolicy, string) =
for line in s.lines():
yield parsePasswordPolicy line
proc part1*(s: Stream): int =
result = 0
for (pp, pw) in asPasswordPolicies(s):
if isValidPassword(pw, pp):
result += 1
proc part2*(s: Stream): int =
result = 0
for (pp, pw) in asPasswordPolicies(s):
if isValidPasswordPart2(pw, pp):
result += 1

7
2020/src/day3.nim Normal file
View file

@ -0,0 +1,7 @@
import streams
proc part1*(s: Stream): int =
0
proc part2*(s: Stream): int =
0

View file

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

View file

@ -0,0 +1,9 @@
import streams, strutils, sugar
iterator mapStream*[T](s: Stream, cb: (string) -> T): T =
for line in s.lines():
yield cb line
iterator asInts*(s: Stream): int =
for i in mapStream[int](s, parseInt):
yield i