-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
55 lines (45 loc) · 1.24 KB
/
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
DATA = File.read('data.txt')
RULES_RAW = DATA.scan(/(\d+): (.*)/).map do |rule, line|
[rule.to_i, line]
end.to_h
def make_regex special_rules = {}
rules = {}
todo = RULES_RAW.to_a
loop do
ids = todo.select do |id, rule|
rule.scan(/\d+/).map(&:to_i) - rules.keys == []
end.map(&:first)
ids.each do |id|
if special_rules.include? id
rules[id] = special_rules[id][id, rules]
else
r = RULES_RAW[id].gsub(/\d+/){ rules[_1.to_i] }.gsub(/[ "]/, '')
rules[id] = "(?:#{r})"
end
end
todo = todo.reject{ |k, v| ids.include? k }
break if todo.size == 0
end
rx = Regexp.new "^#{rules[0]}$"
end
RX_PART1 = make_regex
PART1 = DATA.scan(/[ab]+/).count do |l|
RX_PART1.match l
end
def rule11 id, rules
(1..10).map do |n|
"(?:#{rules[42]}{#{n}})(?:#{rules[31]}{#{n}})"
end.join('|').yield_self do |v|
"(?:#{v})"
end
end
SPECIAL = {
11 => -> id, rules { rule11 id, rules },
8 => -> id, rules { "(?:#{rules[42]}+)" },
}
RX_PART2 = make_regex SPECIAL
PART2 = DATA.scan(/[ab]+/).count do |l|
RX_PART2.match l
end
puts 'Part 1: %s' % PART1
puts 'Part 2: %s' % PART2