C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2009/06/09 22:37

[どうでもよいこと]10分コーディング | Ryuzee.com
10分でコーディング|プログラミングに自信があるやつこい!!


問題読むのに2分ちょい、問題解くのに5分ちょいでした。

⊂(^ω^)⊃ セフセフ!!

class Cards
{
    public string[] Deal(int numPlayers, string deck)
    {
        int count = deck.Length - deck.Length % numPlayers;
        string[] result = new string[numPlayers];

        for (int i = 0; i < numPlayers; i++)
        {
            result[i] = string.Empty;
        }

        int playerIndex = 0;
        for (int i = 0; i < count; i++)
        {
            result[playerIndex] += deck[i];
            playerIndex++;
            if (numPlayers == playerIndex)
            {
                playerIndex = 0;
            }
        }
        return result;
    }
}



終了後に、リファクタリングもしてみました。
yield return による、順序のオブジェクト化が面白いかもです。

class Cards
{
    public string[] Deal(int numPlayers, string deck)
    {
        string trimmedDeck = this.TrimDeck(deck, numPlayers);
        string[] hands = this.CreateInitialHands(numPlayers);

        IEnumerator<int> order = this.CreateDealOrder(numPlayers);
        foreach (char card in trimmedDeck)
        {
            order.MoveNext();
            hands[order.Current] += card;
        }
        return hands;
    }

    private string TrimDeck(string deck, int numPlayers)
    {
        int needlessCount = deck.Length % numPlayers;
        int needCount = deck.Length - needlessCount;
        return deck.Substring(0, needCount);
    }

    private string[] CreateInitialHands(int numPlayers)
    {
        string[] hands = new string[numPlayers];
        for (int i = 0; i < numPlayers; i++)
        {
            hands[i] = string.Empty;
        }
        return hands;
    }

    private IEnumerator<int> CreateDealOrder(int numPlayers)
    {
        const int startIndex = 0;
        int currentIndex = startIndex;
        while (true)
        {
            yield return currentIndex;

            int incrementedIndex = currentIndex + 1;
            currentIndex = (incrementedIndex < numPlayers) ? incrementedIndex : startIndex;
        }
    }
}

続き → C#と諸々 Refactoring:10分でコーディング
タグ: .NET C#


はじめまして。
いつもなるほどと、読ませていただいています。

本題と関係ないですが、初期化部分を以下のようにやるのは、どうなんでしょうか?

string[] res = new string[numPlayers].Select(s => s = string.Empty).ToArray();

2009.06.11 09:07 URL | insect #- [ 編集 ]


insect さん、はじめまして

> string[] res = new string[numPlayers].Select(s => s = string.Empty).ToArray();

なるほど、LINQ を使って単純化するということですね。
Select メソッドを使う場合、引数 s を何らかの形で利用して戻り値を作るのが本来の使い方なので、
やや直接的ではないかな、というのが個人的な感想です。
というのも、new string[numPlayers] は要素数を示す以外にあまり意味を持っておらず、
例えば次のように int の配列からスタートしても平気だからです。

string[] res = new int[numPlayers].Select(s => string.Empty).ToArray();

ただ、LINQ を使っての単純化はできることなら取り込みたい所ですね。
ということで、探してみたところ System.Linq.Enumerable の Repeat メソッドがありました。

string[] res = Enumerable.Repeat(string.Empty, numPlayers).ToArray();

これなら意図を的確に表現しつつ単純化が可能ですねー。

2009.06.11 10:05 URL | よこけん #Ay6tTHf6 [ 編集 ]


>Enumerable.Repeat

確かに、こちらの方が断然直感的で、美しいすね。
思い切ってよこけんさんに質問して良かったです。

勉強になりました。
ありがとうございました!!

2009.06.11 10:38 URL | insect #- [ 編集 ]


こちらこそ、おかげで Enumerable.Repeat に辿り着くことができました。
ありがとうございます。

2009.06.11 12:23 URL | よこけん #Ay6tTHf6 [ 編集 ]


private static string[] deal2(int numPlayers, string deck)
{

var result = Enumerable.Repeat(string.Empty, numPlayers).ToArray();
int count = (deck.ToCharArray().Length - (deck.ToCharArray().Length % numPlayers));

for(var key = 0; key < numPlayers; key++)
for (var index = key; index < count; index += numPlayers)
result[key] = result[key] + deck.ToCharArray().ElementAt(index);

return result;
}

2009.06.12 18:36 URL | これはどうでしょう #- [ 編集 ]


お、かなりコンパクトですね
そしましたら、for 文をこうすると更にコンパクトになりますね~

for (int i = 0; i < count; i++)
 result[i % numPlayers] += deck[i];

2009.06.12 22:15 URL | よこけん #Ay6tTHf6 [ 編集 ]












トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/267-eef0b6fb

[SQL]10 分間コーディングで 30 分かかった・・・
「10分でコーディング」で15分かかった件 - T/O C#と諸々 10分でコーディング 10分でコーディング|プログラミングに自信があるやつこい!! 流行に乗り遅れた感はあるけど、SQL でやってみた。 WITH Input(id, numPlayers, deck) AS ( SELECT 1, 3, ’123123123’ UNION

2009.06.13 13:47 | 予定は未定Blog版

IEnumerableに文字列連結
C#と諸々 10分でコーディングから。ネタ元、のネタ元の問題文の解読しづらさは異常。例も酷かった。というのはともかく、Linqならグルーピングのお話だよねー class Cards &#123; public str...

2009.06.24 02:52 | neue cc