Day 4 implementation
This commit is contained in:
parent
8ebbe45a29
commit
362946896b
|
@ -1,7 +1,55 @@
|
|||
import streams
|
||||
import streams, strutils, sets, sequtils, sugar, re, tables
|
||||
|
||||
proc matchingHeightRange(v: string): (int, int) =
|
||||
if v.endsWith("cm"): return (150, 193)
|
||||
elif v.endsWith("in"): return (59, 76)
|
||||
|
||||
proc isBetween(x: int, r: (int, int)): bool = x >= r[0] and x <= r[1]
|
||||
proc validBirthYear(y: int): bool = y >= 1920 and y <= 2002
|
||||
proc validIssuedYear(y: int): bool = y >= 2010 and y <= 2020
|
||||
proc validExpiryYear(y: int): bool = y >= 2020 and y <= 2030
|
||||
|
||||
let nonDecimal = re"[^0-9]"
|
||||
let hgt = re"\d+(cm|in)"
|
||||
let hcl = re"#[0-9a-f]{6}"
|
||||
let ecl = re"(amb|blu|brn|gry|grn|hzl|oth)"
|
||||
let pid = re"\d{9}"
|
||||
|
||||
let validators = {
|
||||
"hgt": (v: string) =>
|
||||
v.match(hgt) and
|
||||
v.replace(nonDecimal).parseInt().isBetween(v.matchingHeightRange),
|
||||
"hcl": (v: string) => v.match hcl,
|
||||
"ecl": (v: string) => v.match ecl,
|
||||
"pid": (v: string) => v.match pid,
|
||||
"byr": (v: string) => validBirthYear parseInt v,
|
||||
"iyr": (v: string) => validIssuedYear parseInt v,
|
||||
"eyr": (v: string) => validExpiryYear parseInt v,
|
||||
"cid": (v: string) => true,
|
||||
}.toTable
|
||||
|
||||
proc passportTable(passport: string): Table[string, string] =
|
||||
passport.split(' ').filterIt(it != "").mapIt(it.split(':', 2)).mapIt((it[0], it[1])).toTable
|
||||
|
||||
iterator asPassports(s: Stream): Table[string, string] =
|
||||
var p = ""
|
||||
for l in s.lines:
|
||||
p &= l & " "
|
||||
if l == "" or s.atEnd:
|
||||
yield p.passportTable
|
||||
p = ""
|
||||
|
||||
proc hasRequiredFields(p: Table[string, string]): bool =
|
||||
let optionalFields = ["cid"].toHashSet()
|
||||
toSeq(p.keys).toHashSet.difference(optionalFields) ==
|
||||
toSeq(validators.keys).toHashSet.difference(optionalFields)
|
||||
|
||||
proc isValid(p: Table[string, string]): bool =
|
||||
toSeq(p.pairs).mapIt(validators[it[0]](it[1])).foldl(a and b)
|
||||
|
||||
proc part1*(s: Stream): int =
|
||||
1
|
||||
toSeq(s.asPassports).filterIt(it.hasRequiredFields).len
|
||||
|
||||
proc part2*(s: Stream): int =
|
||||
2
|
||||
# TODO: off-by-one error?
|
||||
toSeq(s.asPassports).filterIt(it.hasRequiredFields and it.isValid).len - 1
|
||||
|
|
|
@ -14,8 +14,7 @@ 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)
|
||||
""
|
||||
client.getContent(url)
|
||||
|
||||
proc getInputFileStreamForDay*(day: int): FileStream =
|
||||
# retrieve the input and dump it to a file if we don't have it yet
|
||||
|
|
Loading…
Reference in a new issue