-
Notifications
You must be signed in to change notification settings - Fork 0
/
day9.rb
76 lines (61 loc) · 1.34 KB
/
day9.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
require 'set'
class Node
attr_accessor :next, :value
def initialize(value)
@value = value
end
end
file = File.open('input9.txt')
steps = file.readlines.map(&:strip)
visits = Set[]
rope = Array.new(ARGV[0].to_i) { Node.new({ x: 0, y: 0 }) }
nexx = nil
rope.reverse.each do |knot|
knot.next = nexx
nexx = knot
end
def touching?(head, tail)
(head[:x] - tail[:x]).abs <= 1 && (head[:y] - tail[:y]).abs <= 1
end
def move_tail(head, tail)
delta_x = head[:x] - tail[:x]
delta_y = head[:y] - tail[:y]
if delta_x.abs >= 2
tail[:x] += delta_x / delta_x.abs
if delta_y.abs > 0
tail[:y] += delta_y / delta_y.abs
end
else
tail[:y] += delta_y / delta_y.abs
if delta_x.abs > 0
tail[:x] += delta_x / delta_x.abs
end
end
tail
end
steps.each do |step|
direction, moves = step.split(' ')
moves.to_i.times do
case direction
when 'L'
rope[0].value[:x] -= 1
when 'U'
rope[0].value[:y] += 1
when 'R'
rope[0].value[:x] += 1
when 'D'
rope[0].value[:y] -= 1
end
rope.each do |knot|
if knot.next.nil?
visits.add([knot.value[:x], knot.value[:y]])
else
head = knot.value
tail = knot.next.value
knot.next.value = move_tail(head, tail) unless touching?(head, tail)
end
end
end
end
puts visits.length
file.close