From 337fa5835be1374aebe52fcd509a81d04844c286 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Sun, 9 Dec 2018 14:55:24 -0800 Subject: [PATCH] [2018][ruby][09.2] --- 2018/ruby/day_09.rb | 56 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/2018/ruby/day_09.rb b/2018/ruby/day_09.rb index 64f4068..2bcfea3 100644 --- a/2018/ruby/day_09.rb +++ b/2018/ruby/day_09.rb @@ -1,35 +1,45 @@ +Node = Struct.new(*%i[ value next prev ]) do + def to_s + out = [value] + current = self + loop do + current = current.next + break if current == self + out << current.value + end + out.join(" ") + end +end + ARGF.read.chomp =~ /(\d+) players; last marble is worth (\d+) points/ num_players = $1.to_i -num_marbles = $2.to_i +num_marbles = $2.to_i * 100 -circle = [] -marbles = (0...num_marbles).to_a +current = Node.new(0, nil, nil) +current.next = current.prev = current -zero = marbles.shift -circle << zero - -current_marble_index = 0 current_player = 0 -scores = Hash.new(0) - -until marbles.empty? - current_marble = marbles.shift - - if current_marble % 23 == 0 - scores[current_player] += current_marble - index = (current_marble_index - 7) % circle.size - scores[current_player] += circle.delete_at(index) - current_marble_index = index +scores = Array.new(num_players, 0) + +(1...num_marbles).each do |marble| + if marble % 23 == 0 + scores[current_player] += marble + 7.times { current = current.prev } + scores[current_player] += current.value + current.next.prev = current.prev + current.prev.next = current.next + current = current.next else - index = (current_marble_index + 2) % circle.size - 1 - index += 1 unless index == -1 - circle.insert(index, current_marble) - current_marble_index = index % circle.size + current = current.next + current.next = Node.new(marble, current.next, current) + current = current.next + current.next.prev = current end - # puts "[#{current_player + 1}] #{circle.join(" ")}" + # puts "[#{current_player + 1}] #{current}" + puts marble if marble % 100000 == 0 current_player = (current_player + 1) % num_players end -p scores.max_by(&:last) +p scores.max