Skip to content

Commit

Permalink
Solve 2023-23
Browse files Browse the repository at this point in the history
  • Loading branch information
bcc32 committed Dec 23, 2023
1 parent 2832fc2 commit 6fab3e1
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 0 deletions.
79 changes: 79 additions & 0 deletions 2023/23/sol1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
require 'set'

$stdout = File.open('aoc.out', 'w')
grid = File.open('aoc.in') do |f|
f.readlines.map do |line|
line.chomp.chars
end
end

start_x = 0
start_y = grid[0].index { |c| c == '.' }

# def bfs(grid, start_x, start_y)
# q = [[start_x, start_y]]
# max_dist = { q[0] => 0 }

# until q.empty?
# x, y = q.shift
# d = max_dist[[x, y]]

# dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
# case grid[x][y]
# when '<'
# dirs = [[0, -1]]
# when '>'
# dirs = [[0, 1]]
# when '^'
# dirs = [[-1, 0]]
# when 'v'
# dirs = [[1, 0]]
# end
# dirs.each do |dx, dy|
# next unless (0...grid.size) === (x + dx) && (0...grid[0].size) === (y + dy)
# next if grid[x + dx][y + dy] == '#'

# cand = d + 1
# if !max_dist[[x + dx, y + dy]] || cand > max_dist[[x + dx, y + dy]]
# max_dist[[x + dx, y + dy]] = cand
# end
# end
# end
# end

def dfs_max_length(grid, start_x, start_y, visited)
if visited.include?([start_x, start_y])
return 0
end

if start_x == grid.size - 1
return visited.size
end

visited << [start_x, start_y]

dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
case grid[start_x][start_y]
when '<'
dirs = [[0, -1]]
when '>'
dirs = [[0, 1]]
when '^'
dirs = [[-1, 0]]
when 'v'
dirs = [[1, 0]]
end

ans = dirs.map do |dx, dy|
next unless (0...grid.size) === (start_x + dx) && (0...grid[0].size) === (start_y + dy)
next if grid[start_x + dx][start_y + dy] == '#'

dfs_max_length(grid, start_x + dx, start_y + dy, visited)
end.compact.max

visited.delete [start_x, start_y]

ans || -Float::INFINITY
end

p dfs_max_length(grid, start_x, start_y, Set.new)
107 changes: 107 additions & 0 deletions 2023/23/sol2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
require 'set'

$stdout = File.open('aoc.out', 'w')
grid = File.open('aoc.in') do |f|
f.readlines.map do |line|
line.chomp.chars
end
end

start_x = 0
start_y = grid[0].index { |c| c == '.' }

end_x = grid.size - 1
end_y = grid.last.index('.')

$interesting_points = Set.new
$interesting_points << [start_x, start_y]
$interesting_points << [end_x, end_y]

# other interesting points are those with more than 2 neighbors

grid.size.times do |x|
grid[0].size.times do |y|
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
next if grid[x][y] == '#'
if dirs.count { |dx, dy| (0...grid.size) === (x + dx) && (0...grid[0].size) === (y + dy) && grid[x + dx][y + dy] != '#' } > 2
$interesting_points << [x, y]
end
end
end

# p ['interesting', $interesting_points]

$cache = {}
def shortest_distance(grid, x1, y1, x2, y2)
$cache[[x1, y1]] ||=
begin
q = [[x1, y1]]
d = { q[0] => 0 }
until q.empty?
# p q
x, y = q.shift
if [x, y] != [x1, y1] && $interesting_points.include?([x, y])
next
end
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
dirs.each do |dx, dy|
next unless (0...grid.size) === x+dx && (0...grid[0].size) === y+dy
next if grid[x+dx][y+dy] == '#'
next if d[[x + dx, y + dy]]
d[[x+dx,y+dy]] = d[[x,y]] + 1
q << [x+dx, y+dy]
end
end
d
end

$cache[[x1, y1]][[x2, y2]]
end

$adj = Hash.new { |h, k| h[k] = [] }

$points_flat = $interesting_points.to_a

$points_flat.each_with_index do |u, i|
$points_flat.each_with_index do |v, j|
if shortest_distance(grid, *u, *v)
$adj[i] << j
end
end
end

# p shortest_distance(grid, 0, 1, 5, 3)
# p shortest_distance(grid, 5, 3, 3, 11)

$max = 0

# this works but is too slow
def dfs_longest_path(grid, start, stop, visited, current_total)
if visited[start]
return 0
end

if start == stop
$max = [$max, current_total].max
p $max
return current_total
end

visited[start] = true

ans = $adj[start].map do |next_point|
d = shortest_distance(grid, *$points_flat[start], *$points_flat[next_point])
dfs_longest_path(grid, next_point, stop, visited, current_total + d)
end.compact.max

visited[start] = false

ans || -Float::INFINITY
end

# Takes about 3 minutes to run on my fastest machine
p dfs_longest_path(grid,
$points_flat.index([start_x, start_y]),
$points_flat.index([end_x, end_y]),
Array.new($points_flat.size, false),
0)

0 comments on commit 6fab3e1

Please sign in to comment.