[どうでもよいこと]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分でコーディング
はじめまして。
いつもなるほどと、読ませていただいています。
本題と関係ないですが、初期化部分を以下のようにやるのは、どうなんでしょうか?
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];
トラックバック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
{
public str...
2009.06.24 02:52 | neue cc