前些日子謝亮兄弟丟了一個鏈接在群里,我當時看了下,覺得這種裝逼題目沒什么意思,因為每種語言都有不同的實現方法,
你怎么能說你的方法一定比其他語言的好,所以要好的思路 + 好的語言特性運用才能讓代碼升華。
題目如下:《【拉勾專場】拋棄簡歷!讓代碼說話!》
FizzBuzzWhizz 你是一名體育老師,在某次課距離下課還有五分鍾時,你決定搞一個游戲。此時有100名學生在上課。游戲的規則是: 1. 你首先說出三個不同的特殊數,要求必須是個位數,比如3、5、7。 2. 讓所有學生拍成一隊,然后按順序報數。 3. 學生報數時,如果所報數字是第一個特殊數(3)的倍數,那么不能說該數字,而要說Fizz;如果所報數字是第二個特殊數(5)的倍數,那么要說Buzz;如果所報數字是第三個特殊數(7)的倍數,那么要說Whizz。 4. 學生報數時,如果所報數字同時是兩個特殊數的倍數情況下,也要特殊處理,比如第一個特殊數和第二個特殊數的倍數,那么不能說該數字,而是要說FizzBuzz, 以此類推。如果同時是三個特殊數的倍數,那么要說FizzBuzzWhizz。 5. 學生報數時,如果所報數字包含了第一個特殊數,那么也不能說該數字,而是要說相應的單詞,比如本例中第一個特殊數是3,那么要報13的同學應該說Fizz。如果數字中包含了第一個特殊數,那么忽略規則3和規則4,比如要報35的同學只報Fizz,不報BuzzWhizz。 現在,我們需要你完成一個程序來模擬這個游戲,它首先接受3個特殊數,然后輸出100名學生應該報數的數或單詞。比如, 輸入 3,5,7 輸出(片段) 1 2 Fizz 4 Buzz Fizz Whizz 8 Fizz Buzz 11 Fizz Fizz Whizz FizzBuzz 16 17 Fizz 19 Buzz … 一直到100
猛地一看,還以為是ACM....里的水題,額,好吧,其實這個考點在思路,而不是結果。
因為誰都能得到這個結果,但是思路就各出奇招吧。
一開始我也沒什么好方法,所以沒去做,今天想到個比較奇葩的方法實現的,給大家參考下。
可能其他語言根本不能這么用,因為js語言特性,所以他在js下能得到比好的結果。算是 js only 的代碼吧。
簡單說下思路吧。
1. 先處理 1 - 100 之間 3,5,7 的倍數的值,給他們累加字符串。
2. 遍歷 1 - 100,如果編號含 3 的,就直接用 Fizz 覆蓋,如果是空的返回編號,否則返回之前累加的字符串。
思路簡單,直接上代碼吧:
var key = [3, 5, 7], // 特殊數字 keyStr = ["Fizz", "Buzz", "Whizz"], // 替換字符 arr = Array(101).join(",").split(","), // 初始化101個空字符串數組 i = 0, // 累加器 n = 1, // 倍數累加器 tmp; // 臨時變量 for (; i<3; i++, n=1) { // 遍歷 key 數組 while (101 > (tmp = key[i]*n++)) { // n倍結果 arr[tmp] += keyStr[i]; // 累加字符串 } } for (i=1; i<101; i++) { arr[i] = (i+"").indexOf(key[0])>-1 ? keyStr[0] : arr[i] === '' ? i : arr[i]; } arr.shift(); // 去除下標0的元素 console.log(arr.join("\n"));
不到 20 行代碼,我也不知道這個 "行" 是怎么定義的,在js里,全部縮成一行也是OK的,對吧。
如果按 ; 分,那整理下:
var key = [3, 5, 7], keyStr = ["Fizz", "Buzz", "Whizz"], arr = Array(101).join(",").split(","), i = 0, n = 1, tmp; for (; i<3; i++, n=1) while (101 > (tmp = key[i]*n++)) arr[tmp] += keyStr[i]; for (i=1; i<101; i++) arr[i] = (i+"").indexOf(key[0])>-1 ? keyStr[0] : arr[i] === '' ? i : arr[i]; arr.shift(); console.log(arr.join("\n"));
嗯,不錯,5行代碼,呵呵。。。
好了,不扯蛋了,只是分享下思路,不要研究10行還是5行實現的問題了,因為語言特性所致,沒辦法明確規定,思路新穎奇葩才能出彩。
剛才在開源中國看到一位大神8行實現,FizzBuzzWhizz,比我思路好多了,我簡單修改了下,去掉了所有 if 語句,代碼展開狀態10行:
function cd(x, y, s) { return x % y === 0 ? s : ''; } function bs(a, b, c) { for (var i = 1; i <= 100; i++) { var d = cd(i, a, 'Fizz') + cd(i, b, 'Buzz') + cd(i, c, "Whizz"); console.log((i + "").indexOf(a) !== -1 ? "Fizz" : d !== '' ? d : i); } } bs(3, 5, 7);
只有想不到,沒有做不到,我會繼續收集js版FizzBuzzWhizz神思路的。