-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathd15.rb
More file actions
70 lines (51 loc) · 1.76 KB
/
d15.rb
File metadata and controls
70 lines (51 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# frozen_string_literal: true
require_relative '../day'
class Day15 < Day
DIRECTION_MODIFIERS = [
[1, 0], [-1, 0],
[0, 1], [0, -1]
].freeze
def part_one
map, tentative_distances, unvisited_nodes, size = parse_input(read_input)
current_node = [0, 0]
target_node = [size - 1, size - 1]
while unvisited_nodes.key?(target_node)
neighbors = neighbors(current_node, size)
neighbors.each do |neighbor|
next unless unvisited_nodes.key?(neighbor)
distance = tentative_distances[current_node] + map[neighbor]
tentative_distances[neighbor] = distance if distance < tentative_distances[neighbor]
unvisited_nodes[neighbor] = tentative_distances[neighbor] if unvisited_nodes.key?(neighbor)
end
unvisited_nodes.delete(current_node)
current_node = unvisited_nodes.min_by { |_k, v| v }[0] # TODO: Here is probably the main bottleneck
end
tentative_distances[target_node].to_s
end
def part_two
'-'
end
private
def neighbors(node, limit)
neighbors_nodes = DIRECTION_MODIFIERS.map do |(mx, my)|
[node[0] + mx, node[1] + my]
end
neighbors_nodes.reject! do |x, y|
x.negative? || y.negative? || x >= limit || y >= limit
end
neighbors_nodes
end
def parse_input(input)
map = {}
unvisited_nodes = { [0, 0] => 0 }
tentative_distances = { [0, 0] => 0 }
input.lines(chomp: true).each_with_index.map do |line, y|
line.chars.each_with_index.map do |item, x|
map[[x, y]] = item.to_i
tentative_distances[[x, y]] = Float::INFINITY unless [x, y] == [0, 0]
unvisited_nodes[[x, y]] = Float::INFINITY unless [x, y] == [0, 0]
end
end
[map, tentative_distances, unvisited_nodes, Math.sqrt(map.size).to_i]
end
end