天天看點

最難面試的IT公司之ThoughtWorks代碼挑戰——FizzBuzzWhizz遊戲(C#解法)

原題

看到那麼多人看到前面這麼糟粕的代碼各種不忍直視後,樓主還是把最終實作放在頁首吧.

            Console.WriteLine("說出三個不同的特殊數,用','隔開 ");

            string[] s1 = Console.ReadLine().Split(',');

            for (int i = 1; i < 101; i++)

            {

                if (i.ToString().Contains(s1[0])) { Console.WriteLine("Fizz"); }

                else { Console.WriteLine((i % int.Parse(s1[0]) == 0 ? "Fizz" : "") + (i % int.Parse(s1[1]) == 0 ? "Buzz" : "") + (i % int.Parse(s1[2]) == 0 ? "Whizz" : "") + ((i % int.Parse(s1[0]) != 0 && i % int.Parse(s1[1]) != 0 && i % int.Parse(s1[2]) != 0) ? i.ToString() : "")); }

            }

            Console.ReadKey();

其實我想表達的意思是學習更多的是循序漸進而不是天才般的靈光乍現,不過不知誰懂呢. 

一開始樓主傻BB直接求解,思路慘不忍睹,各種循環啊有木有?還寫了個計算是否整除擴充方法以為重複複用很了不起啊(其實是傻...)

二逼青年的代碼

 1   #region so1

 2             int[] count = new int[100];

 3             string[] s4 = new string[] { "Fizz", "Buzz", "Whizz" };

 4             for (int i = 0; i < count.Length; i++)

 5             {

 6                 count[i] = i + 1;

 7                 if (count[i].compa(s2[0]))

 8                 {

 9                     result[i] = s4[0];

10                     if (count[i].compa(s2[1]))

11                     { result[i] = s4[0] + s4[1]; }

12                 }

13                 else

14                 {

15                     if (count[i].compa(s2[2]))

16                     {

17                         result[i] = s4[2];

18                         if (count[i].compa(s2[1]))

19                         {

20                             result[i] = s4[1] + s4[2];

21                             if (count[i].compa(s2[0]))

22                             { result[i] = s4[0] + s4[1] + s4[2]; }

23                         }

24                         else

25                         {

26                             if (count[i].compa(s2[0]))

27                             { result[i] = s4[0] + s4[1]; }

28                         }

29                     }

30                     else

31                     { result[i] = (i + 1).ToString(); }

32                 }

33             }

34             for (int i = 0; i < 10; i++)

35             { result[s2[0] + i * 10 - 1] = s4[0]; result[i + s2[0] * 10 - 1] = s4[0]; }

36             foreach (var item in result)

37             { Console.WriteLine(item); }

38             #endregion

後來樓主想了一下,感覺判斷是否整除可以複用,然後一般的值先賦過去,雖然這樣會重複,但是由于集合是越來越小的是以不會出差錯,而在a,b,c集合外的值作為另外一個判斷,賦普通的值給他,這樣代碼就如下了:

普通青年的代碼

 #region so02

            int sh = 1;

            for (int i = 0; i < 10; i++)

            {

                int i2 = 0;

                for (i2 = 0; i2 < 10; i2++)

                {

                    bool b1 = sh.compa(s2[0]);

                    bool b2 = sh.compa(s2[1]);

                    bool b3 = sh.compa(s2[2]);

                    if (b1) { result[i * 10 + i2] = "Fizz"; }

                    if (b2) { result[i * 10 + i2] = "Buzz"; }

                    if (b3) { result[i * 10 + i2] = "Whizz"; }

                    if (b1 && b2) { result[i * 10 + i2] = "FizzBuzz"; }

                    if (b1 && b3) { result[i * 10 + i2] = "FizzWhizz"; }

                    if (b2 && b3) { result[i * 10 + i2] = "BuzzWhizz"; }

                    if (b1 && b2 && b3) { result[i * 10 + i2] = "FizzBuzzWhizz"; }

                    if (i2 == s2[0]) { result[i * 10 + i2] = "Fizz"; }

                    if (!(b1 || b2 || b3))

                    { result[i * 10 + i2] = sh.ToString(); }

                    sh++;

                }

                if (i == s2[0])

                    for (int i3 = 0; i3 < 10; i3++)

                    { result[i * 10 + i3 - 1] = "Fizz"; }

            }

            #endregion

(是否有誤未測試,但大體是這個思路) .

後來樓主再回去看那個頁面,人家說10行代碼就能搞定,樓主看着這普通青年的代碼表示蛋疼,于是請教一下在中大的基友.人家讀數學專業的就是不一樣,給的思路也是天馬行空,于是借鑒一下傳說中的至簡代碼就出來了.

文藝青年的代碼

1             Console.WriteLine("說出三個不同的特殊數,用','隔開 ");

2             string[] s1 = Console.ReadLine().Split(',');

3             int[] s2 = new int[] { int.Parse(s1[0]), int.Parse(s1[1]), int.Parse(s1[2]) };

4             string[] result = new string[100];

5             for (int i = 1; i < 101; i++) { result[i - 1] = (i % s2[0] == 0 ? "Fizz" : "") + (i % s2[1] == 0 ? "Buzz" : "") + (i % s2[2] == 0 ? "Whizz" : "") + ((i % s2[0] != 0 && i % s2[1] != 0 && i % s2[2] != 0) ? i.ToString() : ""); }

6             for (int i3 = 0; i3 < 10; i3++) { result[s2[0] * 10 + i3 - 1] = result[i3 * 10 + s2[0] - 1] = "Fizz"; }

7             foreach (var item in result) { Console.WriteLine(item); }

8             Console.ReadKey();

思路就是規則3和4通過活用三元運算符+字元串同時拼接處理.第一個for循環為規則3和4指派,如果滿足整除條件,輸出對應單詞,這樣能被N(1到3)整除的數字對應的單詞都能賦到,但是有一種情況就是整除條件都不滿足,也就是說是一個普通的數字,而前面根據三元運算符得到的答案都是“”,所已最後的條件滿足的話輸出普通的數字。

然後是規則5。規則5是最重要的,所已在最後才為其指派。這個沒什麼好說的,想一想都知道規則5每種條件都包含10個數,所已在0到10之間循環,同時為個數滿足以及十位數滿足的數指派就行了.代碼控制在10行代碼啊有木有(我不知道10行的定義是什麼這樣稍微有點勉強不過最少也有8行吧,哈哈 )?

當然是假定使用者不搗亂,一開始不輸入錯的情況。加個驗證?那你們就慢慢驗吧。

最難面試的IT公司之ThoughtWorks代碼挑戰——FizzBuzzWhizz遊戲(C#解法)

下部就不截了。