Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
My solution for the Omni Group’s Swift Bike Shedding Club week two question: http://rubyquiz.com/quiz2.html
//: Playground - noun: a place where people can play
import Cocoa
class Person: Hashable {
let firstName: String
let lastName: String
let email: String
var hashValue: Int {
return email.hashValue
}
init(firstName: String, lastName: String, email: String) {
self.firstName = firstName
self.lastName = lastName
self.email = email
}
func canBeSantaFor(person: Person) -> Bool {
return person.lastName != lastName
}
}
func ==(lhs: Person, rhs: Person) -> Bool {
return lhs.email == rhs.email
}
let input = "Luke Skywalker <luke@theforce.net>\nLeia Skywalker <leia@therebellion.org>\nToula Portokalos <toula@manhunter.org>\nGus Portokalos <gus@weareallfruit.net>\nBruce Wayne <bruce@imbatman.com>\nVirgil Brigman <virgil@rigworkersunion.org>\nLindsey Brigman <lindsey@iseealiens.net>"
//let input = "Luke Skywalker <luke@theforce.net>\nLeia Skywalker <leia@therebellion.org>\nToula Portokalos <toula@manhunter.org>\nGus Portokalos <gus@weareallfruit.net>\nBruce Wayne <bruce@imbatman.com>\nVirgil Brigman <virgil@rigworkersunion.org>\nLindsey Brigman <lindsey@iseealiens.net>\nFranz Kafka <franz@kafka.com>\nCourtney Kafka <courtney@kafka.com>\nSkip Kafka <skip@kafka.com>\nAloysius Kafka <aloysius@kafka.com>"
// This one is not solvable.
//let input = "Luke Skywalker <luke@theforce.net>\nLeia Skywalker <leia@therebellion.org>\nToula Portokalos <toula@manhunter.org>"
let lines = input.componentsSeparatedByString("\n")
let people = lines.map { personWithLine($0) }
if let assignments = assignSantas(people) {
for oneSanta in assignments.keys {
let oneRecipient = assignments[oneSanta]!
print("\(oneSanta.firstName) \(oneSanta.lastName) is Santa for \(oneRecipient.firstName) \(oneRecipient.lastName).")
}
}
else {
print("There was no solution.")
}
extension String {
mutating func removeThoseDamnCarets() {
if self.hasPrefix("<") {
self.removeAtIndex(self.startIndex)
}
if self.hasSuffix(">") {
self.removeAtIndex(self.endIndex.advancedBy(-1))
}
}
}
private func personWithLine(line: String) -> Person {
let components = line.componentsSeparatedByString(" ")
let firstName = components[0]
let lastName = components[1]
var email = components[2]
email.removeThoseDamnCarets()
return Person(firstName: firstName, lastName: lastName, email: email)
}
private func possibleRecipientsForSanta(santa: Person, people: [Person]) -> [Person] {
return people.filter { santa.canBeSantaFor($0) }
}
private func assignmentsAreValid(assignments: [Person: Person], people: [Person]) -> Bool {
if (Set(people) != Set(assignments.keys)) {
return false
}
if Set(assignments.values) != Set(assignments.keys) {
return false
}
for oneSanta in assignments.keys {
let recipient = assignments[oneSanta]!
if !oneSanta.canBeSantaFor(recipient) {
return false
}
}
return true
}
private func assignSantas(people: [Person]) -> [Person: Person]? {
let assignments = tryEveryCombination(people, assignments: [Person: Person](), index: 0)
if assignmentsAreValid(assignments, people: people) {
return assignments
}
return nil
}
private func tryEveryCombination(people: [Person], assignments: [Person: Person], index: Int) -> [Person: Person] {
let santa = people[index]
let possibleRecipients = possibleRecipientsForSanta(santa, people: people)
var updatedAssignments = assignments
for oneRecipient in possibleRecipients {
if updatedAssignments.values.contains(oneRecipient) {
continue
}
updatedAssignments[santa] = oneRecipient
if index < people.count - 1 {
updatedAssignments = tryEveryCombination(people, assignments: updatedAssignments, index: index + 1)
}
if assignmentsAreValid(updatedAssignments, people: people) {
return updatedAssignments
}
}
return updatedAssignments
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.