Skip to content

Commit fadbc0f

Browse files
committed
Day 16 part 1 Ruby solution
1 parent a9a572c commit fadbc0f

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

16-1.rb

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'numo/narray'
4+
require 'algorithms'
5+
6+
class Map
7+
attr_accessor :map
8+
9+
def initialize(input)
10+
@height = input.size
11+
@width = input[0].size
12+
@map = Numo::UInt8.zeros(@height, @width)
13+
@costs = Numo::UInt32.new(@height, @width).fill Numo::UInt32::MAX
14+
15+
@height.times do |y|
16+
@width.times do |x|
17+
case input[y][x]
18+
when '.'
19+
@map[y, x] = 0
20+
when '#'
21+
@map[y, x] = 1
22+
when 'S'
23+
@map[y, x] = 2
24+
@start = { y: y, x: x }
25+
when 'E'
26+
@map[y, x] = 3
27+
@end = { y: y, x: x }
28+
end
29+
end
30+
end
31+
end
32+
33+
def solve!
34+
queue = Containers::MinHeap.new
35+
queue.push(0, { y: @start[:y], x: @start[:x], dir: :east })
36+
37+
until queue.empty?
38+
cost = queue.next_key
39+
pos = queue.pop
40+
41+
y = pos[:y]
42+
x = pos[:x]
43+
dir = pos[:dir]
44+
45+
@costs[y, x] = cost if cost < @costs[y, x]
46+
47+
return cost if y == @end[:y] && x == @end[:x]
48+
49+
case dir
50+
when :north
51+
queue.push(cost + 1, { y: y - 1, x: x, dir: :north }) if @map[y - 1, x] != 1 && @costs[y - 1, x] > cost + 1
52+
queue.push(cost + 1000, { y: y, x: x, dir: :east }) if @map[y, x + 1] != 1 && @costs[y, x + 1] > cost + 1000
53+
queue.push(cost + 1000, { y: y, x: x, dir: :west }) if @map[y, x - 1] != 1 && @costs[y, x - 1] > cost + 1000
54+
when :east
55+
queue.push(cost + 1, { y: y, x: x + 1, dir: :east }) if @map[y, x + 1] != 1 && @costs[y, x + 1] > cost + 1
56+
queue.push(cost + 1000, { y: y, x: x, dir: :south }) if @map[y + 1, x] != 1 && @costs[y + 1, x] > cost + 1000
57+
queue.push(cost + 1000, { y: y, x: x, dir: :north }) if @map[y - 1, x] != 1 && @costs[y - 1, x] > cost + 1000
58+
when :south
59+
queue.push(cost + 1, { y: y + 1, x: x, dir: :south }) if @map[y + 1, x] != 1 && @costs[y + 1, x] > cost + 1
60+
queue.push(cost + 1000, { y: y, x: x, dir: :west }) if @map[y, x - 1] != 1 && @costs[y, x - 1] > cost + 1000
61+
queue.push(cost + 1000, { y: y, x: x, dir: :east }) if @map[y, x + 1] != 1 && @costs[y, x + 1] > cost + 1000
62+
when :west
63+
queue.push(cost + 1, { y: y, x: x - 1, dir: :west }) if @map[y, x - 1] != 1 && @costs[y, x - 1] > cost + 1
64+
queue.push(cost + 1000, { y: y, x: x, dir: :north }) if @map[y - 1, x] != 1 && @costs[y - 1, x] > cost + 1000
65+
queue.push(cost + 1000, { y: y, x: x, dir: :south }) if @map[y + 1, x] != 1 && @costs[y + 1, x] > cost + 1000
66+
end
67+
end
68+
end
69+
70+
def inspect
71+
to_s
72+
end
73+
74+
def to_s
75+
chars = ['.', '#', 'S', 'E']
76+
s = "<#{self.class}:\n"
77+
@height.times do |y|
78+
@width.times do |x|
79+
s += chars[@map[y, x]]
80+
end
81+
s += "\n"
82+
end
83+
s += '>'
84+
s
85+
end
86+
end
87+
88+
map = Map.new File.read('16.input').lines.map(&:strip)
89+
puts map.solve!

0 commit comments

Comments
 (0)