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) };
}
decks
variable lazily inside the loop?empty
variable I have?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:
alias Card => String;
{{Card*}*} deal({Card*} cards, Integer players)
=> {for (i in 0:players) cards.skipping(i).by(players)};
void run() {
value suits = {"♦", "♣", "♥", "♠"};
value ranks = {for (i in 2..10) i.string}.chain{"J", "Q", "K", "A"};
value deck = {for (suit in suits) for (rank in ranks) rank + suit};
print(deal(deck.taking(10), 2)); // { { 2♦, 4♦, 6♦, 8♦, 10♦ }, { 3♦, 5♦, 7♦, 9♦, J♦ } }
}
The laziness and immutable style comes at the cost of iterating through all of the cards for each hand. I prefer this eager solution:
{Card[]*} deal({Card*} cards, Integer players) {
value hands = [for (i in 0:players) SequenceBuilder<Card>()];
for (card->hand in zipEntries(cards, hands.cycled)) {
hand.append(card);
}
return {for (hand in hands) hand.sequence};
}
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:
abstract class Suit(shared actual String string)
of diamonds | clubs | hearts | spades {}
object diamonds extends Suit("♦") {}
object clubs extends Suit("♣") {}
object hearts extends Suit("♥") {}
object spades extends Suit("♠") {}