-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2020_day21.lua
More file actions
77 lines (73 loc) · 1.53 KB
/
Copy path2020_day21.lua
File metadata and controls
77 lines (73 loc) · 1.53 KB
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
local ingredients = {}
local occurrences = {}
local allergens = {}
for v in input:gmatch("[^\n]+") do
local s, a = v:match("(.+) %(contains (.+)%)")
local set = {}
for w in s:gmatch("%w+") do
set[w] = true
ingredients[w] = ingredients[w] or {}
occurrences[w] = (occurrences[w] or 0) + 1
end
for w in a:gmatch("%w+") do
allergens[w] = allergens[w] or {}
allergens[w][#allergens[w]+1] = set
end
end
local has_allergen = {}
local possibilities = {}
for a, t in pairs(allergens) do
local set
for k, v in pairs(t) do
if not set then
set = v
else
local valid = {}
for a, _ in pairs(v) do
if set[a] then
valid[a] = true
end
end
set = valid
end
end
for k, v in pairs(set) do
possibilities[a] = possibilities[a] or {}
possibilities[a][#possibilities[a]+1] = k
has_allergen[k] = true
end
end
local solved = {}
local list = {}
repeat
local remove = {}
for k, t in pairs(possibilities) do
if #t == 1 then
solved[t[1]] = k
list[#list+1] = t[1]
remove[k] = true
for _, v in pairs(possibilities) do
if v ~= t then
for i = #v, 1, -1 do
if v[i] == t[1] then
table.remove(v, i)
break
end
end
end
end
end
end
for k, v in pairs(remove) do
possibilities[k] = nil
end
until not next(possibilities)
table.sort(list, function(a, b) return solved[a] < solved[b] end)
local count = 0
for k, v in pairs(ingredients) do
if not has_allergen[k] then
count = count + occurrences[k]
end
end
print(count) -- part 1
print(table.concat(list, ",")) -- part 2