Use immutable data structures to calculate variations

This commit is contained in:
Manuel Bustillo 2024-08-02 18:42:24 +02:00
parent 60b96ab82d
commit c2feb229d2
5 changed files with 39 additions and 17 deletions

View File

@ -12,6 +12,22 @@ module Tables
@tables.values.freeze @tables.values.freeze
end end
def deep_freeze
@tables.each_value(&:freeze)
@tables.freeze
freeze
end
def replace(table)
@tables[table.id] = table
end
def dup
super.tap do |new_distribution|
new_distribution.instance_variable_set(:@tables, @tables.dup)
end
end
def <<(array) def <<(array)
Table.new(array).tap do |table| Table.new(array).tap do |table|
@tables[table.id] = table @tables[table.id] = table
@ -22,6 +38,9 @@ module Tables
@tables = {} @tables = {}
self << people.slice!(0..rand(@min_per_table..@max_per_table)) while people.any? self << people.slice!(0..rand(@min_per_table..@max_per_table)) while people.any?
@tables.freeze
freeze
end end
def discomfort def discomfort

View File

@ -8,25 +8,23 @@ module Tables
def each def each
@initial_solution.tables.combination(2) do |table_a, table_b| @initial_solution.tables.combination(2) do |table_a, table_b|
table_a.product(table_b).each do |(person_a, person_b)| table_a.product(table_b).each do |(person_a, person_b)|
original_discomfort_a = table_a.reset new_solution = @initial_solution.dup
original_discomfort_b = table_b.reset
table_a.delete(person_a) new_table_a = table_a.dup
table_b.delete(person_b) new_table_b = table_b.dup
table_a << person_b new_solution.replace(new_table_a)
table_b << person_a new_solution.replace(new_table_b)
yield(@initial_solution) new_table_a.delete(person_a)
ensure new_table_b.delete(person_b)
table_a.delete(person_b)
table_b.delete(person_a)
table_a << person_a new_table_a << person_b
table_b << person_b new_table_b << person_a
table_a.discomfort = original_discomfort_a new_solution.freeze
table_b.discomfort = original_discomfort_b
yield(new_solution)
end end
end end
end end

View File

@ -18,5 +18,11 @@ module Tables
def discomfort def discomfort
@discomfort ||= DiscomfortCalculator.new(self).calculate @discomfort ||= DiscomfortCalculator.new(self).calculate
end end
def dup
super.tap do |new_table|
new_table.discomfort = nil
end
end
end end
end end

View File

@ -1,4 +1,4 @@
NUMBER_OF_GUESTS = 50 NUMBER_OF_GUESTS = ENV['SEED_GUEST_COUNT'].presence.to_i || 50
TablesArrangement.delete_all TablesArrangement.delete_all
Expense.delete_all Expense.delete_all
@ -21,7 +21,6 @@ Expense.create!(name: 'Transportation', amount: 3000, pricing_type: 'fixed')
Expense.create!(name: 'Invitations', amount: 200, pricing_type: 'fixed') Expense.create!(name: 'Invitations', amount: 200, pricing_type: 'fixed')
Expense.create!(name: 'Cake', amount: 500, pricing_type: 'fixed') Expense.create!(name: 'Cake', amount: 500, pricing_type: 'fixed')
samples = { samples = {
close_family_a: 10, close_family_a: 10,
close_family_b: 10, close_family_b: 10,