Created
August 27, 2019 09:20
-
-
Save zakbarlow1995/1f3b0152a3a18296e66e91f061a1f6d8 to your computer and use it in GitHub Desktop.
Rugby World Cup 2019 Sweepstakes
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
import Foundation | |
class Person { | |
let name: String | |
private var teams = [Team]() | |
public var sortedTeams: [Team] { | |
return teams.sorted(by: { $0.rank < $1.rank }) | |
} | |
public var highestTeamRank: Int? { | |
return teams.map { $0.rank }.max() | |
} | |
public var lowestTeamRank: Int? { | |
return teams.map { $0.rank }.min() | |
} | |
init(name: String) { | |
self.name = name | |
} | |
public func add(_ team: Team) { | |
teams.append(team) | |
} | |
} | |
class Team { | |
let name: String | |
let rank: Int | |
init(name: String, rank: Int) { | |
self.name = name | |
self.rank = rank | |
} | |
} | |
final class Sweepstakes { | |
static let sharedInstance = Sweepstakes() | |
private init() {} | |
private var people = [Person]() | |
private var teams = [Team]() | |
func set(people: [Person]) { | |
self.people = people | |
} | |
func setPeopleByNames(_ names: [String]) { | |
self.people = names.map { Person(name: $0) } | |
} | |
func setPeopleByNames(_ names: String...) { | |
self.people = names.map { Person(name: $0) } | |
} | |
/// Default value WRC-2019 teams. Rankings accurate as of 19 August 2019. | |
func setTeams(_ teams: [Team] = [Team(name: "Ireland", rank: 3), Team(name: "Scotland", rank: 8), Team(name: "Japan", rank: 9), Team(name: "Russia", rank: 20), Team(name:"Samoa", rank: 16), Team(name: "New Zealand", rank: 2), Team(name: "South Africa", rank: 4), Team(name: "Italy", rank: 13), Team(name: "Namibia", rank: 23), Team(name: "Canada", rank: 21), Team(name: "England", rank: 5), Team(name: "France", rank: 7), Team(name: "Argentina", rank: 11), Team(name: "United States", rank: 14), Team(name: "Tonga", rank: 15), Team(name: "Australia", rank: 6), Team(name: "Wales", rank: 1), Team(name: "Georgia", rank: 12), Team(name: "Fiji", rank: 10), Team(name: "Uruguay", rank: 19)] ) { | |
self.teams = teams | |
} | |
func performSweepStakesAssignment(people: [String], teams: [String]) { | |
assert(!people.isEmpty && !teams.isEmpty && people.count <= teams.count, "Illegal combination of people/teams - both must be non-empty and #people <= #teams") | |
var shuffledTeams = teams.shuffled() | |
for person in people.shuffled() { | |
guard let randomTeam = shuffledTeams.popLast() else { | |
print("SWEEPSTAKES - No more teams left to assign for \(person)") | |
return | |
} | |
print("SWEEPSTAKES - \(person) --> \(randomTeam)") | |
shuffledTeams.shuffle() | |
} | |
print("SWEEPSTAKES - ASSIGNMENTS DONE, LEFTOVER TEAMS: \(shuffledTeams)") | |
} | |
func performAssignment() { | |
assert(!people.isEmpty && !teams.isEmpty && people.count <= teams.count, "Illegal combination of people/teams - both must be non-empty and #people <= #teams") | |
print("SWEEPSTAKES - First round of assignments\n") | |
var shuffledTeams = teams.shuffled() | |
for person in people.shuffled() { | |
guard let randomTeam = shuffledTeams.popLast() else { | |
print("SWEEPSTAKES - No more teams left to assign for \(person)") | |
return | |
} | |
print("SWEEPSTAKES - \(person.name) --> \(randomTeam.name) (#\(randomTeam.rank))") | |
person.add(randomTeam) | |
shuffledTeams.shuffle() | |
} | |
if !shuffledTeams.isEmpty { | |
print("\nSWEEPSTAKES - Initial assignments done, leftover teams: \(shuffledTeams.compactMap { $0.name })") | |
assignLeftOver(shuffledTeams) | |
prettyPrintAssignments() | |
} else { | |
print("\nSWEEPSTAKES - Assignments complete, no leftover teams") | |
} | |
} | |
/// Assign leftover teams to people according to rank (give to those with the worst "best" rank first) | |
private func assignLeftOver(_ teams: [Team]) { | |
print("\nSWEEPSTAKES - Begin clearing assignments") | |
for team in teams.shuffled() { | |
print("SWEEPSTAKES - Assigned \(team.name) (#\(team.rank)) to \(people.sorted(by: { $0.lowestTeamRank ?? Int.max < $1.lowestTeamRank ?? Int.max}).last?.name ?? "N/A")") | |
self.people.sorted(by: { $0.lowestTeamRank ?? Int.max < $1.lowestTeamRank ?? Int.max}).last?.add(team) | |
} | |
} | |
public func prettyPrintAssignments() { | |
print("\nSWEEPSTAKES - Assignments") | |
people.forEach { | |
print("SWEEPSTAKES - \($0.name) --> teams: \($0.sortedTeams.compactMap { $0.name + " (#\($0.rank))" })") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example usage (you can copy and paste the code into a new playground):
Example output: