Skip to content

Instantly share code, notes, and snippets.

@herval
Created April 6, 2010 20:50
Show Gist options
  • Save herval/358093 to your computer and use it in GitHub Desktop.
Save herval/358093 to your computer and use it in GitHub Desktop.
Perl-ish solution for the Secret Santas Ruby Quiz (http://rubyquiz.com/quiz2.html)
# Perl-ish solution for the Secret Santas Ruby Quiz (http://rubyquiz.com/quiz2.html)
santas = "Luke Skywalker <luke@theforce.net>
Leia Skywalker <leia@therebellion.org>
Gus Portokalos <gus@weareallfruit.net>
Toula Portokalos <toula@manhunter.org>
Bruce Wayne <bruce@imbatman.com>
Virgil Brigman <virgil@rigworkersunion.org>
Lindsey Brigman <lindsey@iseealiens.net>
".split("\n")
def give_and_take!(santas)
givers, takers, giving = santas.sort_by { rand }, santas.sort_by { rand }, {}
while !givers.empty? && (giver, taker = givers.last.split[1], takers.last.split[1])
(giver == taker || givers.empty?) ? break : (giving[givers.pop] = takers.pop)
end
giving
end
def too_many_people_per_family?(santas)
map = {}
santas.each { |s| map[s.split[1]] ||= []; map[s.split[1]] << s }
biggies = map.keys.select { |k| k if ((map[k].size.to_f/santas.size) > 0.5) }
biggies.each { |e| p "Too many people on the #{e} family!" }
!biggies.empty?
end
def try_and_try_and_try!(santas)
return if too_many_people_per_family?(santas)
giving = {}
giving = give_and_take!(santas) while (giving.keys.size != santas.size)
giving.each { |k, v| p "#{k.split[0..1].join(' ')} => #{v.split[0..1].join(' ')}" }
end
try_and_try_and_try!(santas)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment