-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_12.rb
102 lines (96 loc) · 2.33 KB
/
day_12.rb
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
def step1(example = false)
input = example == 'example' ? @input_example : @input
run(input)
end
def step2(example = false)
input = example == 'example' ? @input_example : @input
run2(input)
end
def run(input)
map = []
input.each do |line|
map <<
line.chars.map do |x|
if %w[S E].include?(x)
if x == 'S'
0
else
27
end
else
x.ord - 96
end
end
end
start_x = 0
start_y = 0
end_x = 0
end_y = 0
map.each_with_index do |x, idx|
x.each_with_index do |y, idy|
if y == 27
end_x = idx
end_y = idy
end
if y.zero?
start_x = idx
start_y = idy
end
end
end
visited = {}
step(start_x, start_y, map, 0, visited)
p visited["#{end_x}:#{end_y}"]
end
def step(x, y, map, steps, visited)
return visited if !visited["#{x}:#{y}"].nil? && steps >= visited["#{x}:#{y}"]
visited["#{x}:#{y}"] = steps
current = map[x][y]
return visited if current == 27
up = (y - 1 >= 0 ? map[x][y - 1] : 30)
down = (y + 1 <= map.first.size - 1 ? map[x][y + 1] : 30)
left = (x - 1 >= 0 ? map[x - 1][y] : 30)
right = (x + 1 <= map.size - 1 ? map[x + 1][y] : 30)
visited = step(x, y - 1, map, steps + 1, visited) if up - current < 2 || (current == 25 && up == 27)
visited = step(x, y + 1, map, steps + 1, visited) if down - current < 2 || (current == 25 && down == 27)
visited = step(x - 1, y, map, steps + 1, visited) if left - current < 2 || (current == 25 && left == 27)
visited = step(x + 1, y, map, steps + 1, visited) if right - current < 2 || (current == 25 && right == 27)
visited
end
def run2(input)
map = []
input.each do |line|
map <<
line.chars.map do |x|
if %w[S E].include?(x)
if x == 'S'
0
else
27
end
else
x.ord - 96
end
end
end
end_x = 0
end_y = 0
points = []
map.each_with_index do |x, idx|
x.each_with_index do |y, idy|
if y == 27
end_x = idx
end_y = idy
end
points << [idx, idy] if y == 1
end
end
paths = []
points.each_with_index do |point, index|
p "#{index}/#{points.size}"
visited = {}
step(point[0], point[1], map, 0, visited)
paths << visited["#{end_x}:#{end_y}"]
end
p paths.compact.min
end