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]()
|
||||
|
||||
when isMainModule:
|
||||
# solve_all()
|
||||
solve_for_day(4)
|
||||
solve_all()
|
||||
# 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]
|
||||
|
||||
|
@ -8,20 +8,12 @@ proc parsePasswordLine(str: string): (PasswordPolicy, string) =
|
|||
if match(str, parsePasswordLineRe, 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 parsePasswordLine line
|
||||
|
||||
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 asPasswordPolicies(s: Stream): seq[(PasswordPolicy, string)] =
|
||||
toSeq(s.lines()).mapIt(it.parsePasswordLine)
|
||||
|
||||
proc part1*(s: Stream): int =
|
||||
for (pp, pw) in s.asPasswordPolicies:
|
||||
if isValidPassword(pw, pp): inc result
|
||||
s.asPasswordPolicies.countIt(it[1].count(it[0].keyChar) in it[0].min..it[0].max)
|
||||
|
||||
proc part2*(s: Stream): int =
|
||||
for (pp, pw) in s.asPasswordPolicies:
|
||||
if isValidPasswordPart2(pw, pp): inc result
|
||||
s.asPasswordPolicies.countIt(
|
||||
(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
|
||||
|
||||
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({
|
||||
"hcl": (v: string) => v.match re"^#[0-9a-f]{6}$",
|
||||
"ecl": (v: string) => v.match re"^(amb|blu|brn|gry|grn|hzl|oth)$",
|
||||
"pid": (v: string) => v.match re"^\d{9}$",
|
||||
"hcl": (v: string) => v.match regexes["hcl"],
|
||||
"ecl": (v: string) => v.match regexes["ecl"],
|
||||
"pid": (v: string) => v.match regexes["pid"],
|
||||
"byr": (v: string) => parseInt(v) in 1920..2002,
|
||||
"iyr": (v: string) => parseInt(v) in 2010..2020,
|
||||
"eyr": (v: string) => parseInt(v) in 2020..2030,
|
||||
"hgt": proc (v: string): bool =
|
||||
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,
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue