2014-03-19 61 views
3

以下是StackOverflowers的算術益智遊戲。我正在開發一款JS遊戲,它將允許某人輸入他們的名字,並根據他們輸入的內容生成另一個名字。有點像this。基本上每次有人輸入一個特定的字符串時,我想通過從列表中獲取項目來生成相同的其他字符串。將字母字符串轉換爲數字並遞歸求和,以使它們低於某個最大值

所以,我有字的陣列,在該示例

"nouns": [ 
    "Nitwit", 
    "Cretin", 
    "Village Idiot" 
    // .. 
] 

編號20當用戶輸入他們的名字,我每個ASCII字母字符轉換爲一個數字。我將把所有得到的數字加起來,並用總數從我的數組中選擇一個單詞。

// Convert alpha chars to numerical equivalents 
function str2num (mystr) { 

    mystr = mystr.toUpperCase(); 
    var conv = [], 
     l = mystr.length, 
     regex = /^[A-Za-z]+$/; 

    for (var i = 0; i < l; i++) { 
     if (regex.test(mystr.charAt(i))) { 
      conv.push(mystr.charCodeAt(i) - 64); 
     } 
    } 

    var c = conv.length, 
     sum = 0; 
    for (var j = 0; j < c; j++) { 
     sum += conv[j]; 
    } 
    return sumDigits(sum); 

} 

由於只有20字數組中的元素,我總是想總和小於20所以,如果它等於或大於20,我想再次加起來的數字。這就是我目前的做法。

// Recursively add digits of number together 
// till the total is less than length of word list 
function sumDigits (number) { 

    var listLength = adjectives.length; 
    var sum = number % listLength; 

    if (number > listLength) { 
     var remainder = Math.floor(number/10); 
     sum += sumDigits(remainder); 
    } 

    if (sum > listLength) { 
     sum = sumDigits(sum); 
    } 

    return sum; 
} 

當我有低於20的結果,我的nouns[sum]值返回給用戶。這段代碼非常有用 - 總和總是低於允許的最大值。但結果並不是很隨意 - 看起來我在0到20範圍的低端得到了不成比例的總和。我不希望用戶從列表的開始處看到單詞。我可以對sumDigits進行任何更改,以確保結果的均勻分佈?或者這已經是正確的了? (我done this JSFiddle演示我在說什麼。)

+0

對於每個名稱使用[bag-of-words模型](http://en.wikipedia.org/wiki/Bag-of-words_model),使用一包字母而不是單詞來說明情況。把他們的名字變成一個26個字母的向量,看看他們的名字最接近哪個名字。 –

回答

2

我將使它依賴於名稱的字符中charCode:

function getValue(name) { 
    var letters = name.toLowerCase().split(''), 
     value = 0, 
     i = 0; 
    for(; i < letters.length; i ++) { 
     value += letters[i].charCodeAt(0); 
    } 
    return value % 20; 
} 
+0

因爲數組從0到19爲什麼+1? – jing3142

+0

@ jing3142你是對的。 – fzzle

+1

謝謝你,很好的解決方案!我已經在使用charCodeAt轉換字母了。只使用模數而不是sumDigits(sum)似乎會產生更好的結果分佈。 –

0

我覺得sumDigits函數返回一個偏見數。不要返回sumDigits(sum)。相反,您可以返回sum % 20

0

fzzle的答案是一個很好的答案。

或者,你可以做一個總和降低了,同時:

var reduced = sum; 
while(reduced > 20){ 
    reduced -= name.length; 
} 

這是一個更完整的例子:

var sum = 0; 
var name = 'John Smith'.split(''); 

for(var k in name){ 
    sum += name[k].charCodeAt(0); 
} 

var key = sum; 
while(key > 20){ 
    key -= 'John Smith'.length; 
} 

如果你測試一下你會看到它產生了不同的結果到sumDigits % 20。請注意,我不知道這種方法如何以非常長的名字行事。讓我測試它。

確認。 XD 我嘗試了John Smith John Smith John Smith John Smithxx並將其破解。現在不要認爲這是合格的答案。 :(

+1

如果名稱長於20個字符,該怎麼辦? – fzzle

1

您當前執行的輸出總和確實是而不是均勻分佈。

作爲一個例子,考慮所有的號碼與一個或兩個數字(1 - 99):

1 of them is summed up to 1 (1) 
2 of them are summed up to 2 (2, 20) 
3 of them are summed up to 3 (3, 30, 21) 
4 of them are summed up to 4 (4, 40, 31, 22) 
5 of them are summed up to 5 (5, 50, 41, 32, 23) 
6 of them are summed up to 6 (6, 60, 51, 42, 33, 24) 
7 of them are summed up to 7 (7, 70, 61, 52, 43, 34, 25) 
8 of them are summed up to 8 (8, 80, 71, 62, 53, 44, 35, 26) 
9 of them are summed up to 9 (9, 90, 81, 72, 63, 54, 45, 36, 27) 
9 of them are summed up to 10 (10, 91, 82, 73, 64, 55, 46, 37, 28) 
9 of them are summed up to 11 (11, 92, 83, 74, 65, 56, 47, 38, 29) 
8 of them are summed up to 12 (12, 93, 84, 75, 66, 57, 48, 39) 
7 of them are summed up to 13 (13, 94, 85, 76, 67, 58, 49) 
6 of them are summed up to 14 (14, 95, 86, 77, 68, 59) 
5 of them are summed up to 15 (15, 96, 87, 78, 69) 
4 of them are summed up to 16 (16, 97, 88, 79) 
3 of them are summed up to 17 (17, 98, 89) 
2 of them are summed up to 18 (18, 99) 
1 of them is summed up to 19 (19) 

這可能是比均勻分佈接近正態分佈

爲了實現後者,只需返回sum % c而不是sumDigits(sum)

+0

非常感謝barak,第一次接觸模數的答案,但是你的數字金字塔非常漂亮,我已經給你一個贊! –

+0

謝謝,不客氣:) –

相關問題