Manuel Bustillo 19d309a2cf
All checks were successful
Check usage of free licenses / build-static-assets (pull_request) Successful in 35s
Add copyright notice / copyright_notice (pull_request) Successful in 1m7s
Run unit tests / unit_tests (pull_request) Successful in 1m44s
Modify initial distribution of tables to guarantee there is no single-person table
2024-11-10 10:16:22 +01:00

69 lines
1.8 KiB
Ruby

# Copyright (C) 2024 Manuel Bustillo
require_relative '../../extensions/tree_node_extension'
module Tables
class Distribution
attr_accessor :tables
def initialize(min_per_table:, max_per_table:)
@min_per_table = min_per_table
@max_per_table = max_per_table
@tables = []
end
def random_distribution(people)
min_tables = (people.count * 1.0 / @max_per_table).ceil
max_tables = (people.count * 1.0 / @min_per_table).ceil
@tables = people.in_groups(rand(min_tables..max_tables), false)
.map { |group| Table.new(group) }
end
def discomfort
@tables.map do |table|
local_discomfort(table)
end.sum
end
def inspect
"#{@tables.count} tables, discomfort: #{discomfort}"
end
def pretty_print
@tables.map.with_index do |table, i|
"Table #{i + 1} (#{table.count} ppl): (#{local_discomfort(table)}) #{table.map(&:full_name).join(', ')}"
end.join("\n")
end
def deep_dup
self.class.new(min_per_table: @min_per_table, max_per_table: @max_per_table).tap do |new_distribution|
new_distribution.tables = @tables.map(&:dup)
end
end
def save!
ActiveRecord::Base.transaction do
arrangement = TablesArrangement.create!
records_to_store = []
tables.each_with_index do |table, table_number|
table.each do |person|
records_to_store << { guest_id: person.id, tables_arrangement_id: arrangement.id, table_number: }
end
end
Seat.insert_all!(records_to_store)
arrangement.update!(discomfort:)
end
end
private
def local_discomfort(table)
table.discomfort ||= DiscomfortCalculator.new(table).calculate
end
end
end