Created
September 25, 2015 17:30
-
-
Save brentsimmons/418b4389a1b404bd7678 to your computer and use it in GitHub Desktop.
My solution for the Omni Group’s Swift Bike Shedding Club week two question: http://rubyquiz.com/quiz2.html
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
//: 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