「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure
「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム
「進捗・どう・です・か」をHaskellで書いてみた
golang の進捗どうですか
おもしろそうだったのでC#で挑戦してみました。
うまい人が書くと、もっとシンプルになるんでしょうけど、まぁ。
(思いつくままに書いたコメントとかテスト用コードとかそのままです)
Program.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Word = System.Int32;
namespace ShinchokuDoudesuka
{
class Program
{
static readonly string[] SDDK_WORDS = new string[] { "進捗", "どう", "です", "か" };
static void Main()
{
#if DEBUG
Console.WriteLine("デバッグモードです");
// テストデータ文字列(最後は必ず0123で終わること)
string tstDatStr = "0002030100130120012101221230123";
// テストデータを変換(文字列→数値配列)
int x = 0;
int[] tstDat = tstDatStr.Select(s => int.Parse(s.ToString())).ToArray<int>();
Console.WriteLine("テストデータ確認");
foreach (int ts in tstDat)
{
Console.Write(ts);
}
Console.WriteLine("");
#endif
Random rnd = new Random();
bool aoriFlg = false; // 煽るか? t⇒煽る f⇒煽らない
int tryCnt = 0; // 試行回数
bool asyStcFlg = false; // 文を組み立て中か? t⇒組み立て進行中 f⇒組み立ててない
Word befW = 0; // 1つ前の単語(比較用)
#region 文が完成する(煽る)までの間、文を生成し続ける
while (!aoriFlg)
{
//「進捗・どう・です・か」をランダムに取得し、表示する
Word w = rnd.Next(SDDK_WORDS.Length);
#if DEBUG
//乱数の代わりにテストデータを順に渡す
w = tstDat[x++];
Debug.Write(w);
#endif
Console.Write(SDDK_WORDS[w]);
#region 文が完成したか判定する
if (asyStcFlg)
{
#region 文を組み立て中の場合
if (w == (befW + 1)) // w == ++befWでも良いかも?
{
#region 単語が連続している場合
if (w == SDDK_WORDS.Length - 1)
{
// 文が完成した場合、煽る
tryCnt++;
aoriFlg = true;
}
else
{
// 組み立てが進行
befW = w; // w == ++befWだったら、ここ削れる?
}
#endregion 単語が連続している場合
}
else
{
// 組み立てが失敗
asyStcFlg = false;
tryCnt++;
}
#endregion 文を組み立て中の場合
}
else
{
#region 文を組み立ててない場合
if (w == 0)
{
// 組み立て開始
asyStcFlg = true;
befW = w;
}
else
{
// 失敗
tryCnt++;
}
#endregion 文を組み立ててない場合
}
#endregion 文が完成したか判定する
}
#endregion 文が完成する(煽る)までの間、文を生成し続ける
Console.WriteLine("");
Console.WriteLine("_人人人人人人人_");
Console.WriteLine(">進捗どうですか<");
Console.WriteLine(" ̄Y^Y^Y^Y^Y^Y^Y ̄");
Console.WriteLine(string.Format("{0}回で煽られました", tryCnt));
}
}
}
2015/07/22 追記
「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム(C#/LINQ)
に感銘を受け、書き直してみた。
しかし……あんまり進歩してない。
とりあえず、クラスに詰め込んでみた。
クラス設計、未だによく分からない。
ネストは減らせた。
ifまわりまだ整理できそうだけど、前より改善されたから良しとする。
Program.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
//using Word = System.Int32;
namespace ShinchokuDoudesuka
{
class Program
{
public class Shinchoku
{
#region 定数&変数
readonly string[] SDDK_WORDS = { "進捗", "どう", "です", "か" }; // 正解を文字列配列で定義
readonly string SDDK_RLT_STR; // 正解を文字列で定義
List<string> words; // LINQ用リスト(HashSetの方が速かった気がするけど、使い慣れたListで)。
Random rnd; // 擬似乱数用変数
int tryCnt; // 試行回数
/// <summary>
/// コンストラクタ
/// </summary>
public Shinchoku()
{
SDDK_RLT_STR = string.Join("", SDDK_WORDS);
words = new List<string>();
rnd = new Random();
tryCnt = 0;
}
#endregion 定数&変数
/// <summary>
/// 完成したら煽る関数
/// </summary>
public void Aoru()
{
// 完成するまで表示を続ける
while (!TryMakeWords())
{
//必要なら復活しても良い
//Thread.Sleep(1);
}
Console.WriteLine("");
Console.WriteLine("_人人人人人人人_");
Console.WriteLine(">進捗どうですか<");
Console.WriteLine(" ̄Y^Y^Y^Y^Y^Y^Y ̄");
Console.WriteLine(string.Format("{0}回で煽られました", tryCnt));
}
/// <summary>
/// 「進捗・どう・です・か」を1回だけ組み立ててみる
/// </summary>
/// <returns>完成したか? true⇒完成、false⇒未完成</returns>
private bool TryMakeWords()
{
bool ret = false;
// 1つの単語を追加する
words.Add(SDDK_WORDS[rnd.Next(SDDK_WORDS.Length)]);
// ここまでに作ったものmakingWordsと正解checkStrとを比べる
string makingWords = string.Join("", words);
string checkStr = string.Join("", SDDK_WORDS.Where((e, i) => i < words.Count));
if (makingWords == checkStr)
{
// 正解と完全一致したら完成
if (makingWords == SDDK_RLT_STR)
{
Console.Write(makingWords);
tryCnt++;
ret = true;
}
}
else
{
// 不一致
Console.Write(makingWords);
tryCnt++;
words.Clear();
}
return ret;
}
}
static void Main()
{
Shinchoku s = new Shinchoku();
s.Aoru();
}
}
}