Merge pull request 'Introduce an invitations penalty for solutions that split guests in the same invitation' (#302) from invitations-penalty into main
All checks were successful
Run unit tests / rubocop (push) Has been skipped
Run unit tests / check-licenses (push) Has been skipped
Run unit tests / copyright_notice (push) Has been skipped
Run unit tests / unit_tests (push) Successful in 58s
Run unit tests / build-static-assets (push) Successful in 8m33s
All checks were successful
Run unit tests / rubocop (push) Has been skipped
Run unit tests / check-licenses (push) Has been skipped
Run unit tests / copyright_notice (push) Has been skipped
Run unit tests / unit_tests (push) Successful in 58s
Run unit tests / build-static-assets (push) Successful in 8m33s
Reviewed-on: #302
This commit is contained in:
commit
c8b88ab3b1
@ -16,6 +16,7 @@ class AffinityGroupsHierarchy < Array
|
||||
end
|
||||
|
||||
discomforts
|
||||
invitation_counts
|
||||
freeze
|
||||
end
|
||||
|
||||
@ -54,8 +55,16 @@ class AffinityGroupsHierarchy < Array
|
||||
Rational(dist, dist + 1)
|
||||
end
|
||||
|
||||
def guest_count(invitation_id)
|
||||
@invitation_counts[invitation_id] || 0
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def invitation_counts
|
||||
@invitation_counts = Guest.where.not(invitation_id: nil).group(:invitation_id).count
|
||||
end
|
||||
|
||||
def discomforts
|
||||
@discomforts ||= GroupAffinity.pluck(:group_a_id, :group_b_id,
|
||||
:discomfort).each_with_object({}) do |(id_a, id_b, discomfort), acc|
|
||||
|
@ -15,7 +15,7 @@ module Tables
|
||||
end
|
||||
|
||||
def breakdown
|
||||
@breakdown ||= { table_size_penalty:, cohesion_penalty: }
|
||||
@breakdown ||= { table_size_penalty:, cohesion_penalty:, invitations_penalty: }
|
||||
end
|
||||
|
||||
private
|
||||
@ -39,6 +39,12 @@ module Tables
|
||||
10 * (cohesion_discomfort * 1.0 / table.size)
|
||||
end
|
||||
|
||||
def invitations_penalty
|
||||
2 * table.map(&:invitation_id)
|
||||
.tally
|
||||
.sum { |invitation_id, guests_in_table| hierarchy.guest_count(invitation_id) - guests_in_table }
|
||||
end
|
||||
|
||||
#
|
||||
# Calculates the discomfort of the table based on the cohesion of the guests. The total discomfort
|
||||
# is calculated as the sum of the discomfort of each pair of guests. The discomfort of a pair of
|
||||
|
@ -14,14 +14,14 @@ module Tables
|
||||
|
||||
describe '#calculate' do
|
||||
before do
|
||||
allow(calculator).to receive_messages(table_size_penalty: 2, cohesion_discomfort: 3)
|
||||
allow(calculator).to receive_messages(table_size_penalty: 2, cohesion_penalty: 5, invitations_penalty: 4)
|
||||
end
|
||||
|
||||
let(:table) { Table.new(create_list(:guest, 6)) }
|
||||
|
||||
it 'returns the sum of the table size penalty and the average cohesion penalty', :aggregate_failures do
|
||||
expect(calculator.calculate).to eq(7)
|
||||
expect(calculator.breakdown).to eq(table_size_penalty: 2, cohesion_penalty: 5)
|
||||
expect(calculator.calculate).to eq(11)
|
||||
expect(calculator.breakdown).to eq(table_size_penalty: 2, cohesion_penalty: 5, invitations_penalty: 4)
|
||||
end
|
||||
end
|
||||
|
||||
@ -131,5 +131,44 @@ module Tables
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#invitations_penalty' do
|
||||
let(:invitation_a) { create(:invitation) }
|
||||
let(:invitation_b) { create(:invitation) }
|
||||
let(:invitation_c) { create(:invitation) }
|
||||
|
||||
let(:table) do
|
||||
create_list(:guest, 2, invitation: invitation_a) +
|
||||
create_list(:guest, 3, invitation: invitation_b) +
|
||||
create_list(:guest, 4, invitation: invitation_c)
|
||||
end
|
||||
|
||||
context 'when the table contains all members of an invitation' do
|
||||
it 'returns 0 as penalty' do
|
||||
expect(calculator.send(:invitations_penalty)).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is an additional guest of one of the invitations that is not included' do
|
||||
before do
|
||||
create(:guest, invitation: invitation_a)
|
||||
end
|
||||
|
||||
it 'returns the penalty for the missing guest' do
|
||||
expect(calculator.send(:invitations_penalty)).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are multiple guests missing from different invitations' do
|
||||
before do
|
||||
create(:guest, invitation: invitation_b)
|
||||
create(:guest, invitation: invitation_c)
|
||||
end
|
||||
|
||||
it 'returns 2x # of guests left out as the total penalty for all missing guests' do
|
||||
expect(calculator.send(:invitations_penalty)).to eq(4)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user