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 <[email protected]>\nLeia Skywalker <[email protected]>\nToula Portokalos <[email protected]>\nGus Portokalos <[email protected]>\nBruce Wayne <[email protected]>\nVirgil Brigman <[email protected]>\nLindsey Brigman <[email protected]>" | |
//let input = "Luke Skywalker <[email protected]>\nLeia Skywalker <[email protected]>\nToula Portokalos <[email protected]>\nGus Portokalos <[email protected]>\nBruce Wayne <[email protected]>\nVirgil Brigman <[email protected]>\nLindsey Brigman <[email protected]>\nFranz Kafka <[email protected]>\nCourtney Kafka <[email protected]>\nSkip Kafka <[email protected]>\nAloysius Kafka <[email protected]>" | |
// This one is not solvable. | |
//let input = "Luke Skywalker <[email protected]>\nLeia Skywalker <[email protected]>\nToula Portokalos <[email protected]>" | |
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