```Hi!

I didn't have the time to implement a complete solution, but at least I'd
like to show my algorithm for assigning the santas.
I start by assigning a random santa to everyone without caring about the
constraints. Then I go through the list of people and for each one not
having a correct santa I swap santas with someone else, so that both have
correct santas afterwards.
As far as I can see, this will only fail when no solution is possible and
should be reasonably unbiased.

Here is the code:

class Person
attr_accessor :santa

def initialize(line)
m = /(\S+)\s+(\S+)\s+<(.*)>/.match(line)
raise unless m
@first = m[1].capitalize
@last = m[2].capitalize
@email = m[3]
end

def can_be_santa_of?(other)
@last != other.last
end
end

people = []
input.each_line do |line|
line.strip!
people << Person.new(line) unless line.empty?
end

santas = people.dup
people.each do |person|
person.santa = santas.delete_at(rand(santas.size))
end

people.each do |person|
unless person.santa.can_be_santa_of? person
candidates = people.select {|p| p.santa.can_be_santa_of?(person) &&
person.santa.can_be_santa_of?(p)}
raise if candidates.empty?
other = candidates[rand(candidates.size)]
temp = person.santa
person.santa = other.santa
other.santa = temp
finished = false
end
end

people.each do |person|
printf "%s %s -> %s %s\n", person.santa.first, person.santa.last,
person.first, person.last
end

--
exoticorn/farbrausch

```