On Day 8 we can play around with tiny LCD screen which is 50 pixels wide and 6 pixels tall. Our input contains a set of instructions that can lit some pixels. This input looks like this:
rect 3x2
rotate column x=1 by 1
rotate row y=0 by 4
rotate column x=1 by 1
Here are example outputs after performing above instructions:
###....
###....
.......
#.#....
###....
.#.....
....#.#
###....
.#.....
.#..#.#
#.#....
.#.....
In Part A we need to output how many pixels are lit after performing all instructions from the input and in Part B we need to render what’s on the LCD.
Here is my solution for both parts:
WIDTH = 50
HEIGHT = 6
data = File.readlines("8.txt", chomp: true).map do |line|
if line =~ /rect (\d+)x(\d+)/
captures = Regexp.last_match.captures
[:rect, *captures.map(&:to_i)]
elsif line =~ /rotate row y=(\d+) by (\d+)/
captures = Regexp.last_match.captures
[:row, *captures.map(&:to_i)]
elsif line =~ /rotate column x=(\d+) by (\d+)/
captures = Regexp.last_match.captures
[:column, *captures.map(&:to_i)]
end
end
screen = (0..(HEIGHT - 1)).map { |_| Array.new(WIDTH, false) }
def display(screen)
screen.map do |row|
row.map do |cell|
cell ? "#" : "."
end.join
end
end
def rect(screen, x, y)
y.times do |row|
x.times do |column|
screen[row][column] = true
end
end
screen
end
def row(screen, y, by)
screen[y].rotate!(-by)
screen
end
def column(screen, x, by)
temp = Array.new(HEIGHT, nil)
HEIGHT.times do |row|
temp[row] = screen[row][x]
end
temp.rotate!(-by)
HEIGHT.times do |row|
screen[row][x] = temp[row]
end
screen
end
def count(screen)
screen.map do |row|
row.select { |cell| cell }.size
end.sum
end
data.each do |command, *arguments|
screen = send(command, screen, *arguments)
end
puts display(screen)
puts count(screen)