-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12b_solution.rb
50 lines (40 loc) · 1.18 KB
/
12b_solution.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
require 'set'
input = File.read("./12input.txt").split("\n").map do |line|
line.split("-")
end
$edges = Hash.new { |h, k| h[k] = Set.new }
input.each do |nodeA, nodeB|
$edges[nodeA].add nodeB
$edges[nodeB].add nodeA
end
# returns two booleans: [permission, double_visited]
# - permission determines if path can be taken
# - double_visited indicates if a small cave was visited twice
def check_path(from, to, visited_caves, double_visited)
if to == 'start'
[false, double_visited]
elsif to.downcase == to && visited_caves.include?(to) # visiting small cave twice
if double_visited
[false, true]
else
[true, true]
end
else
[true, double_visited]
end
end
# returns number of paths from "from" to end
def find_paths(from, visited_caves, double_visited)
return 1 if from == 'end'
$edges[from].inject(0) do |a, neighbour|
permission, new_double_visited = check_path(from, neighbour, visited_caves, double_visited)
if !permission
a
else
new_visited_caves = visited_caves + [neighbour]
a + find_paths(neighbour, new_visited_caves, new_double_visited)
end
end
end
paths = find_paths('start', Set.new, false)
puts paths