-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path20-2.rb
executable file
·115 lines (91 loc) · 2.12 KB
/
20-2.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
#!/usr/bin/env ruby
class Linked_List
class Linked_Number
attr_accessor :value, :pos, :back, :forward
def initialize(value, pos, back, forward)
@value = value
@pos = pos
@back = back
@forward = forward
end
def to_s
"<#{self.class}: number #{@value}, original #{@pos}, next #{@forward&.value}, previous #{@back&.value}>"
end
alias inspect to_s
end
def initialize(elements)
@size = elements.size
@elements = Array.new @size
back = nil
forward = nil
elements.each_with_index do |n, value|
num = Linked_Number.new(n, value, back, forward)
back.forward = num if back
back = num
@elements[value] = num
end
@elements[0].back = @elements[-1]
@elements[-1].forward = @elements[0]
end
def unlink!(number)
back = number.back
forward = number.forward
back.forward = forward
number.back = nil
forward.back = back
number.forward = nil
number
end
def link!(number, back, forward)
back.forward = number
number.back = back
forward.back = number
number.forward = forward
end
def size
@size
end
def to_s
cur = @elements[0]
s = ''
loop do
s += cur.value.to_s
s += ', '
cur = cur.forward
break if cur == @elements[0]
end
s
end
attr_accessor :elements
end
input = File.read('20.input').lines.map(&:strip).map(&:to_i).map { |n| n * 811_589_153 }
numbers = Linked_List.new(input)
10.times do
numbers.size.times do |round|
num = numbers.elements.find { |num| num.pos == round }
next if (num.value % (numbers.size - 1)).zero?
back = num.back
old = numbers.unlink!(num)
num = back
if old.value.positive?
(old.value % (numbers.size - 1)).times do
num = num.forward
end
else
(old.value.abs % (numbers.size - 1)).times do
num = num.back
end
end
forward = num.forward
numbers.link!(old, num, forward)
end
end
num = numbers.elements.find { |num| num.value.zero? }
sum = 0
3.times do
1_000.times do
num = num.forward
end
sum += num.value
end
print sum, "\n"