「10分でコーディング」に挑戦

ゲンゾウ用ポストイット: 10分でコーディング|プログラミングに自信があるやつこい!! だって。とか10分でコーディング - uehaj's blogとかはやってるみたいなのでやってみました。(もちろん自分でやってみるまではコードには目を通しませんでしたよ!)
10分でコーディング|プログラミングに自信があるやつこい!!

あまりに簡単なので制限時間を10分としてやってみてください。
これ以上かかった人は
自分はかなりプログラミングができない。
とつらい事実を認識しましょう。

うひー。これは頑張らないと…
てわけでやってみたら、10分ぎりぎりでなんとか書き上げました。あぶなー…

まずはシンプルなのを。

文字列をカードのデッキに見立てて、指定された人数分配る、というプログラムらしいです。仕様は例で示されているので、例通りのassertを1個ずつ書いていく事にしました。

2つの引数がもらえます。

3
"123123123"

最初の3はプレイヤーの人数を示しています。
"123123123" はトランプの並びを示しています。あなたはこのなかのトランプを配っていかなければなりません。
この場合、あなたのプログラムは

{"111","222","333"}

を返さなければなりません。

ふむふむ。

assert deal(3, "123123123") == ["111","222","333"]:deal(3, "123123123")

もちろんエラーになるので、ひとまずfake it。

String[] deal (int numPlayers, String deck) {
    return  ["111","222","333"]
}

assertが意図通りに動く事を確認したので、実装します。要はnumPlayers分の配り先を作って、先頭から順に配っていけば良いんですね。

String[] deal (int numPlayers, String deck) {
    def res = (0..<numPlayers).collect{[]}
    deck.eachWithIndex{it, i->res[i%numPlayers] << it}
    return res*.join("")
}

通りました。リファクトしたいところですが、時間制限が有るのでどんどん行っちゃいます。

割り切れない場合

すべてのプレイヤーは同じ数だけのトランプを受け取らなければなりません。ですので

4
"123123123"

この場合、あなたのプログラムは

{"12","23","31","12"}

を返さなければなりません。
{"123","23","31","12"} は駄目です。

だそうです。

assert deal(3, "123123123") == ["111","222","333"]:deal(3, "123123123")
assert deal(4, "123123123") == ["12","23","31","12"]:deal(4, "123123123")

もちろん{"123","23","31","12"}になってしまってエラーになります。
配りきれない最後の端切れ部分はのぞかなきゃいけないんですね。なら…

String[] deal (int numPlayers, String deck) {
    def res = (0..<numPlayers).collect{[]}
    deck[0..<(deck.length()-(deck.length()%numPlayers))].eachWithIndex{it, i->res[i%numPlayers] << it}
    return res*.join("")
}

deckの割り切れる部分だけを対象にしてやれば良いんです。これで2つとも通りました。

他のテストも

では、以下にもうすこし例をのせます。

と、いろんな例が載っています。多分もう通ると思うので、一気にassertを足してみました。通らなきゃコメントアウトしつつ実装していけば良いのです。

assert deal(6, "012345012345012345") == ["000", "111", "222", "333", "444", "555"]: deal(6, "012345012345012345")
assert deal(4, "111122223333") == ["123","123","123","123"]:deal(4, "111122223333")
assert deal(1, "012345012345012345") == ["012345012345012345"]:deal(1, "012345012345012345")
assert deal(6, "01234") == ["", "", "", "", "", ""]: deal(6, "01234")
assert deal(2, "") == ["", ""]: deal(2, "")

完璧に通りました。完成です。

指定された仕様?

完成かと思いきや、

クラス名、などは以下のとおりです。

Class:    Cards
Method:    deal
Parameters:  int, String
Returns:   String
Method signature: String
deal(int numPlayers, String deck)

て仕様が最後に指定されてるじゃないですか。関数で書いてしまいました。仕方が無いので、この仕様に合うように直します。
保存ボタンを押して、ファイル名を「Cards.groovy」と指定して保存。
ばっちりです!今度こそ完成です。


で、出来たので他の人のを見てみると…
ゲンゾウ用ポストイット: 10分でコーディング|プログラミングに自信があるやつこい!! だって。:

class Cards{  
    String[] deal(int numPlayers, String deck){  
        def cardCount = (int)(deck.size() / numPlayers)  
          
        def i = 0  
        deck.toList().groupBy{  
            i++%numPlayers  
        }*.value*.join()  
    }  
}  

むむ!groupByとは!そんなんが有ったんですねー…悔しい、かっこいい…
やっぱAPIはきっちり身に付けないとあきませんねー…