parent
77256e1bf8
commit
47b07ceb34
@ -1,72 +1,90 @@
|
|||||||
layout = ARGF.read.split("\n").map(&:chars)
|
class Layout
|
||||||
Y_MAX = layout.size
|
def self.from(raw, &logic)
|
||||||
X_MAX = layout.first.size
|
seats = Hash.new
|
||||||
|
raw.split("\n").each.with_index do |row,y|
|
||||||
|
row.chars.each.with_index do |pos,x|
|
||||||
|
seats[[y,x]] = false if pos == ?L
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.new(seats, &logic)
|
||||||
|
end
|
||||||
|
|
||||||
# NEIGHBORS = (-1..1).flat_map {|y| (-1..1).map {|x| [y, x] }} - [[0, 0]]
|
attr_reader :seats, :y_max, :x_max
|
||||||
|
|
||||||
# def tick(layout)
|
def initialize(seats, &logic)
|
||||||
# (0...Y_MAX).map {|y|
|
@seats, @logic = seats, logic
|
||||||
# (0...X_MAX).map {|x|
|
@y_max = @seats.keys.map(&:first).max
|
||||||
# occupied = NEIGHBORS
|
@x_max = @seats.keys.map(&:last).max
|
||||||
# .map {|dy,dx| [y+dy, x+dx] }
|
end
|
||||||
# .select {|y,x| (0...Y_MAX).cover?(y) && (0...X_MAX).cover?(x) }
|
|
||||||
# .select {|y,x| layout[y][x] == ?# }
|
|
||||||
# .count
|
|
||||||
# case layout[y][x]
|
|
||||||
# when ?.
|
|
||||||
# ?.
|
|
||||||
# when ?L
|
|
||||||
# occupied == 0 ? ?# : ?L
|
|
||||||
# when ?#
|
|
||||||
# occupied >= 4 ? ?L : ?#
|
|
||||||
# else
|
|
||||||
# fail
|
|
||||||
# end
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# end
|
|
||||||
|
|
||||||
DIRS = (-1..1).flat_map {|y| (-1..1).map {|x| [y, x] }} - [[0, 0]]
|
def [](yx)
|
||||||
|
@seats[yx]
|
||||||
|
end
|
||||||
|
|
||||||
def tick(layout)
|
def each
|
||||||
(0...Y_MAX).map {|y|
|
return enum_for(__method__) unless block_given?
|
||||||
(0...X_MAX).map {|x|
|
|
||||||
next ?. if layout[y][x] == ?.
|
loop do
|
||||||
occupied = DIRS
|
yield self
|
||||||
.map {|dy,dx|
|
seats = tick(&@logic)
|
||||||
(1..)
|
break if seats == @seats
|
||||||
.lazy
|
@seats = seats
|
||||||
.map {|i| [dy*i+y, dx*i+x] }
|
|
||||||
.map {|y,x|
|
|
||||||
if (0...Y_MAX).cover?(y) && (0...X_MAX).cover?(x)
|
|
||||||
layout[y][x]
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
}
|
|
||||||
.find {|s| s != ?. }
|
|
||||||
}
|
|
||||||
.select {|s| s == ?# }
|
|
||||||
.count
|
|
||||||
case occupied
|
|
||||||
when 0
|
|
||||||
?#
|
|
||||||
when (5..)
|
|
||||||
?L
|
|
||||||
else
|
|
||||||
layout[y][x]
|
|
||||||
end
|
end
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
loop do
|
def tick
|
||||||
next_layout = tick(layout)
|
@seats.keys.map {|yx|
|
||||||
break if next_layout == layout
|
[yx, @logic[self, yx]]
|
||||||
layout = next_layout
|
}.to_h
|
||||||
|
end
|
||||||
|
|
||||||
puts layout.map(&:join).join("\n")
|
def to_s
|
||||||
puts
|
(0..@y_max).map {|y|
|
||||||
|
(0..@x_max).map {|x|
|
||||||
|
case @seats[[y,x]]
|
||||||
|
when true then ?#
|
||||||
|
when false then ?L
|
||||||
|
when nil then ?.
|
||||||
|
else fail
|
||||||
|
end
|
||||||
|
}.join
|
||||||
|
}.join("\n")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
p layout.map {|row| row.count(?#) }.sum
|
NEIGHBORS = (-1..1).flat_map {|y| (-1..1).map {|x| [y, x] }} - [[0, 0]]
|
||||||
|
day1 = ->(layout, yx) {
|
||||||
|
y, x = yx
|
||||||
|
occupied_neighbors = NEIGHBORS.filter_map {|dy,dx| layout[[y+dy, x+dx]] }
|
||||||
|
if !layout[yx] && occupied_neighbors.empty?
|
||||||
|
true
|
||||||
|
elsif layout[yx] && occupied_neighbors.size >= 4
|
||||||
|
false
|
||||||
|
else
|
||||||
|
layout[yx]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
day2 = ->(layout, yx) {
|
||||||
|
y, x = yx
|
||||||
|
occupied_neighbors = NEIGHBORS.filter_map {|dy,dx|
|
||||||
|
(1..).lazy
|
||||||
|
.map {|i| [y+dy*i, x+dx*i] }
|
||||||
|
.find {|y,x|
|
||||||
|
!(0..layout.y_max).cover?(y) ||
|
||||||
|
!(0..layout.x_max).cover?(x) ||
|
||||||
|
layout.seats.has_key?([y, x])
|
||||||
|
}
|
||||||
|
}.filter_map {|yx| layout[yx] }
|
||||||
|
if !layout[yx] && occupied_neighbors.empty?
|
||||||
|
true
|
||||||
|
elsif layout[yx] && occupied_neighbors.size >= 5
|
||||||
|
false
|
||||||
|
else
|
||||||
|
layout[yx]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
layout = Layout.from(ARGF.read, &day2)
|
||||||
|
layout.each.take_while(&:itself).last
|
||||||
|
puts layout.seats.count(&:last)
|
||||||
|
Loading…
Reference in new issue