#!/usr/bin/env ruby require_relative '../common' class Day05 < Day class Store def self.parse(input) stacks_data = input.take_while { |line| line != "" } instructions_data = input.drop_while { |line| !line.start_with?("move") } stacks = stacks_data.pop.tr_s(' ', ' ').strip.split(' ') crates = stacks_data.reverse Store.new(stacks.map do |stack| [ stack, crates.map { |row| row[1 + 4 * (stack.to_i - 1)] } .take_while { |crate| crate != " " } ] end.to_h, instructions_data) end attr_reader :stacks def initialize(stacks, instructions) @stacks = stacks @instructions = instructions end def parse(instruction) count, from, to = instruction.match(/move ([0-9]+) from ([0-9]+) to ([0-9]+)/).captures [from, to, count.to_i] end def move_one_by_one(from, to, count) count.times { stacks[to] << stacks[from].pop } end def move_multiple(from, to, count) stacks[to] += stacks[from].pop(count) end def result_part1 @instructions.each { |instruction| move_one_by_one(*parse(instruction)) } stacks.map { |_,v| v.last }.join end def result_part2 @instructions.each { |instruction| move_multiple(*parse(instruction)) } stacks.map { |_,v| v.last }.join end end def part1 Store.parse(stdin).result_part1 end def part2 Store.parse(stdin).result_part2 end end Day05.run