Last active
October 26, 2016 01:59
-
-
Save bk2204/b163e4c4aaa0aef2ba865acb9033e1ac to your computer and use it in GitHub Desktop.
An algorithm for eating M&Ms in pairs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MMSorter | |
def initialize(preference) | |
@preference = preference | |
@reverse = preference.each_with_index.to_h | |
end | |
def pairs(candy) | |
# Find the candies which aren't part of a pair and sort them in preference | |
# order. | |
leftovers = candy.select { |_c, cnt| cnt.odd? }.map { |p| p[0] } | |
.sort_by { |c| @reverse[c] } | |
# Collect the pairs. | |
pairs = candy.map { |color, count| [color, color] * (count / 2) } | |
# Form the extras into pairs. | |
pairs += leftovers.each_slice(2).to_a | |
# Order pairs by their most preferred color, preferring identical pairs over | |
# odd pairs. | |
pairs.sort_by { |p| @reverse[p[0]] * @reverse.length + @reverse[p[1]] } | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'mm-sorter' | |
describe MMSorter do | |
before(:each) do | |
@prefs = %i(blue green red yellow orange brown) | |
@sorter = MMSorter.new(@prefs) | |
end | |
it 'should sort paired items in order' do | |
candy = { | |
blue: 2, | |
brown: 2, | |
green: 2, | |
orange: 2, | |
red: 2, | |
yellow: 2 | |
} | |
result = [ | |
%i(blue blue), | |
%i(green green), | |
%i(red red), | |
%i(yellow yellow), | |
%i(orange orange), | |
%i(brown brown), | |
] | |
expect(@sorter.pairs(candy)).to eq result | |
end | |
it 'should sort extra items by first color then by second' do | |
candy = { | |
blue: 3, | |
brown: 3, | |
green: 3, | |
orange: 3, | |
red: 3, | |
yellow: 3 | |
} | |
result = [ | |
%i(blue blue), | |
%i(blue green), | |
%i(green green), | |
%i(red red), | |
%i(red yellow), | |
%i(yellow yellow), | |
%i(orange orange), | |
%i(orange brown), | |
%i(brown brown), | |
] | |
expect(@sorter.pairs(candy)).to eq result | |
end | |
it 'should sort extra items by first color' do | |
candy = { | |
blue: 3, | |
green: 2, | |
orange: 3, | |
red: 2, | |
} | |
result = [ | |
%i(blue blue), | |
%i(blue orange), | |
%i(green green), | |
%i(red red), | |
%i(orange orange), | |
] | |
expect(@sorter.pairs(candy)).to eq result | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment