2020-12-04 11:02:05 -06:00
|
|
|
import streams, strutils, re, sequtils
|
2020-12-02 21:33:18 -06:00
|
|
|
|
2020-12-03 09:54:58 -06:00
|
|
|
type PasswordPolicy = tuple[min: int, max: int, keyChar: char]
|
2020-12-02 21:33:18 -06:00
|
|
|
|
2020-12-03 11:42:18 -06:00
|
|
|
let parsePasswordLineRe = re"^(\d+)-(\d+) (.): (.*)$"
|
|
|
|
proc parsePasswordLine(str: string): (PasswordPolicy, string) =
|
|
|
|
var matches: array[4, string]
|
|
|
|
if match(str, parsePasswordLineRe, matches):
|
|
|
|
return ((min: parseInt(matches[0]), max: parseInt(matches[1]), keyChar: matches[2][0]), matches[3])
|
|
|
|
|
2020-12-04 11:02:05 -06:00
|
|
|
proc asPasswordPolicies(s: Stream): seq[(PasswordPolicy, string)] =
|
|
|
|
toSeq(s.lines()).mapIt(it.parsePasswordLine)
|
2020-12-03 09:54:58 -06:00
|
|
|
|
|
|
|
proc part1*(s: Stream): int =
|
2020-12-04 11:02:05 -06:00
|
|
|
s.asPasswordPolicies.countIt(it[1].count(it[0].keyChar) in it[0].min..it[0].max)
|
2020-12-03 09:54:58 -06:00
|
|
|
|
|
|
|
proc part2*(s: Stream): int =
|
2020-12-04 11:02:05 -06:00
|
|
|
s.asPasswordPolicies.countIt(
|
|
|
|
(it[1][it[0].min - 1] == it[0].keyChar) xor (it[0].keyChar == it[1][it[0].max - 1]))
|