Created
December 9, 2013 05:46
-
-
Save sethladd/7867811 to your computer and use it in GitHub Desktop.
My humble entry for Dart Dare - Secret Santa. I'm sure there are smaller or faster ways to do this. However, I wanted to try to solve the problem with sorting and processing lists. The entire solution hinges on sorting the santas by last name and by family size. Features of Dart that I used: * Classes
* String interpolation
* Type annotations
* …
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
class Person { | |
String firstName, lastName; | |
Person(List<String> raw) : firstName = raw[0], lastName = raw[1]; | |
String toString() => '$firstName $lastName'; | |
} | |
/** | |
* Expects one person per line, each line containing a first and last name | |
* separated by a single space. | |
*/ | |
List<Person> parsePeople(String santas) { | |
return santas | |
.split('\n') | |
.map((e) => e.trim().split(' ')) | |
.map((e) => new Person(e)) | |
.toList(); | |
} | |
/** | |
* Try the old "generate a big sorted list" approach. Sort all people | |
* by last name, and then sort again by biggest family down to smallest | |
* family. The actual pairing assumes this structure. | |
*/ | |
List<Person> prepForGiftification(String santas) { | |
return ((parsePeople(santas) | |
// Group by last name. | |
..sort((p1, p2) => p1.lastName.compareTo(p2.lastName))) | |
// Create a list of lists, grouped by last name. Assumes the list is sorted. | |
.fold([[]], (List<List> list, person) { | |
var current = list.last; | |
if (current.isEmpty || current.last.lastName == person.lastName) { | |
current.add(person); | |
} else { | |
list.add([person]); | |
} | |
return list; | |
}) as List | |
// Order by biggest family first. | |
..sort((l1, l2) => l2.length.compareTo(l1.length))) | |
// Flatten the list of lists. | |
.expand((i) => i).toList(); | |
} | |
/** | |
* Assumes a sorted list of people, sorted by biggest family to smallest | |
* family. | |
* | |
* TODO: any error handling at all. | |
*/ | |
Map<Person, Person> pairUp(List<Person> santas) { | |
var pairs = {}; | |
var currentPairing = santas.indexOf(santas.firstWhere((p) => p.lastName != santas[0].lastName)); | |
for (var santa in santas) { | |
pairs[santa] = santas[currentPairing++]; | |
if (currentPairing == santas.length) currentPairing = 0; | |
} | |
return pairs; | |
} | |
main() { | |
var input = ''' | |
Zoe Washburne | |
Hoban Washburne | |
Malcolm Reynolds | |
Simon Tam | |
River Tam | |
Buffy Summers | |
Dawn Summers'''; | |
var people = prepForGiftification(input); | |
var pairs = pairUp(people); | |
print(pairs); | |
} |
@sethladd why did you use the : syntax in the Person constructor on line 3, rather than parsing the raw string into first name last name in the constructor body?
@MarkBennett i think it is preparation for optional firstname/lastname lockdown by final keyword. All final fields must be initialized before constructor body begins to run.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See original Dart Dare description and other solutions: https://plus.google.com/+SethLadd/posts/XjgFRvqtVA4