python邏輯題(以下10道選擇題有唯一答案,請編寫自定義函數judge遍歷答案列表並彙報正確答案)
1.題目、代碼及答案演示
-
代碼: 邏輯題
-
說明
:個人沒用過Jupyter Notebook
,題目也只是爲了統計執行時間,就找了一個計時裝飾器將遍歷並判斷邏輯的函數裝飾了下,就可以看出運行的粗略時間了(一秒多一點)。 -
題目要求:以下10道選擇題有唯一答案,請編寫自定義函數judge遍歷答案列表並彙報正確答案。可使用內置或第三方數據類型,但judge函數的參數只能有1個。使用Jupyter Notebook的%%time魔術方法統計執行時間,控制在3秒內。
-
答案演示:
2.思路及要點說明
怎麼說呢,這題的實現確實不難,甚至枯燥。
但是卻讓我思考了下人類大腦與藉助計算機完成大量重複判斷的思維的根本性差異!
爲什麼這麼說呢?
首先,拿到這題,還沒看題幹,就會先像解決十幾年學習生活中的文化課的選擇題一樣,一道一道地做了起來。
當一題沒有思路後,會先放着,坐下一題。
最多看到後面第二三題慢慢發現,這十道題之間不少會有關聯性。
而當經過長達一個多小時的人腦判斷十道題目的答案後(並得到了正確答案),開始考慮實現的時候,十分想
打自己的臉
!!
站在計算機的角度
,我送入判斷函數的那個參數必然是答案,也就是先用嵌套十層的for
循環生成的結果列表。
我先將4^10
個答案列表做出來,再將這些列表放到每一題中去過濾,發現一個答案列表不符合某題答案的過濾一下。
每一個包含判斷的小題是一個不同形狀的過濾網
,層層過濾即可。
真実(しんじつ)はいつもひとつ!
我們就得到了唯一的真相~ B C A C A C D A B A
代碼在我倉庫,希望使用的人能夠遵循開源協議,維護開源社區
最重要的是,能給博客和倉庫一個小星星~MUA
下面舉一些例子說明,如果還有問題請留評論區。
- 從第三題入手
原因是因爲,一下就可以過濾掉極大一部分三題不相同
的答案列表,減輕後面的判斷數量;
以下爲判斷:
def judge_3(res):
'''第三題 判斷3624題有三個相同一個不同
第三題選A 3 624
第三題選B 6 324
第三題選C 2 364
第三題選D 4 362
'''
if res[2] == 1:
if res[5] == res[1] == res[3] and res[2] != res[5]:
judge_6(res)
elif res[2] == 2:
if res[2] == res[1] == res[3] and res[5] != res[2]:
judge_6(res)
elif res[2] == 3:
if res[2] == res[5] == res[3] and res[1] != res[2]:
judge_6(res)
elif res[2] == 4:
if res[2] == res[5] == res[1] and res[3] != res[2]:
judge_6(res)
外層的if判斷每一題都有,判斷當此題分別選ABCD的時候,相關聯題目的邏輯;
在最開始,我們將ABCD映射爲1234,通過判斷過濾後最後的答案再映射回來即可;
當第三題選A,即res[2] == 1
時,這裏res
就是生成的所有可能的答案數組;
通過分析,可以將語義轉化爲邏輯判斷代碼的有3 2 5 8 6 4 9 10題,那麼17倆題起不到作用,沒有使用到;
每一題的註釋都有簡單寫判斷的邏輯,這裏就不做贅述
;
3.優化
3.1.生成答案列表的優化
生成答案列表原本用十層for循環:
for i1 in range(1, 5):
for i2 in range(1, 5):
for i3 in range(1, 5):
for i4 in range(1, 5):
for i5 in range(1, 5):
for i6 in range(1, 5):
for i7 in range(1, 5):
for i8 in range(1, 5):
for i9 in range(1, 5):
for i10 in range(1, 5):
pass
# result_list = [i1, i2, i3, i4, i5, i6, i7, i8, i9, i10]
現在更換成了itertools.product(可迭代對象, repeat=重複次數)
來生成笛卡爾積對象
# 生成映射ABCD的1234的 十次笛卡爾積列表
for item in itertools.product(range(1, 5), repeat=10):
pass
可以看到十層for循環時間在0.1S,而itertools.product(可迭代對象, repeat=重複次數)
時間在0.05s,得到了一倍的提升!
並且優化後每一個迭代對象不需要用list()方法轉換爲列表(直接用item送入判斷函數即可),又省去了0.1S之多!
3.2.各小題判斷順序的更改
將關聯選項更多的判斷子函數優先放置,效果很小;
調整了幾個答題順序,發現效果不明顯,因此這不是耗時的最主要原因
3.3.減少函數調用
接下來調整了函數調用結構,時間控制在了0.3秒內:
幾次優化的過程可以從git歷史中看到
4.總結
通過這種邏輯題的分析,就能看出,計算機的優勢——快速作大量的判斷工作,看起來複雜的背後是一個個簡單的判斷,真相只有一個,只要認真分析,就能發現蛛絲馬跡,茅塞頓開
後面優化速度的內容讓我好好思考並優化函數調用結構,不知道還有更好的思路麼
最終運行時間控制在了0.3
秒內,正確答案只有一個BCACA,CDABA