11_seating_system.rb
# Let's apply some logic that doesn't work in general,
# but actually does work for inputs given.
#
# Reason as follows:
#
# For any seat with too few neighbours (corners, etc),
# once they become occupied, they stay that way forever,
# since they will never have occupied neighbours >= threshold.
#
# Thus, the seats adjacent to them, once they become free, will stay that way forever,
# since they will never have zero occupied neighbours.
#
# That in turns makes it some that more seats have too few neighbours and stay occupied forever,
# and the cycle repeats.
#
# This doesn't work in general because the statements above say "once they become occupied/free",
# but there's no guarantee that they actually become that way.
Let's apply some logic that doesn't work in general,
but actually does work for inputs given.

Reason as follows.

For any seat with too few neighbours (corners, etc),
once they become occupied, they stay that way forever,
since they will never have occupied neighbours >= threshold.

Thus, the seats adjacent to them, once they become free, will stay that way forever,
since they will never have zero occupied neighbours.

That in turns makes it some that more seats have too few neighbours and stay occupied forever,
and the cycle repeats.

This doesn't work in general because the statements above say "once they become occupied/free",
but there's no guarantee that they actually become that way.
Let ' s apply some logic that doesn ' t work in general but actually does work for inputs given . Reason as follows . For any seat with too few neighbours ( corners etc ) once they become occupied they stay that way forever since they will never have occupied neighbours > = threshold . Thus the seats adjacent to them once they become free will stay that way forever since they will never have zero occupied neighbours . That in turns makes it some that more seats have too few neighbours and stay occupied forever and the cycle repeats . This doesn ' t work in general because the statements above say " once they become occupied / free " but there ' s no guarantee that they actually become that way .
def equilibrium_logic(_, neighs, occupy_threshold, verbose: false)
  seats = neighs.map.with_index { |neigh, i| neigh && Seat.new(i, neigh) }.freeze
  can_lock_occupied = seats.select { |seat| seat && seat.max_occupied_neigh < occupy_threshold }
  t = 0
  until can_lock_occupied.empty?
    t += 1
    puts "t=#{t} Locking #{can_lock_occupied.uniq.size} occupied" if verbose
    can_lock_empty = can_lock_occupied.flat_map { |seat| seat.lock_occupied(seats) }
    t += 1
    puts "t=#{t} Locking #{can_lock_empty.uniq.size} empty" if verbose
    can_lock_occupied = can_lock_empty.flat_map { |seat| seat.lock_empty(seats, occupy_threshold) }
  end
  unknowns = seats.count { |seat| seat && seat.locked_known.nil? }
  raise "#{unknowns} unknowns" if unknowns != 0
  seats.count { |seat| seat&.locked_known == OCCUPIED }
end
def equilibrium_logic ( _ , neighs , occupy_threshold , verbose : false ) seats = neighs . map . with_index { | neigh , i | neigh && Seat . new ( i , neigh ) } . freeze can_lock_occupied = seats . select { | seat | seat && seat . max_occupied_neigh < occupy_threshold } t = 0 until can_lock_occupied . empty? t += 1 puts "t=#{t} Locking #{can_lock_occupied.uniq.size} occupied" if verbose can_lock_empty = can_lock_occupied . flat_map { | seat | seat . lock_occupied ( seats ) } t += 1 puts "t=#{t} Locking #{can_lock_empty.uniq.size} empty" if verbose can_lock_occupied = can_lock_empty . flat_map { | seat | seat . lock_empty ( seats , occupy_threshold ) } end unknowns = seats . count { | seat | seat && seat . locked_known . nil? } raise "#{unknowns} unknowns" if unknowns != 0 seats . count { | seat | seat &. locked_known == OCCUPIED } end
Let's apply some logic that doesn't work in general,
but actually does work for inputs given.
Let ' s apply some logic that doesn ' t work in general but actually does work for inputs given .
_
<not_specific>
neighs
<not_specific>
occupy_threshold
<not_specific>
verbose
<not_specific>