More cleanup, stick precompiled regexes in a table
This commit is contained in:
parent
541279fa25
commit
e6683932e8
|
@ -8,5 +8,5 @@ proc solve_for_day(n: int) {.used.} =
|
||||||
echo solvers[n]()
|
echo solvers[n]()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
# solve_all()
|
solve_all()
|
||||||
solve_for_day(4)
|
# solve_for_day(4)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import streams, strutils, re
|
import streams, strutils, re, sequtils
|
||||||
|
|
||||||
type PasswordPolicy = tuple[min: int, max: int, keyChar: char]
|
type PasswordPolicy = tuple[min: int, max: int, keyChar: char]
|
||||||
|
|
||||||
|
@ -8,20 +8,12 @@ proc parsePasswordLine(str: string): (PasswordPolicy, string) =
|
||||||
if match(str, parsePasswordLineRe, matches):
|
if match(str, parsePasswordLineRe, matches):
|
||||||
return ((min: parseInt(matches[0]), max: parseInt(matches[1]), keyChar: matches[2][0]), matches[3])
|
return ((min: parseInt(matches[0]), max: parseInt(matches[1]), keyChar: matches[2][0]), matches[3])
|
||||||
|
|
||||||
iterator asPasswordPolicies(s: Stream): (PasswordPolicy, string) =
|
proc asPasswordPolicies(s: Stream): seq[(PasswordPolicy, string)] =
|
||||||
for line in s.lines(): yield parsePasswordLine line
|
toSeq(s.lines()).mapIt(it.parsePasswordLine)
|
||||||
|
|
||||||
proc isValidPassword(str: string, pp: PasswordPolicy): bool =
|
|
||||||
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])
|
|
||||||
|
|
||||||
proc part1*(s: Stream): int =
|
proc part1*(s: Stream): int =
|
||||||
for (pp, pw) in s.asPasswordPolicies:
|
s.asPasswordPolicies.countIt(it[1].count(it[0].keyChar) in it[0].min..it[0].max)
|
||||||
if isValidPassword(pw, pp): inc result
|
|
||||||
|
|
||||||
proc part2*(s: Stream): int =
|
proc part2*(s: Stream): int =
|
||||||
for (pp, pw) in s.asPasswordPolicies:
|
s.asPasswordPolicies.countIt(
|
||||||
if isValidPasswordPart2(pw, pp): inc result
|
(it[1][it[0].min - 1] == it[0].keyChar) xor (it[0].keyChar == it[1][it[0].max - 1]))
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
import streams, strutils, sets, sequtils, sugar, re, tables
|
import streams, strutils, sets, sequtils, sugar, re, tables
|
||||||
|
|
||||||
|
let regexes = toTable({
|
||||||
|
"hcl": re"^#[0-9a-f]{6}$",
|
||||||
|
"ecl": re"^(amb|blu|brn|gry|grn|hzl|oth)$",
|
||||||
|
"pid": re"^\d{9}$",
|
||||||
|
"hgt": re"^\d+(cm|in)$",
|
||||||
|
"nondec": re"[^0-9]",
|
||||||
|
})
|
||||||
|
|
||||||
let validators = toTable({
|
let validators = toTable({
|
||||||
"hcl": (v: string) => v.match re"^#[0-9a-f]{6}$",
|
"hcl": (v: string) => v.match regexes["hcl"],
|
||||||
"ecl": (v: string) => v.match re"^(amb|blu|brn|gry|grn|hzl|oth)$",
|
"ecl": (v: string) => v.match regexes["ecl"],
|
||||||
"pid": (v: string) => v.match re"^\d{9}$",
|
"pid": (v: string) => v.match regexes["pid"],
|
||||||
"byr": (v: string) => parseInt(v) in 1920..2002,
|
"byr": (v: string) => parseInt(v) in 1920..2002,
|
||||||
"iyr": (v: string) => parseInt(v) in 2010..2020,
|
"iyr": (v: string) => parseInt(v) in 2010..2020,
|
||||||
"eyr": (v: string) => parseInt(v) in 2020..2030,
|
"eyr": (v: string) => parseInt(v) in 2020..2030,
|
||||||
"hgt": proc (v: string): bool =
|
"hgt": proc (v: string): bool =
|
||||||
let (mn, mx) = if v.endsWith("cm"): (150, 193) else: (59, 76)
|
let (mn, mx) = if v.endsWith("cm"): (150, 193) else: (59, 76)
|
||||||
v.match(re"^\d+(cm|in)$") and v.replace(re"[^0-9]").parseInt in mn..mx,
|
v.match(regexes["hgt"]) and v.replace(regexes["nondec"]).parseInt in mn..mx,
|
||||||
"cid": (v: string) => true,
|
"cid": (v: string) => true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue