-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday16.rb
122 lines (102 loc) · 2.44 KB
/
day16.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
require 'set'
file = File.open("input/day16.txt", "r")
lines = file.readlines
rules = []
my_ticket = []
tickets = []
pt = 0
for line in lines
if line.strip == "nearby tickets:" or line.strip == "your ticket:"
next
end
if line.strip == ""
pt += 1
next
end
if pt == 0
rx = /([\w ]+): ([0-9]+)-([0-9]+) or ([0-9]+)-([0-9]+)/
md = rx.match(line)
rule = []
rule.push(md[1])
rule += md[2..5].map{|n| n.to_i}
rules.push(rule)
next
end
if pt == 1
my_ticket = line.split(",").map{|n| n.to_i}
next
end
if pt == 2
tickets.push(line.split(",").map{|n| n.to_i})
next
end
end
# puts rules
# puts "--"
# puts tickets.map{|t| t.join(",")}
def fits(field, rule)
min1 = rule[1]
max1 = rule[2]
min2 = rule[3]
max2 = rule[4]
if (field >= min1 and field <= max1) or (field >= min2 and field <= max2)
return rule[0]
end
return nil
end
def fits_many(field, rules)
for rule in rules
t = fits(field, rule)
if t != nil
return t
end
end
return nil
end
invalidNums = []
validTickets = [my_ticket]
for ticket in tickets
invalid = false
for field in ticket
if fits_many(field, rules) == nil
invalidNums.push(field)
invalid = true
end
end
if not invalid
validTickets.push(ticket)
end
end
puts invalidNums.sum # part 1
def fits_all(fields, rules)
fitting = Set[]
for rule in rules
does_fit = fields.map{|f| fits(f, rule) != nil}
if does_fit.all?(true)
fitting.add(rule[0])
end
end
return fitting
end
possible_rules = []
for field_index in 0..my_ticket.length-1
fields = validTickets.map{|t| t[field_index]}
rule_names = fits_all(fields, rules)
possible_rules[field_index] = rule_names
end
rule_field_mapping = {}
while possible_rules.map{|x| x.to_a.count}.sum > 0
for i in 0..possible_rules.length-1
pr = possible_rules[i]
if pr.length == 1
rule = pr.to_a[0]
for j in 0..possible_rules.length-1
rule_field_mapping[i] = rule
possible_rules[j] = possible_rules[j].delete(rule)
end
break
end
end
end
# puts rule_field_mapping
puts rule_field_mapping.filter{|k, v| v.start_with?("departure")}.keys.map{|i| my_ticket[i]}.reduce(1, :*)