47 lines
949 B
Ruby
47 lines
949 B
Ruby
# frozen_string_literal: true
|
|
|
|
input = File.read('./input').split("\n\n").map { |r| r.split("\n") }
|
|
|
|
# Replacements for Part 2
|
|
input[0].delete('8: 42')
|
|
input[0].push('8: 42 | 42 8')
|
|
input[0].delete('11: 42 31')
|
|
input[0].push('11: 42 31 | 42 11 31')
|
|
|
|
$mem = {}
|
|
$lines = input[1]
|
|
|
|
$rules = input[0].map do |i|
|
|
k, v = i.match(/(\d+): (.*)/).captures
|
|
[k, v.split('|').map do |x|
|
|
x.split(' ').reject(&:empty?).compact.map do |y|
|
|
y.gsub('"', '')
|
|
end
|
|
end]
|
|
end.sort_by(&:first).to_h
|
|
|
|
def rules(key, d = 0)
|
|
$mem[key] ||= begin
|
|
either_or = $rules[key]
|
|
|
|
d += 1
|
|
return '' if d == 96
|
|
return key unless either_or
|
|
|
|
pair = either_or.map do |group|
|
|
group.map do |sub_rule|
|
|
rules(sub_rule, d)
|
|
end.join('')
|
|
end.join('|')
|
|
if pair.include?('|')
|
|
'(?:' + pair + ')'
|
|
else
|
|
pair
|
|
end
|
|
end
|
|
end
|
|
|
|
re = Regexp.new('^' + rules('0') + '$')
|
|
|
|
puts $lines.select { |line| re.match(line) }.size
|