64 lines
1.5 KiB
Ruby
64 lines
1.5 KiB
Ruby
|
#!/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
|