I haven't quite verified the correctness and lack of off-by-one bugs, but bear with me for a moment.
The goal here is to deal/split a deck of cards (defined as a {Card*}) into multiple Decks (which optionally take a {Card*} as a constructor argument). I want to split the cards in a round-robin fashion, like cards would actually be dealt. Here's the code I have so far:
{Deck*} split(Integer ways) {
assert(theCards.size % ways == 0);
{Card*} empty = {};
value decks = LinkedList { for (i in 0:ways) empty };
for(i -> card in entries(theCards)) {
value deckIndex = i % ways;
assert (exists current = decks[deckIndex]);
decks.set(deckIndex, {card, *current});
}
return { for(cards in decks) Deck(cards) };
}
- Is this the correct/idiomatic way to split a list into multiple lists?
- If I wanted to not reverse all the cards (that is, append to the list instead of prepend, or reverse the iterable) how might I do that?
- How would I initialize the values of the
decks
variable lazily inside the loop? - Is there any way I can get away from needing the
empty
variable I have? - Any chance I could write this without the need for mutable data structures?
Thanks, and sorry for the multi-question (I'd have created this on codereview.stackexchange.com but I don't have the rep to create a ceylon
tag there).
Not reversed, lazy, no mutable data structures:
The laziness and immutable style comes at the cost of iterating through all of the cards for each hand. I prefer this eager solution:
That way, you're just iterating the deck once.
Note that Ceylon's enumerated types provide a nifty way to represent things like suits and ranks in a type-safe and object-oriented way, analogously to Java's enums: