-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday10.lua
More file actions
120 lines (98 loc) · 2.87 KB
/
day10.lua
File metadata and controls
120 lines (98 loc) · 2.87 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
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
require 'util'
DAY = 10
local filename = string.format("inputs/input_%02d.txt", DAY)
local f = assert(io.open(filename, "r"))
-- Function definitions here
local data = {}
local visited = {}
local function getAdj(row, col, data)
local pipe = data[row][col]
local res = {}
if row > 1 and ("|JLS"):match(pipe) then
res[#res + 1] = { row - 1, col }
end
if row < #data and ("|7FS"):match(pipe) then
res[#res + 1] = { row + 1, col }
end
if col > 1 and ("-7JS"):match(pipe) then
res[#res + 1] = { row, col - 1 }
end
if col < #data[row] and ("-FLS"):match(pipe) then
res[#res + 1] = { row, col + 1 }
end
return res
end
local function canVisit(orgRow, orgCol, destRow, destCol, data)
local adj = getAdj(destRow, destCol, data)
for i, v in ipairs(adj) do
if v[1] == orgRow and v[2] == orgCol then
return true
end
end
return false
end
local function hash(row, col) return tostring(row) .. " " .. tostring(col) end
local startRow, startCol
for line in f:lines() do
-- Process the file here
local row = {}
local visitRow = {}
for c in chars(line) do
row[#row + 1] = c
visitRow[#visitRow + 1] = false
if c == "S" then
startRow = #data + 1
startCol = #row
end
end
data[#data + 1] = row
visited[#visited + 1] = visitRow
end
-- Do everything else here
local part1 = 0
local part2 = 0
-- Part 1: bfs to find the loop
local loopSize = 1
visited[startRow][startCol] = "|"
-- Cheating by hardcoding value of S, I know there is a way to do this correctly once we get the loop, but I am too lazy
local Q = { { startRow, startCol } }
while #Q ~= 0 do
local c = table.remove(Q, 1)
for i, adj in ipairs(getAdj(c[1], c[2], data)) do
local nRow = adj[1]
local nCol = adj[2]
if not visited[nRow][nCol] and canVisit(c[1], c[2], nRow, nCol, data) then
loopSize = loopSize + 1
visited[nRow][nCol] = data[nRow][nCol]
table.insert(Q, { nRow, nCol })
end
end
end
for _, row in ipairs(visited) do
local inLoop = false
local sub = nil
for _, loop in ipairs(row) do
if loop then
if loop == "|" then
inLoop = not inLoop
elseif loop ~= "-" then
if sub == nil then
sub = loop
elseif sub == "F" then
if loop == "J" then inLoop = not inLoop end
sub = nil
elseif sub == "L" then
if loop == "7" then inLoop = not inLoop end
sub = nil
end
end
else
if inLoop then
part2 = part2 + 1
end
end
end
end
part1 = math.floor(loopSize / 2)
print("Part 1:", part1)
print("Part 2:", part2)