Re: [心得] 鉍鎝氫--可拆成元素符號的英文單字

作者: LPH66 (-6.2598534e+18f)   2017-01-05 01:55:02
※ 引述《jurian0101 (Hysterisis)》之銘言:
: 因為元素符號有一或兩個字母,強烈在引誘我利用費氏數列解題
: 'bitch':> b-i-t-c-h, b-it-c-h, b-it-ch, b-i-tc-h,
: b-i-t-ch, bi-t-c-h, bi-tc-h, bi-t-ch
: 拆成這恰好八種,分別檢查是否子字串屬於元素符號即可
: 這八種的邏輯等於「下五階樓梯,一次可走一或兩階」的走法 Fibonacci[5]=8
: --元素名可以從 MMA 的化學資料集取得
: ElementData[#, "Abbreviation"] & /@ ElementData[]
: 再自己加上最新最潮的四個新元素 "Nh", "Mc", "Ts", "Og"。
: 後來我發現這樣簡潔的暴力法對於 WordList["KnownWords"] 永遠也跑不出來
: 原因是這個字集裡含有 acrylonitrile-butadiene-styrene (ABS塑膠的全名)
: 這種長字...qq 真是暴力的單字 (很顯然它以 -ene 結尾,不能拆)
: 而 Fibonacci[29] = 514229 等於要查遍有半百萬個元素的清單,會爆記憶體。
其實這個方向下去只差一步了
既然是費氏數列, 那就能利用「下一個值等於前兩個值的和」這資訊
於是:
checkSpellCount[""] = 1
checkSpellCount[s_] :=
checkSpellCount[s] =
If[StringLength[s] >= 2 && MemberQ[elem, StringTake[s, -2]],
checkSpellCount[StringTake[s, {1, -3}]], 0] +
If[StringLength[s] >= 1 && MemberQ[elem, StringTake[s, -1]],
checkSpellCount[StringTake[s, {1, -2}]], 0]
是的, 這是個有點無恥的 Memoization XD
elem 是已經轉成小寫的元素列表
計算邏輯本身其實看上面程式就很清楚了
由於這是全域筆記, 不僅同一字內可以共享, 有共同 prefix 的字的組法數也能共享
(所以才說有點無恥www)
用你那行 GatherBy 的寫法計時, 在我的電腦上只要 3.5~4 秒就可以完成 KnownWords
之後用 Save 把所存的定義給倒出來看的結果一共有約十七萬四千筆資料
記憶體用量看起來也並不是很大
作者: jurian0101 (Hysterisis)   2017-01-05 09:47:00
總是會忘記有錸這個元素qq哦!懂了。所謂全域記憶就是簡化所有重複做工的方法,教會我從「什麼是程式一做再做的計算」方向考慮優化。3Q太感謝。
作者: LPH66 (-6.2598534e+18f)   2017-01-06 09:35:00
其實這東西的傳統解法是動態規劃 Dynamic Programming只是在 MMA 上寫 DP 稍微麻煩了點, 不如筆記法直覺
作者: ntust661 (TOEFL_5!)   2017-04-22 19:10:00
XD

Links booklink

Contact Us: admin [ a t ] ucptt.com