65 lines
1.4 KiB
Ruby
65 lines
1.4 KiB
Ruby
class PrintingDepartment
|
|
attr_reader :rows, :removed_rolls
|
|
def initialize(rows)
|
|
@rows = rows
|
|
@removed_rolls = []
|
|
end
|
|
|
|
def self.for(string)
|
|
new string.split("\n").map{ |row| row.split("") }
|
|
end
|
|
|
|
def rolls
|
|
rows.each_with_index.map do |row, row_index|
|
|
row.each_with_index.map do |char, column_index|
|
|
[row_index, column_index] if char == "@"
|
|
end.compact
|
|
end.flatten(1)
|
|
end
|
|
|
|
def char_at(row, column)
|
|
rows[row][column]
|
|
end
|
|
|
|
def width
|
|
rows[0].length
|
|
end
|
|
|
|
def height
|
|
rows.length
|
|
end
|
|
|
|
def neighbor_indices(row, column)
|
|
[0, row - 1].max.upto([width - 1, row + 1].min).map do |r|
|
|
[0, column - 1].max.upto([height - 1, column + 1].min).map do |c|
|
|
[r, c]
|
|
end
|
|
end.flatten(1).reject{ |r, c| r == row && c == column }
|
|
end
|
|
|
|
def neighbors(row, column)
|
|
neighbor_indices(row, column).map { |nr, nc| char_at nr, nc }
|
|
end
|
|
|
|
def adjacent_roll_count(row, column)
|
|
neighbors(row, column).select { |char| char == "@" }.count
|
|
end
|
|
|
|
def accessible_rolls
|
|
rolls.select{ |r, c| adjacent_roll_count(r, c) < 4 }
|
|
end
|
|
|
|
def remove_roll!(row, col)
|
|
removed_rolls << [row, col]
|
|
rows[row][col] = "."
|
|
end
|
|
|
|
def remove_accessible_rolls!
|
|
accessible_rolls.each { |r, c| remove_roll! r, c }
|
|
end
|
|
|
|
def remove_all_accessible_rolls!
|
|
remove_accessible_rolls! until accessible_rolls.empty?
|
|
end
|
|
end
|