-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path20.rb
executable file
·77 lines (63 loc) · 1.77 KB
/
20.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
#!/usr/bin/env ruby
require 'pp'
class Time
def to_ms
(self.to_f * 1000.0).to_i
end
end
def tests; end
def parse(filename)
chars = File.read(filename).strip
raise 'Invalid file beginning' unless chars[0] == '^'
raise 'Invalid file ending' unless chars[chars.length - 1] == '$'
chars[0] = ''
chars.chomp('$')
end
def parse2(filename)
positions = []
distance = 0
distance_for_position = Hash.new(0)
current_position = Complex(0, 0)
chars = parse(filename)
chars.each_char do |x|
if x == '('
positions.push(current_position)
elsif x == ')'
current_position = positions.pop
elsif x == '|'
current_position = positions[-1]
elsif %w[N E S W].include? x
distance += 1
new_position = change_position(current_position, x)
compare_these = [distance_for_position[current_position] + 1]
if distance_for_position.key?(new_position)
compare_these.push(distance_for_position[new_position])
end
distance_for_position[new_position] = compare_these.min
current_position = new_position
end
end
distance_for_position
end
def change_position(current_position, letter)
return current_position + Complex(0, 1) if letter == 'N'
return current_position + Complex(0, -1) if letter == 'S'
return current_position + Complex(-1, 0) if letter == 'W'
return current_position + Complex(1, 0) if letter == 'E'
current_position
end
def part1(filename)
distances = parse2(filename)
distances.values.max
end
def part2(filename)
distances = parse2(filename)
distances.values.select { |x| x >= 1_000 }.count
end
begin_tests = Time.now
tests
end_tests = Time.now
puts "All tests passed - #{end_tests.to_ms - begin_tests.to_ms}ms"
filename = 'input.txt'
puts part1(filename)
puts part2(filename)