|
| 1 | +#!/usr/bin/ruby |
| 2 | +require 'matrix' |
| 3 | +require 'test/unit' |
| 4 | +require 'pry' |
| 5 | +require 'digest' |
| 6 | + |
| 7 | +class Game |
| 8 | + def initialize(init) |
| 9 | + @nums = init.split(//).map(&:to_i) |
| 10 | + @cur = create_list(@nums) |
| 11 | + end |
| 12 | + |
| 13 | + def resolve_1(start) |
| 14 | + r = [] |
| 15 | + cur = start |
| 16 | + while @cups[cur][:next][:num] != start |
| 17 | + r << @cups[cur][:next][:num] |
| 18 | + cur = @cups[cur][:next][:num] |
| 19 | + end |
| 20 | + r.join |
| 21 | + end |
| 22 | + |
| 23 | + def step(n) |
| 24 | + n.times do |i| |
| 25 | + puts "--- move #{i + 1} ---" if i % 500_000 == 0 |
| 26 | + @keeps = [ |
| 27 | + @cur[:next], @cur[:next][:next], @cur[:next][:next][:next] |
| 28 | + ] |
| 29 | + @cur[:next] = @keeps.last[:next] |
| 30 | + dest = find_dest |
| 31 | + @keeps.last[:next] = dest[:next] |
| 32 | + dest[:next] = @keeps.first |
| 33 | + @cur = @cur[:next] |
| 34 | + end |
| 35 | + [@cups[1][:next][:num], @cups[1][:next][:next][:num]] |
| 36 | + end |
| 37 | + |
| 38 | + def find_dest |
| 39 | + keep_nums = @keeps.map{|k| k[:num]} |
| 40 | + target = @cur[:num] - 1 |
| 41 | + target -= 1 while keep_nums.include?(target) && target != 0 |
| 42 | + target = @cups[-1][:num] if target == 0 |
| 43 | + target -= 1 while keep_nums.include?(target) |
| 44 | + @cups[target] |
| 45 | + end |
| 46 | + |
| 47 | + def complete_circle |
| 48 | + range = ((@nums.max + 1)..1_000_000).to_a |
| 49 | + create_list(range) |
| 50 | + @cups[@nums.last][:next] = @cups[range.first] |
| 51 | + @cups[range.last][:next] = @cups[@nums.first] |
| 52 | + end |
| 53 | + |
| 54 | + def create_list(arr) |
| 55 | + @cups ||= [] |
| 56 | + @cups[arr.first] = cur = { num: arr.first, next: nil } |
| 57 | + nxt = cur |
| 58 | + arr[1..-1].reverse.each do |num| |
| 59 | + nxt = @cups[num] = { num: num, next: nxt } |
| 60 | + end |
| 61 | + cur[:next] = @cups[arr[1]] |
| 62 | + cur |
| 63 | + end |
| 64 | +end |
| 65 | + |
| 66 | +class Day22Test < Test::Unit::TestCase |
| 67 | + def test_star_1 |
| 68 | + game = Game.new('389125467') |
| 69 | + game.step(10) |
| 70 | + assert_equal '92658374', game.resolve_1(1) |
| 71 | + end |
| 72 | + |
| 73 | + def test_star_1_final |
| 74 | + game = Game.new('318946572') |
| 75 | + game.step(100) |
| 76 | + assert_equal '52864379', game.resolve_1(1) |
| 77 | + end |
| 78 | + |
| 79 | + def test_star_2 |
| 80 | + game = Game.new('389125467') |
| 81 | + game.complete_circle |
| 82 | + assert_equal 149245887792, game.step(10_000_000).inject(&:*) |
| 83 | + end |
| 84 | + |
| 85 | + def test_star_2_final |
| 86 | + game = Game.new('318946572') |
| 87 | + game.complete_circle |
| 88 | + assert_equal 11591415792, game.step(10_000_000).inject(&:*) |
| 89 | + end |
| 90 | +end |
0 commit comments