Skip to content

Commit d359ce9

Browse files
committed
[Day 15] Work on problem
1 parent 57ab228 commit d359ce9

File tree

1 file changed

+106
-5
lines changed

1 file changed

+106
-5
lines changed

src/day15.jl

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,49 @@ using AdventOfCode2024
55

66
function day15(input::String = readInput(joinpath(@__DIR__, "..", "data", "day15.txt")))
77
world, instructions = parse_input(input)
8-
part1(world, instructions)
8+
world_p1 = copy(world)
9+
execute_instructions_p1!(world_p1, instructions)
10+
p1 = total_gps(world_p1)
11+
world_p2 = fill('.', (size(world) .* (1, 2))...)
12+
for ind eachindex(IndexCartesian(), world)
13+
if world[ind] == '#'
14+
world_p2[ind[1],2*ind[2]-1] = '#'
15+
world_p2[ind[1],2*ind[2]] = '#'
16+
elseif world[ind] == 'O'
17+
world_p2[ind[1],2*ind[2]-1] = '['
18+
world_p2[ind[1],2*ind[2]] = ']'
19+
elseif world[ind] == '@'
20+
world_p2[ind[1],2*ind[2]-1] = '@'
21+
end
22+
end
23+
execute_instructions_p2!(world_p2, instructions)
24+
return world_p2
925
end
1026

1127
function parse_input(input)
1228
wo, ins = split(input, "\n\n")
13-
return map(x -> x[1], reduce(vcat, permutedims.(map(x -> split(x, ""), split(wo))))), rstrip(ins)
29+
return map(x -> x[1], reduce(vcat, permutedims.(map(x -> split(x, ""), split(wo))))), replace(ins, '\n' => "")
1430
end
1531

16-
function part1(world, instructions)
32+
function execute_instructions_p1!(world, instructions)
1733
current = findall(x -> x == '@', world)[1]
18-
world[start] = '.'
34+
world[current] = '.'
1935
for instruction instructions
2036
next = current + _to_dir(instruction)
2137
if world[next] == '.'
2238
current = next
2339
elseif world[next] == 'O'
40+
while world[next] ('.', '#')
41+
next += _to_dir(instruction)
42+
end
43+
world[next] == '#' && continue
44+
while next != current
45+
pnext = next - _to_dir(instruction)
46+
world[next], world[pnext] = world[pnext], world[next]
47+
next = pnext
48+
end
49+
current = current + _to_dir(instruction)
2450
end
25-
2651
end
2752
end
2853

@@ -33,4 +58,80 @@ function _to_dir(c::Char)
3358
c == '<' && return CartesianIndex(0, -1)
3459
end
3560

61+
function total_gps(world::Matrix{Char})
62+
total = 0
63+
for index findall(x -> x == 'O', world)
64+
total += 100 * (index[1] - 1) + index[2] - 1
65+
end
66+
return total
67+
end
68+
69+
function locate_box_complex!(tipping_positions::Set{CartesianIndex{2}}, move_positions::Set{CartesianIndex{2}}, world::Matrix{Char}, dir::CartesianIndex{2})
70+
new_tipping_positions = Set{CartesianIndex{2}}()
71+
for pos tipping_positions
72+
push!(move_positions, pos)
73+
if world[pos] == '['
74+
lockpos = CartesianIndex(pos[1], pos[2] + 1)
75+
elseif world[pos] == ']'
76+
lockpos = CartesianIndex(pos[1], pos[2] - 1)
77+
end
78+
push!(move_positions, lockpos)
79+
if world[pos + dir] == '#' || world[lockpos + dir] == '#'
80+
return false
81+
else
82+
if world[pos + dir] ('[', ']')
83+
push!(new_tipping_positions, pos + dir)
84+
end
85+
if world[lockpos + dir] ('[', ']')
86+
push!(new_tipping_positions, lockpos + dir)
87+
end
88+
end
89+
end
90+
if !isempty(new_tipping_positions)
91+
return locate_box_complex!(new_tipping_positions, move_positions, world, dir)
92+
end
93+
return true
94+
end
95+
96+
function move!(move_positions::Set{CartesianIndex{2}}, world::Matrix{Char}, dir::CartesianIndex{2})
97+
if dir[1] == -1
98+
mpsorted = sort(collect(move_positions), by=x->x[1])
99+
else
100+
mpsorted = sort(collect(move_positions), by=x->x[1], rev=true)
101+
end
102+
for pos mpsorted
103+
world[pos + dir], world[pos] = world[pos], world[pos + dir]
104+
end
105+
end
106+
107+
function execute_instructions_p2!(world, instructions)
108+
current = findall(x -> x == '@', world)[1]
109+
world[current] = '.'
110+
for instruction instructions
111+
dir = _to_dir(instruction)
112+
next = current + dir
113+
if world[next] == '.'
114+
current = next
115+
elseif world[next] ('[',']')
116+
if instruction ('>', '<')
117+
while world[next] ('.', '#')
118+
next += dir
119+
end
120+
world[next] == '#' && continue
121+
while next != current
122+
pnext = next - dir
123+
world[next], world[pnext] = world[pnext], world[next]
124+
next = pnext
125+
end
126+
current = current + dir
127+
else
128+
move_positions = Set{CartesianIndex{2}}()
129+
if locate_box_complex!(Set([next]), move_positions, world, dir)
130+
move!(move_positions, world, dir)
131+
end
132+
end
133+
end
134+
end
135+
end
136+
36137
end # module

0 commit comments

Comments
 (0)