-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12part1.rb
120 lines (109 loc) · 2.49 KB
/
day12part1.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
file = File.open "day12in.txt"
grid = []
cost = []
visited = []
unvisited = {}
start = nil
dest = nil
row = 0
col = 0
file.each_line do |l|
grid << []
cost << []
l.chomp.each_char do |c|
if c == "S"
start = [row, col]
grid[row] << 0
cost[row] << 0
unvisited[row.to_s + "_" + col.to_s] = 0
elsif c == "E"
dest = [row, col]
grid[row] << 25
cost[row] << 1e15
else
grid[row] << c.ord - 97
cost[row] << 1e15
end
col += 1
end
row += 1
col = 0
end
def min_hash(hash)
min_key = nil
min_val = 1e16
hash.each do |k, v|
if min_val > v
min_key = k
min_val = v
end
end
min_key
end
def neighbours(grid, row, col)
res = [nil, nil, nil, nil] # N, W, S, E
if col > 0
unless grid[row][col - 1] - 1 > grid[row][col]
res[1] = 1
end
end
if col < grid[0].length - 1 # s
unless grid[row][col + 1] - 1 > grid[row][col]
res[3] = 1
end
end
if row > 0
unless grid[row - 1][col] - 1 > grid[row][col]
res[0] = 1
end
end
if row < grid.length - 1 # e
unless grid[row + 1][col] - 1 > grid[row][col]
res[2] = 1
end
end
res
end
row = start[0]
col = start[1]
until dest == [row, col]
neigh = neighbours grid, row, col # N, W, S, E
neigh.each_with_index do |elem, i|
unless elem.nil?
dest_row = row
dest_col = col
dest_row = row - 1 if i == 0
dest_col = col - 1 if i == 1
dest_row = row + 1 if i == 2
dest_col = col + 1 if i == 3
unless visited.include? [dest_row, dest_col]
unvisited[dest_row.to_s + "_" + dest_col.to_s] = 1e15 if unvisited[dest_row.to_s + "_" + dest_col.to_s].nil?
previous_cost = unvisited[dest_row.to_s + "_" + dest_col.to_s]
current_cost = unvisited[row.to_s + "_" + col.to_s]
unvisited[dest_row.to_s + "_" + dest_col.to_s] = current_cost + 1 if current_cost < previous_cost
if dest == [dest_row, dest_col]
puts "path to dest with cost #{unvisited[dest_row.to_s + "_" + dest_col.to_s]}"
end
end
end
end
visited << [row, col]
unvisited.reject! do |k, v|
if k == (row.to_s + "_" + col.to_s)
cost[row][col] = v
true
else
false
end
end
next_ = min_hash(unvisited)
res = next_.split "_"
new_row = res[0].to_i
new_col = res[1].to_i
if dest == [new_row, new_col]
cost[dest[0]][dest[1]] = unvisited[new_row.to_s + "_" + new_col.to_s]
end
row = new_row
col = new_col
end
puts cost[dest[0]][dest[1]]