Add updated solutions, including day 20.
This commit is contained in:
68
day19.cr
Normal file
68
day19.cr
Normal file
@@ -0,0 +1,68 @@
|
||||
require "advent"
|
||||
|
||||
rlines, _, strings = input(2020, 19).partition("\n\n")
|
||||
strings = strings.lines
|
||||
rules = {} of String => String
|
||||
rlines.lines.map do |l|
|
||||
rule, _, text = l.partition(": ")
|
||||
rules[rule] = text
|
||||
end
|
||||
|
||||
alias Matcher = Proc(String,Int32,Array(Int32))
|
||||
|
||||
def char(c)
|
||||
->(str : String, i : Int32) { str[i]? == c ? [i+1] : [] of Int32 }
|
||||
end
|
||||
|
||||
def any(ps)
|
||||
->(str : String, i : Int32) { ps.flat_map { |p| p.call(str, i) } }
|
||||
end
|
||||
|
||||
def seq(ps)
|
||||
->(str : String, i : Int32) {
|
||||
base = [i]
|
||||
ps.each do |p|
|
||||
base = base.flat_map { |i| p.call(str, i) }
|
||||
end
|
||||
base
|
||||
}
|
||||
end
|
||||
|
||||
def to_regex(rules, rule)
|
||||
end
|
||||
|
||||
def build_rule(rules, built, rule) : Matcher
|
||||
if exists = built[rule]?
|
||||
return exists
|
||||
end
|
||||
|
||||
body = rules[rule]
|
||||
return built[rule] = char body[1] if body.matches? /"."/
|
||||
|
||||
branches = [] of Matcher
|
||||
top = any(branches)
|
||||
built[rule] = top
|
||||
branches.concat(body.split(" | ").map { |b| seq(b.split(" ").map { |subrule| build_rule(rules, built, subrule) }) })
|
||||
top
|
||||
end
|
||||
|
||||
def part1(input)
|
||||
rules, lines = input
|
||||
matcher = build_rule(rules, {} of String => Matcher, "0")
|
||||
lines.count do |l|
|
||||
matcher.call(l, 0).includes? l.size
|
||||
end
|
||||
end
|
||||
|
||||
def part2(input)
|
||||
rules, lines = input
|
||||
rules["8"] = "42 | 42 8"
|
||||
rules["11"] = "42 31 | 42 11 31"
|
||||
matcher = build_rule(rules, {} of String => Matcher, "0")
|
||||
lines.count do |l|
|
||||
matcher.call(l, 0).includes? l.size
|
||||
end
|
||||
end
|
||||
|
||||
puts part1({rules,strings})
|
||||
puts part2({rules,strings})
|
||||
Reference in New Issue
Block a user