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

看板Mathematica作者 (かつて交わした約束)時間7年前 (2017/01/05 01:55), 7年前編輯推噓3(304)
留言7則, 3人參與, 最新討論串2/2 (看更多)
※ 引述《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 把所存的定義給倒出來看的結果一共有約十七萬四千筆資料 記憶體用量看起來也並不是很大 -- 然後根據這份 Save 的存檔, ABS 塑膠那個單字是在碰到 -st- 時死掉的 它的結尾是 -rene = Re 錸 + Ne 氖 -- 有人喜歡邊玩遊戲上逼; 也有人喜歡邊聽歌打字。 但是,我有個請求, 選字的時候請專心好嗎? -- 改編自「古 火田 任三郎」之開場白 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 180.177.29.238 ※ 文章網址: https://www.ptt.cc/bbs/Mathematica/M.1483552505.A.BCC.html ※ 編輯: LPH66 (180.177.29.238), 01/05/2017 03:40:02

01/05 09:47, , 1F
總是會忘記有錸這個元素qq
01/05 09:47, 1F

01/05 09:50, , 2F
哦!懂了。所謂全域記憶就是簡化所有重複做工的方法,
01/05 09:50, 2F

01/05 09:51, , 3F
教會我從「什麼是程式一做再做的計算」方向考慮優化。
01/05 09:51, 3F

01/05 09:52, , 4F
3Q太感謝。
01/05 09:52, 4F

01/06 09:35, , 5F
其實這東西的傳統解法是動態規劃 Dynamic Programming
01/06 09:35, 5F

01/06 09:35, , 6F
只是在 MMA 上寫 DP 稍微麻煩了點, 不如筆記法直覺
01/06 09:35, 6F

04/22 19:10, , 7F
XD
04/22 19:10, 7F
文章代碼(AID): #1ORJRvlC (Mathematica)
文章代碼(AID): #1ORJRvlC (Mathematica)