Skip to content

Commit

Permalink
Day 17 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
gregawoods committed Dec 18, 2023
1 parent a84d822 commit 28fd756
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 17 deletions.
5 changes: 5 additions & 0 deletions examples/17_b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
111111111111
999999999991
999999999991
999999999991
999999999991
115 changes: 99 additions & 16 deletions lib/days/17.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ class Day17
require 'fc'
include Util

RIGHT = :right
LEFT = :left
DOWN = :down
UP = :up

Crucible = Struct.new(
:x, :y, :cost, :dir, :moves_in_dir
) do
Expand All @@ -16,7 +21,7 @@ def part1(input)
goal = [grid.length - 1, grid.first.length - 1]

queue = FastContainers::PriorityQueue.new(:min)
queue.push(Crucible.new(0, 0, 0, :down, 0), 0)
queue.push(Crucible.new(0, 0, 0, nil, 0), 0)
visited = Set.new

loop do
Expand All @@ -39,11 +44,6 @@ def part1(input)
end
end

LEFT_TO_RIGHT = :right
RIGHT_TO_LEFT = :left
DOWN = :down
UP = :up

def available_moves(grid, position, current_cost, current_direction, num_direction)
moves = []

Expand Down Expand Up @@ -72,34 +72,117 @@ def available_moves(grid, position, current_cost, current_direction, num_directi
end

if position[0] != grid.length - 1 &&
current_direction != RIGHT_TO_LEFT &&
!(current_direction == LEFT_TO_RIGHT && num_direction >= 3)
current_direction != LEFT &&
!(current_direction == RIGHT && num_direction >= 3)

moves << Crucible.new(
position[0] + 1,
position[1],
current_cost + grid[position[0] + 1][position[1]],
LEFT_TO_RIGHT,
current_direction == LEFT_TO_RIGHT ? num_direction + 1 : 1)
RIGHT,
current_direction == RIGHT ? num_direction + 1 : 1)
end

if !position[0].zero? &&
current_direction != LEFT_TO_RIGHT &&
!(current_direction == RIGHT_TO_LEFT && num_direction >= 3)
current_direction != RIGHT &&
!(current_direction == LEFT && num_direction >= 3)

moves << Crucible.new(
position[0] - 1,
position[1],
current_cost + grid[position[0] - 1][position[1]],
RIGHT_TO_LEFT,
current_direction == RIGHT_TO_LEFT ? num_direction + 1 : 1)
LEFT,
current_direction == LEFT ? num_direction + 1 : 1)
end

moves
end

def part2(_input)
'TODO'
def part2(input)
grid = parse_grid(input, :to_i)
goal = [grid.length - 1, grid.first.length - 1]

queue = FastContainers::PriorityQueue.new(:min)
queue.push(Crucible.new(0, 0, 0, nil, 0), 0)

visited = Set.new

loop do
crucible = queue.top
queue.pop

return crucible.cost if crucible.pos == goal && crucible.moves_in_dir >= 4

next_steps = available_moves_v2(grid, crucible.pos, crucible.cost, crucible.dir, crucible.moves_in_dir)

next_steps.each do |next_step|
hash = [next_step.pos, next_step.dir, next_step.moves_in_dir]
next if visited.include?(hash)

visited.add(hash)
queue.push(next_step, next_step.cost)
end

break if queue.none?
end
end

def available_moves_v2(grid, position, current_cost, current_direction, num_direction)
moves = []

if position[1] != grid.first.length - 1 &&
current_direction != UP &&
!([RIGHT, LEFT].include?(current_direction) && num_direction < 4) &&
!(current_direction == DOWN && num_direction >= 10)

moves << Crucible.new(
position[0],
position[1] + 1,
current_cost + grid[position[0]][position[1] + 1],
DOWN,
current_direction == DOWN ? num_direction + 1 : 1)
end

if !position[1].zero? &&
current_direction != DOWN &&
!([RIGHT, LEFT].include?(current_direction) && num_direction < 4) &&
!(current_direction == UP && num_direction >= 10)

moves << Crucible.new(
position[0],
position[1] - 1,
current_cost + grid[position[0]][position[1] - 1],
UP,
current_direction == UP ? num_direction + 1 : 1)
end

if position[0] != grid.length - 1 &&
current_direction != LEFT &&
!([UP, DOWN].include?(current_direction) && num_direction < 4) &&
!(current_direction == RIGHT && num_direction >= 10)

moves << Crucible.new(
position[0] + 1,
position[1],
current_cost + grid[position[0] + 1][position[1]],
RIGHT,
current_direction == RIGHT ? num_direction + 1 : 1)
end

if !position[0].zero? &&
current_direction != RIGHT &&
!([UP, DOWN].include?(current_direction) && num_direction < 4) &&
!(current_direction == LEFT && num_direction >= 10)

moves << Crucible.new(
position[0] - 1,
position[1],
current_cost + grid[position[0] - 1][position[1]],
LEFT,
current_direction == LEFT ? num_direction + 1 : 1)
end

moves
end

end
4 changes: 3 additions & 1 deletion test/17_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class TestDay17 < Minitest::Test
def setup
@data = File.read(File.join(APP_ROOT, 'examples', '17.txt')).rstrip
@data_b = File.read(File.join(APP_ROOT, 'examples', '17_b.txt')).rstrip
@day = Day17.new
end

Expand All @@ -13,6 +14,7 @@ def test_part1
end

def test_part2
assert_equal @day.part2(@data), ''
assert_equal @day.part2(@data_b), 71
assert_equal @day.part2(@data), 94
end
end

0 comments on commit 28fd756

Please sign in to comment.