js 也來 - 【拉勾專場】拋棄簡歷!讓代碼說話!


前些日子謝亮兄弟丟了一個鏈接在群里,我當時看了下,覺得這種裝逼題目沒什么意思,因為每種語言都有不同的實現方法,
你怎么能說你的方法一定比其他語言的好,所以要好的思路 + 好的語言特性運用才能讓代碼升華。

題目如下:《【拉勾專場】拋棄簡歷!讓代碼說話!》

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神思路的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM