Skip to content

Commit 7a45540

Browse files
authored
Added solution for Puzzle 14 in Lua
1 parent 663faf8 commit 7a45540

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

14/main.lua

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
function parseInput(filePath)
2+
local file = io.open(filePath, "r") -- Open file for reading
3+
if not file then return nil end -- Return nil if file can't be opened
4+
5+
local array2D = {}
6+
for line in file:lines() do
7+
local row = {}
8+
for char in line:gmatch(".") do -- Iterate over each character in the line
9+
table.insert(row, char) -- Insert character into the row
10+
end
11+
table.insert(array2D, row) -- Insert row into the 2D array
12+
end
13+
14+
file:close() -- Close the file
15+
return array2D
16+
end
17+
18+
function copyRoundedRockPositions(roundedRocks)
19+
local newArray = {}
20+
for i, value in ipairs(roundedRocks) do
21+
newArray[i] = {row = value.row, column = value.column }
22+
end
23+
return newArray
24+
end
25+
26+
function positionsAreEqual(roundedRocks1, roundedRocks2)
27+
for i = 1, #roundedRocks1 do
28+
if roundedRocks1[i].row ~= roundedRocks2[i].row then
29+
return false
30+
end
31+
if roundedRocks1[i].column ~= roundedRocks2[i].column then
32+
return false
33+
end
34+
end
35+
return true
36+
end
37+
38+
function findRockPositions(history, roundedRocks)
39+
for i = 1, #history do
40+
if positionsAreEqual(history[i], roundedRocks) then
41+
return i
42+
end
43+
end
44+
return -1
45+
end
46+
47+
function findRoundedRocks(array2D)
48+
local positions = {}
49+
for rowIndex, row in ipairs(array2D) do
50+
for columnIndex, char in ipairs(row) do
51+
if char == 'O' then
52+
table.insert(positions, {row = rowIndex, column = columnIndex})
53+
end
54+
end
55+
end
56+
return positions
57+
end
58+
59+
local function sortByRowDesc(a, b)
60+
if (a.row == b.row) then
61+
return a.column > b.column
62+
end
63+
return a.row > b.row;
64+
end
65+
66+
local function sortByRowAsc(a, b)
67+
if (a.row == b.row) then
68+
return a.column < b.column
69+
end
70+
return a.row < b.row;
71+
end
72+
73+
local function sortByColDesc(a, b)
74+
if (a.column == b.column) then
75+
return a.row > b.row
76+
end
77+
return a.column > b.column;
78+
end
79+
80+
local function sortByColAsc(a, b)
81+
if (a.column == b.column) then
82+
return a.row < b.row
83+
end
84+
return a.column < b.column;
85+
end
86+
87+
88+
function tiltNorth(array2D, roundedRocks)
89+
table.sort(roundedRocks, sortByRowAsc)
90+
for _, pos in ipairs(roundedRocks) do
91+
while pos.row > 1 and array2D[pos.row - 1][pos.column] == '.' do
92+
array2D[pos.row][pos.column] = '.'
93+
pos.row = pos.row - 1
94+
array2D[pos.row][pos.column] = 'O'
95+
end
96+
end
97+
end
98+
99+
function tiltSouth(array2D, roundedRocks)
100+
table.sort(roundedRocks, sortByRowDesc)
101+
for _, pos in ipairs(roundedRocks) do
102+
while pos.row < #array2D and array2D[pos.row + 1][pos.column] == '.' do
103+
array2D[pos.row][pos.column] = '.'
104+
pos.row = pos.row + 1
105+
array2D[pos.row][pos.column] = 'O'
106+
end
107+
end
108+
end
109+
110+
function tiltEast(array2D, roundedRocks)
111+
table.sort(roundedRocks, sortByColDesc)
112+
for _, pos in ipairs(roundedRocks) do
113+
while pos.column < #array2D and array2D[pos.row][pos.column + 1] == '.' do
114+
array2D[pos.row][pos.column] = '.'
115+
pos.column = pos.column + 1
116+
array2D[pos.row][pos.column] = 'O'
117+
end
118+
end
119+
end
120+
121+
function tiltWest(array2D, roundedRocks)
122+
table.sort(roundedRocks, sortByColAsc)
123+
for _, pos in ipairs(roundedRocks) do
124+
while pos.column > 1 and array2D[pos.row][pos.column - 1] == '.' do
125+
array2D[pos.row][pos.column] = '.'
126+
pos.column = pos.column - 1
127+
array2D[pos.row][pos.column] = 'O'
128+
end
129+
end
130+
end
131+
132+
function cycle(charArray2D, roundedRocks)
133+
tiltNorth(charArray2D, roundedRocks)
134+
tiltWest(charArray2D, roundedRocks)
135+
tiltSouth(charArray2D, roundedRocks)
136+
tiltEast(charArray2D, roundedRocks)
137+
end
138+
139+
140+
function calculateWeight(array2D, roundedRocks)
141+
local totalWeight = 0
142+
for _, pos in ipairs(roundedRocks) do
143+
local weight = (#array2D - pos.row) + 1
144+
totalWeight = totalWeight + weight
145+
end
146+
return totalWeight
147+
end
148+
149+
function printArray(array2D)
150+
for i, row in ipairs(array2D) do
151+
for j, char in ipairs(row) do
152+
io.write(char)
153+
end
154+
io.write("\n")
155+
end
156+
io.write("\n")
157+
158+
end
159+
160+
function solve(pathToFile)
161+
local charArray2D = parseInput(pathToFile)
162+
local roundedRocks = findRoundedRocks(charArray2D)
163+
tiltNorth(charArray2D, roundedRocks)
164+
io.write(calculateWeight(charArray2D, roundedRocks))
165+
io.write("\n")
166+
end
167+
168+
function solve2(pathToFile)
169+
local charArray2D = parseInput(pathToFile)
170+
local roundedRocks = findRoundedRocks(charArray2D)
171+
172+
local historyOfPos = { }
173+
174+
local countUntilRepeats;
175+
local cycleLength
176+
for i = 1, 1000000000 do
177+
cycle(charArray2D, roundedRocks)
178+
179+
local existingPos = findRockPositions(historyOfPos, roundedRocks)
180+
if existingPos > -1 then
181+
countUntilRepeats = existingPos
182+
cycleLength = i - countUntilRepeats
183+
break
184+
end
185+
186+
table.insert(historyOfPos, copyRoundedRockPositions(roundedRocks))
187+
end
188+
189+
local remainingCycles = (1000000000 - countUntilRepeats) % cycleLength
190+
191+
for i = 1, remainingCycles do
192+
cycle(charArray2D, roundedRocks)
193+
end
194+
195+
196+
io.write(calculateWeight(charArray2D, roundedRocks))
197+
io.write("\n")
198+
end
199+
200+
local pathToFile = "input"
201+
solve(pathToFile)
202+
solve2(pathToFile)

0 commit comments

Comments
 (0)