我还没有完全验证正确性和缺少一个错误,但请耐心等待一段时间。
此处的目标是将一副牌(定义为{Card *})交易/拆分为多个牌组(可选择将{Card *}作为构造函数参数)。我想以循环方式分割卡片,就像卡片实际上会被处理一样。这是我到目前为止的代码:
{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
变量的值?empty
变量吗?谢谢,抱歉这个多问题(我已经在codereview.stackexchange.com上创建了这个,但我没有代表在那里创建ceylon
标签)。
答案 0 :(得分:4)
没有逆转,懒惰,没有可变数据结构:
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♦ } }
}
懒惰和不可变的风格是以每只手的所有牌重复为代价的。我更喜欢这个急切的解决方案:
{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};
}
这样,你只需要迭代一次。
请注意,Ceylon的枚举类型提供了一种很好的方式来表示类型安全和面向对象方式的套装和排名,类似于Java的枚举:
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("♠") {}
答案 1 :(得分:1)
如下:
alias Deck => {Card*};
{Deck*} split(Deck cards, Integer ways) {
assert(ways.divides(cards.size));
return { for i in (0:ways) { for (j->card in entries(cards)) if (j%ways==i) card } };
}
如果Deck
实际上是一个类,从您的描述中不是很清楚,那么:
class Deck(shared {Card*} cards) { ... }
{Deck*} split(Deck deck, Integer ways) {
assert(ways.divides(deck.cards.size));
return { for i in (0:ways) Deck { for (j->card in entries(deck.cards)) if (j%ways==i) card } };
}
注意:我没有测试过这个。