[2022][ruby][10.x] refactor

pull/1/head
Alpha Chen 1 year ago
parent f871f28d27
commit 762e65126a
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -1,25 +1,42 @@
instructions = ARGF.read.lines(chomp: true)
adds = {}
cycle = 1
instructions.each do |instruction|
cycle += case instruction
when /noop/
1
when /addx (-?\d+)/
adds[cycle+1] = $1.to_i
2
else fail instruction
end
def exec(instructions)
return enum_for(__method__, instructions) unless block_given?
x = 1
instructions.each do |instruction|
case instruction
when /noop/
yield x
when /addx (-?\d+)/
yield x
yield x
x += $1.to_i
else
fail "invalid instruction: #{instruction}"
end
end
yield x
end
xs = (0..adds.keys.max).inject([1]) { _1 << _1.last + adds.fetch(_2, 0) }
p 20.step(by: 40, to: 220).map { [_1, xs[_1]] }.sum { _1 * _2 }
x_hist = exec(instructions).to_a
# part one
p 20.step(by: 40, to: 220).sum { x_hist[_1-1] * _1 }
puts 6.times.map {|y|
40.times.map {|x|
cycle = 40*y + x + 1
xx = xs.fetch(cycle, xs.last)
(-1..1).cover?(x - xx) ? ?# : ?.
# part two
puts x_hist.each_slice(40).map {|row|
row.each.with_index.map {|x, cycle|
(-1..1).cover?(cycle - x) ? ?# : ?.
}.join
}.join("\n")
# a functional version of part two, but I think
# the imperative version feels closer to the domain
#
# x_hist.each_slice(40) do |row|
# row.each.with_index do |x, cycle|
# putc (-1..1).cover?(cycle - x) ? ?# : ?.
# end
# puts
# end

@ -0,0 +1,30 @@
require "minitest/autorun"
def exec(instructions)
return enum_for(__method__, instructions) unless block_given?
x = 1
instructions.each do |instruction|
case instruction
when /noop/
yield x
when /addx (-?\d+)/
yield x
yield x
x += $1.to_i
else
fail "invalid instruction: #{instruction}"
end
end
yield x
end
class TestDay10 < Minitest::Test
def test_example
assert_equal [1, 1, 1, 4, 4, -1], exec(<<~PROG.lines(chomp: true)).to_a
noop
addx 3
addx -5
PROG
end
end
Loading…
Cancel
Save