Skip to content

Commit

Permalink
Day 18 - Puzzle 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ariejan committed Dec 18, 2024
1 parent 1c98638 commit f146b9e
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 4 deletions.
138 changes: 135 additions & 3 deletions lib/solutions/day_18.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,141 @@ def part_one(input, w = 70, h = 70, run_corruptions = 1024)
sim.run!
end

def part_two(input)
0
def part_two(input, w = 70, h = 70, run_corruptions = 1024)
sim = DayTwo.new(input, w, h, run_corruptions)
sim.sim!
end

class DayTwo
#Shamelessly stolen from day 16
DIRECTIONS = [
[0, -1], # North
[1, 0], # East
[0, 1], # South
[-1, 0] # West
]

TURN_COST = 1
MOVE_COST = 1

def initialize(input, w = 70, h = 70, run_corruptions = 1024)
@rows = h + 1
@cols = w + 1
@run_corruptions = run_corruptions
@grid = Array.new(@rows) { Array.new(@cols, '.') }

@corruptions = input.split("\n").map { |l| l.split(',').map(&:to_i) }
end

def rain_corruption!(idx)
@corruptions[0..idx].each do |corruption|
set_cell(corruption, '#')
end
end

def set_cell(xy, ch)
x, y = xy
@grid[y][x] = ch
end

def to_s
@grid.map { |r| r.join('') }
end

def sim!
r = (0...@corruptions.size)

result = r.bsearch do |corruption_index|
puts "BSearching #{corruption_index} - #{@corruptions[corruption_index].join(',')}"
@grid = Array.new(@rows) { Array.new(@cols, '.') }
rain_corruption!(corruption_index)
run! == Float::INFINITY
end

@corruptions[result].join(",")
end

def run!
# Run, Dijkstra, Run!
start_xy = [0,0]
end_xy = [@cols - 1, @rows - 1]

direction = 1 # East

# 3D array to keep track of distances from each cell
distances = Array.new(@cols) { Array.new(@rows) { Array.new(4, Float::INFINITY) } }

# Start cell
distances[start_xy[0]][start_xy[1]][direction] = 0

# Priority queue for [cost, x, y, direction]
p_queue = []
p_queue << [0, start_xy[0], start_xy[1], direction]

while !p_queue.empty?
# Sort priority queueu by cost
p_queue.sort_by! { |a| a[0] }

# Get next items from queue
cost, x, y, direction = p_queue.shift

# Reached end
return cost if x == end_xy[0] && y == end_xy[1]

# Skip if we already have a lower cost to this cell
next if distances[x][y][direction] < cost

# Try moving forward
new_x = x + DIRECTIONS[direction][0]
new_y = y + DIRECTIONS[direction][1]

if can_move?(new_x, new_y)
new_cost = cost + MOVE_COST
if new_cost < distances[new_x][new_y][direction]
distances[new_x][new_y][direction] = new_cost
p_queue << [new_cost, new_x, new_y, direction]
end
end

# Try turning
[
direction,
(direction + 1) % 4,
(direction + 2) % 4,
(direction + 3) % 4
].each do |new_dir|
new_dir = (direction - 1) % 4
new_cost = cost # + TURN_COST

if new_cost < distances[x][y][new_dir]
distances[x][y][new_dir] = new_cost
p_queue << [new_cost, x, y, new_dir]
end
end

end

# Can't move forward...
return Float::INFINITY
end

def can_move?(x, y)
return false if x < 0 || x >= @cols
return false if y < 0 || y >= @rows
return false if @grid[y][x] == '#'
true
end


def find_cell(ch)
@grid.each_with_index do |row, y|
x = row.index(ch)
if x
return [x, y]
end
end
nil
end
end

class DayOne
Expand Down Expand Up @@ -34,7 +167,6 @@ def rain_corruption!
x, y = corruption
@grid[y][x] = '#'
end
puts to_s
end

def to_s
Expand Down
2 changes: 1 addition & 1 deletion spec/solutions/day_18_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

describe '#part_two' do
it 'calculates the correct solutions for part two' do
expect(subject.part_two(input)).to eq(0)
expect(subject.part_two(input, 6, 6, 12)).to eq("6,1")
end
end
end
Expand Down

0 comments on commit f146b9e

Please # to comment.