summaryrefslogtreecommitdiff
path: root/03.lua
blob: 4cf692f5b0b8911d898634ddd4ef17b74ceaaade (plain) (blame)
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
#!/usr/bin/env lua

local function expand(l, i)
	local p = { i, i }
	while p[1] > 1 and string.gmatch(l:sub(p[1] - 1, p[1] - 1), "%d")() ~= nil do
		p[1] = p[1] - 1
	end
	while p[2] < #l and string.gmatch(l:sub(p[2] + 1, p[2] + 1), "%d")() ~= nil do
		p[2] = p[2] + 1
	end
	return p
end

local function replace(l, s, e)
	local t = {}
	for token in string.gmatch(l, ".") do
		table.insert(t, token)
	end
	for i = 1, #t do
		if i >= s and i <= e then
			t[i] = "."
		end
	end
	return table.concat(t)
end

local function copy(v)
	local j = {}
	for i = 1, #v do
		j[i] = v[i]
	end
	return j
end

local function adj(i, j)
  return {
    { i - 1, j },
    { i + 1, j },
    { i, j - 1 },
    { i, j + 1 },
    { i - 1, j - 1 },
    { i - 1, j + 1 },
    { i + 1, j - 1 },
    { i + 1, j + 1 },
  }
end

local function p1(l)
	local v = copy(l)
	local s = 0
	for i = 1, #v do
		for j = 1, #v[i] do
			if string.gmatch(v[i]:sub(j, j), "[*#+$=@%%/&-]")() ~= nil then
				local p = adj(i, j)
				for k = 1, #p do
					if
						(p[k][1] < 1 or p[k][2] < 1 or p[k][1] > #v or p[k][2] > #v[p[k][1]])
						or (string.gmatch(v[p[k][1]]:sub(p[k][2], p[k][2]), "%d")() == nil)
					then
						goto nextkp1
					end
					local pos = expand(v[p[k][1]], p[k][2])
					s = s + tonumber(v[p[k][1]]:sub(pos[1], pos[2]))
					v[p[k][1]] = replace(v[p[k][1]], pos[1], pos[2])
					::nextkp1::
				end
			end
		end
	end
	return s
end

local function p2(l)
	local v = copy(l)
	local s = 0
	for i = 1, #v do
		for j = 1, #v[i] do
			if string.gmatch(v[i]:sub(j, j), "[*]")() ~= nil then
				local p = adj(i, j)
				local n = {}
				for k = 1, #p do
					if
						(p[k][1] < 1 or p[k][2] < 1 or p[k][1] > #v or p[k][2] > #v[p[k][1]])
						or (string.gmatch(v[p[k][1]]:sub(p[k][2], p[k][2]), "%d")() == nil)
					then
						goto nextkp2
					end
					local pos = expand(v[p[k][1]], p[k][2])
					table.insert(n, tonumber(v[p[k][1]]:sub(pos[1], pos[2])))
					v[p[k][1]] = replace(v[p[k][1]], pos[1], pos[2])
					::nextkp2::
				end
				if #n == 2 then
					s = s + n[1] * n[2]
				end
			end
		end
	end
	return s
end

local f = io.open("03.txt", "r")
local content = f:read("*all")
f:close()
local l = {}
for line in string.gmatch(content, "[(%w%p)]+") do
	table.insert(l, line)
end
print(p1(l))
print(p2(l))