-
Notifications
You must be signed in to change notification settings - Fork 0
/
day19.rb
executable file
·103 lines (70 loc) · 2.59 KB
/
day19.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env ruby
def get_matching(rules, messages)
rule = rules["0"].gsub(' ', '').gsub('(a)', 'a').gsub('(b)', 'b').gsub('(aa)', 'aa').gsub('(bb)', 'bb').gsub('(ab)', 'ab').gsub('(ba)', 'ba') + ' '
messages.count { |m| m.match(/^#{rule}/) }
end
def get_message_count(rules, messages, imax)
last_message_count = 0
rules_to_evaluate = rules.dup
final_rules = false
loop do
to_replace = rules_to_evaluate.select { |_, v| ('0'..'9').none? { |c| v.include? c } }
if to_replace.size == 0
to_replace = rules_to_evaluate.select {|k, _| k == "8" || k == "11" }
final_rules = true
end
to_replace.each do |k, v|
rules.each do |rk, rv|
i = 0
loop do
rv.gsub!(' ' + k + ' ', ' (' + v + ') ')
break if final_rules and i > imax
break unless rv.include? ' ' + k + ' '
i += 1
end
end
end
rules_to_evaluate.reject! { |k, _| to_replace[k] }
break if rules_to_evaluate.size == 0 or final_rules
end
get_matching(rules, messages)
end
def part_a(input)
messages = input[1].split("\n").map { |x| x + ' '}
rules = input[0].split("\n").map { |x| x.split(":") }.to_h { |x| [x[0], x[1].gsub('"', '') + ' ' ] }
rules_to_evaluate = rules.dup
loop do
to_replace = rules_to_evaluate.select { |_, v| ('0'..'9').none? { |c| v.include? c } }
to_replace.each do |k, v|
rules.each do |rk, rv|
loop do
rv.gsub!(' ' + k + ' ', ' (' + v + ') ')
break unless rv.include? ' ' + k + ' '
end
end
end
rules_to_evaluate.reject! { |k, _| to_replace[k] }
break if rules_to_evaluate.size == 0
end
get_matching(rules, messages)
end
def part_b(input)
messages = input[1].split("\n").map { |x| x + ' '}
input_rules = input[0].split("\n").map { |x| x.split(":") }.to_h { |x| [x[0], x[1].gsub('"', '') + ' ' ] }
last_message_count = 0
imax = 0
loop do
message_count = get_message_count(input_rules.to_h {|k, v| [k, v.dup] }, messages, imax)
return message_count if message_count == last_message_count
last_message_count = message_count
imax += 1
end
end
input = File.read(ARGV[0])
input_part_a = input.split("\n\n")
input_part_b = input
.gsub('8: 42', '8: 42 | 42 8')
.gsub('11: 42 31', '11: 42 31 | 42 11 31')
.split("\n\n")
p part_a(input_part_a)
p part_b(input_part_b)