日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python算24点穷举法_关于24点去重的算法?

發布時間:2024/7/23 python 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python算24点穷举法_关于24点去重的算法? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

=== 4月12日更新 ===

=== 先給結論吧 ===

花了近一周時間用JavaScript完成了24點去重算法,源碼提交到了github上:auntyellow/24 ,可以在線試:gives you all dissimilar solutions.

在1到13范圍內的四數組合中,不重復解最多的組合是2、4、8、10:

10 + 8 + 4 + 2 = 24

(10 - 4) × 8 ÷ 2 = 24

(10 × 4 + 8) ÷ 2 = 24

((10 + 2) × 8 ÷ 4 = 24

10 × 2 + 8 - 4 = 24

(10 - 2) × 4 - 8 = 24

8 × 4 - 10 + 2 = 24

(8 ÷ 4 + 10) × 2 = 24

(8 × 2 - 10) × 4 = 24

(10 - 8 ÷ 2)) × 4 = 24

10 × 4 - 8 × 2 = 24

只能用分數來解的(16個,這里不給答案了,有興趣可以自己練練):

1, 3, 4, 6

1, 4, 5, 6 (這題居然有兩解,都必須用分數的)

1, 5, 5, 5

1, 6, 6, 8

1, 8, 12, 12

2, 2, 11, 11

2, 2, 13, 13

2, 3, 5, 12

2, 4, 10, 10

2, 5, 5, 10

2, 7, 7, 10

3, 3, 7, 7

3, 3, 8, 8

4, 4, 7, 7

5, 5, 7, 11

5, 7, 7, 11

其他有難度的,就是中間過程必須有大數的(大于36就很難一下子想到了)(像a × b - a × c = 24這種形式,比如10、12、12、12,其實并沒有太大難度,就沒有列進去):

1, 7, 13, 13

6, 12, 12, 13

1, 6, 11, 13

6, 11, 12, 12

5, 10, 10, 13

1, 5, 11, 11

5, 10, 10, 11

4, 8, 8, 13

4, 4, 10, 10

4, 8, 8, 11

6, 9, 9, 10

3, 8, 8, 10

3, 5, 7, 13

3, 6, 6, 11

1, 2, 7, 7

5, 8, 9, 13

5, 9, 10, 11

4, 7, 11, 13

4, 9, 11, 11

4, 10, 10, 11

6, 7, 7, 11

3, 5, 8, 13

5, 5, 8, 11

2, 3, 13, 13

還找到一個難的:3、7、9、13,它有兩種解法,一種用到了分數,一種有大數。

為了驗證這些結論,還是查到了 @常成 那邊,包括 理論 - 24理論 解決二十四點 (我的算法跟這里相當接近了)、所有獨立解 - 24理論 解決二十四點 (解法最多的牌型確實有11個解),需要分數的解 - 24理論 解決二十四點 (確實有16個牌型),看來程序是沒太大問題了。

=== 然后說說算法 ===

參考了本題 小于0 的回答,還有 24點算法,如何給出所有不同的答案 - 蘿卜的回答 - SegmentFault ,總之就是列出所有不等價表達式,例如 (( a + b ) * c) / d 和 (( b + a) * c ) / d 是等價的,需要去重。

雖然是重復在做很多人以前做過的工作,但還是有些自認為別出心裁的思路,因為并沒從代數形式上做分析,而是通過試數的辦法做的,試的是π、e、lnπ和arctan e這四個超越數,對近似值做比較(浮點數運算總是有誤差的)來判斷兩個表達式是否等價。(我把近似度設定在1e-6其實算是碰巧蒙對了,SegmentFault的蘿卜指出lnπ/(e + π/arctan(e))和π/e - lnπ/arctan(e)只相差7.9e-6,如果把近似度再提高1個數量級,結果可能就不對了。)

5種括號型(((oxo)xo)xo、(ox(oxo))xo、(oxo)x(oxo)、ox((oxo)xo)、ox(ox(oxo)),其中o代表數字,x代表運算符),4個數一共有24種排列,3個符號一共有64種排列,總共需要“試數”的表達式總共有7680個,在這些表達式中找出了1170種不等價的,也和網上能找到的資料相吻合,例如 小于0 給我推薦的 A140606 - OEIS 。

