Skip to content

Instantly share code, notes, and snippets.

@bk2204
Last active October 26, 2016 01:59
Show Gist options
  • Save bk2204/b163e4c4aaa0aef2ba865acb9033e1ac to your computer and use it in GitHub Desktop.
Save bk2204/b163e4c4aaa0aef2ba865acb9033e1ac to your computer and use it in GitHub Desktop.
An algorithm for eating M&Ms in pairs
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
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