-
Notifications
You must be signed in to change notification settings - Fork 0
/
day07.lua
132 lines (103 loc) · 2.36 KB
/
day07.lua
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
123
124
125
126
127
128
129
130
131
132
local read_input = require('lib.read_input')
local str = require('lib.split_str')
local Day07 = {}
function Day07:new(o, input)
o = o or {}
o.parent = self
setmetatable(o, self)
self.__index = self
o.equations = (input and input.input) or {}
return o
end
local Part1 = Day07:new()
function Part1:new(input)
local o = {}
Day07.new(self, o, input)
return o
end
local function plus(x, y)
return x + y
end
local function mult(x, y)
return x * y
end
local function concat(x, y)
return tonumber(tostring(x) .. tostring(y))
end
function Day07:solve_equation(goal, numbers, op, idx, res)
idx = idx or 1
if idx > #numbers then
return goal == res
end
res = op((res or 0), numbers[idx])
if res > goal then
return false
end
for _, func in pairs(self.funcs) do
if self:solve_equation(goal, numbers, func, idx + 1, res) then
return true
end
end
return false
end
function Day07:solve()
local res = 0
for _, eq in pairs(self.equations) do
if self:solve_equation(eq.test, eq.numbers, plus) then
res = res + eq.test
end
end
return res
end
function Part1:solve()
self.funcs = { plus, mult }
return Day07.solve(self)
end
local Part2 = Day07:new()
function Part2:new(input)
local o = {}
Day07.new(self, o, input)
return o
end
function Part2:solve()
self.funcs = { plus, mult, concat }
return Day07.solve(self)
end
local Input = {}
local function map_to_numbers(ns)
for k, n in ipairs(ns) do
ns[k] = tonumber(n)
end
return ns
end
function Input:new(o)
o = o or {}
o.parent = self
setmetatable(o, self)
self.__index = self
local input = read_input("190: 10 19\
3267: 81 40 27\
83: 17 5\
156: 15 6\
7290: 6 8 6 15\
161011: 16 10 13\
192: 17 8 14\
21037: 9 7 18 13\
292: 11 6 16 20")
local eqs = str.split(input, "\n")
local equations = {}
for _, eq in pairs(eqs) do
local equation = str.split(eq, ":")
table.insert(equations, {
test = tonumber(equation[1]),
numbers = map_to_numbers(str.split(equation[2], " "))
})
end
o.input = equations
return o
end
local input = Input:new()
local p1 = Part1:new(input)
print("Part 1: " .. p1:solve())
local p2 = Part2:new(input)
print("Part 2: " .. p2:solve())