#!/usr/bin/env ruby require "debug" require "matrix" input = (ARGV.first.nil? ? DATA : ARGF) .read .scan(/(\d+)/m) .each_slice(6) .to_a .map { _1.flatten.map(&:to_i).each_slice(2).to_a } .map { [:a, :b, :prize].zip(_1).to_h } def solve(input, offset = 0) input.map do |machine| a = Matrix.columns([ # why does rotating matrix work? [machine[:a].first, machine[:a].last], [machine[:b].first, machine[:b].last] ]) b = Matrix[ [machine[:prize].first + offset], [machine[:prize].last + offset] ] (a.inverse * b).to_a.flatten end .select { _1.denominator == 1 && _2.denominator == 1 } .map { 3 * _1 + _2 } .sum end p solve(input).to_i p solve(input, 10_000_000_000_000).to_i __END__ Button A: X+94, Y+34 Button B: X+22, Y+67 Prize: X=8400, Y=5400 Button A: X+26, Y+66 Button B: X+67, Y+21 Prize: X=12748, Y=12176 Button A: X+17, Y+86 Button B: X+84, Y+37 Prize: X=7870, Y=6450 Button A: X+69, Y+23 Button B: X+27, Y+71 Prize: X=18641, Y=10279