parent
b33e678c7e
commit
34cb639327
@ -0,0 +1,117 @@ |
||||
require "advent" |
||||
|
||||
input = input(2020, 23).lines[0].chars.map &.to_i32 |
||||
|
||||
class Array(T) |
||||
def get(i) |
||||
self[i % size] |
||||
end |
||||
|
||||
def del(i) |
||||
delete_at(i % size) |
||||
end |
||||
end |
||||
|
||||
class Node |
||||
property next : Node |
||||
property int : Int32 |
||||
|
||||
def initialize(@int, @next) |
||||
end |
||||
|
||||
def insert(other : Node, n = 1) |
||||
set_next = other |
||||
(n-1).times { set_next = set_next.@next } |
||||
set_next.next = @next |
||||
@next = other |
||||
end |
||||
|
||||
def remove(n = 1) |
||||
curr = self |
||||
to_return = self.next |
||||
n.times { curr = curr.@next } |
||||
@next = curr.@next |
||||
to_return |
||||
end |
||||
|
||||
def find(n) |
||||
start = self |
||||
while start.int != n |
||||
start = start.next |
||||
end |
||||
return start |
||||
end |
||||
|
||||
def to_s(n) |
||||
return "" if n < 0 |
||||
return "#{@int} -> #{@next.to_s(n-1)}" |
||||
end |
||||
|
||||
def includes?(n, count) |
||||
return false if count <= 0 |
||||
return @int == n || @next.includes?(n, count-1) |
||||
end |
||||
end |
||||
|
||||
class Cups |
||||
getter size : Int32 |
||||
getter head : Node |
||||
|
||||
def initialize(list : Array(Int32)) |
||||
@cache = {} of Int32 => Node |
||||
h = list.delete_at(0) |
||||
temp = uninitialized Node |
||||
@cache[h] = @head = Node.new(h, temp) |
||||
@size = list.size |
||||
@local_min = list.min.as(Int32) |
||||
@local_max = list.max.as(Int32) |
||||
@head.next = @head |
||||
curr = @head |
||||
list.each do |n| |
||||
@cache[n] = new = Node.new(n, curr.next) |
||||
curr.insert(new) |
||||
curr = new |
||||
end |
||||
end |
||||
|
||||
def to_s |
||||
@head.to_s(@size) |
||||
end |
||||
|
||||
def step |
||||
first = @head |
||||
after = first.remove(3) |
||||
m = first.int - 1 |
||||
while after.includes?(m, 3) || m < @local_min |
||||
m = (m < @local_min) ? @local_max : (m - 1) |
||||
end |
||||
@cache[m].insert(after, 3) |
||||
@head = @head.next |
||||
end |
||||
end |
||||
|
||||
def play(input, count) |
||||
cups = Cups.new input |
||||
count.times { |n| cups.step } |
||||
cups |
||||
end |
||||
|
||||
def part1(input) |
||||
cups = play(input.clone, 100) |
||||
cups.head.find(1).next.to_s(cups.size - 1).gsub(" -> ", "") |
||||
end |
||||
|
||||
def part2(input) |
||||
list = input.clone |
||||
max = input.max |
||||
(1000000 - input.size).times do |
||||
max += 1 |
||||
list << max |
||||
end |
||||
cups = play(list, 10000000) |
||||
one = cups.head.find(1) |
||||
one.next.int.to_i64 * one.next.next.int |
||||
end |
||||
|
||||
puts "Part 1: #{part1(input)}" |
||||
puts "Part 2: #{part2(input)}" |
Loading…
Reference in new issue