后來發現,僅僅用這1170個表達式是不夠的,還要考慮以下14種牌型:

a, a, b, c // 兩個相同的數可以交換,也可以抵消

a, a, b, b

a, a, a, b

a, a, a, a

1, a, b, c // 1可以舍去

1, a, a, b

1, a, a, a

1, 1, a, b

1, 1, a, a

1, 1, 1, a

2, 2, a, b // 2 + 2 = 2 × 2,這個算重復解應該說得過去

2, 2, a, a

1, 2, 2, a

2, a, a, b // 2 × a - a = (a + a) ÷ 2,這個居然被我算成重復解了!

另外還有,a、a'(=a+1)、b、c這種牌型,需要把(a'-a)參與乘除運算的解法排除掉,然后單獨算b+c、b*c有沒有可能等于24。

所以程序里絕大部分邏輯都是在判斷:牌型到底屬于上面列出來的15種當中的哪一種,寫得相當啰嗦。

另外還有一些小問題,比如:1、1、5、5,只給出了一種解,因為對牌型1、1、a、a組成的表達式來說, (a+1)(a-1)和a*a-1*1是等價的;

沒有考慮4/2和4-2等價的問題,例如2、4、6、6,(6-(4-2))*6和(6-4/2)*6被認為是兩個不等價的解(憑什么2+2和2*2等價,但4-2和4/2不等價?)

當2作為中間步驟時,沒考慮2+2和2*2的等價,還拿2、4、6、6說事,(6-4+2)*6和(6-4)*2*6是不等價的解(寫到這里我真后悔把2+2和2*2算做等價了)

仔細想想,還真不能輕易認為2+2=2*2、4-2=4/2是等價解法,要是真這么算的話,那么我們可以寫出:

(6-4/2)*6 = (6-(4-2))*6 = (6-4+2)*6 = (6-4)*2*6

顯然每個等號左右兩邊都是等價的。但要說最左邊的和最右邊的是重復的解法,那又說不過去了。

看似很簡單的問題,本以為可以花半天時間搞定的,結果編碼、測試、驗證、優化一系列過程居然花了1周的時間,再次印證了我的盲目樂觀 :-(

=== 更早的回答 ===

我在SegmentFault上提了一個相似的問題,問完才發現知乎上已經有了。很快就有人給出漂亮的解答了:24點算法,如何給出所有不同的答案 - 蘿卜的回答 - SegmentFault ,起初答題者思路跟 小于0 的回答類似,后來發現窮舉太麻煩,就改用符號代數,在Mathimatica里用10余行代碼搞定了,真讓我吃驚。

另外,對于重復解的定義,還是有挺大爭論的,比如我認為2x2和2+2應該算是雷同的,但很多人并不認同。

轉載一下:

Clear[game24]game24[input_List,result_:24]:=Block[{add,sub,mul,div},With[{oprules={add->Plus,sub->Subtract,mul->Times,div->Divide},specifics={div[x_,1]:>x,mul[x_,1]:>x,mul[1,x_]:>x,add[2,2]->mul[2,2]}},Map[RightComposition[Hold,ReplaceAll[oprules],ToString[#,InputForm]&,StringDelete[{"Hold[","]"}],StringReplace[{"*"->"\[Times]","/"->"\[Divide]"}]],Union[Select[result==(#/.oprules)&]@Groupings[Permutations@input,{add,sub,mul,div}->2],SameTest->(0===Simplify[sub[#1,#2]//.specifics/.Prepend[oprules,k_Integer:>ToString[k]]]&)]]]]用符號add、sub、mul、div分別對應加減乘除四則運算,構建二叉樹代表算式。Groupings函數生成了所有可能的表達式二叉樹。

Select篩選出計算結果符合要求的。

Union負責除去雷同的算式。它的SameTest選項計算兩個代數式的差化簡后是否為0。注意這里通過把數字轉為字符進行“符號化”了,而且對數字1、2進行了特殊處理(specifics)。

最后Map負責把每個算式轉成字符串輸出。

測試:

總結

以上是生活随笔為你收集整理的python算24点穷举法_关于24点去重的算法?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。