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