02-1. 來託夢的魔術師
Computer Science activities with a sense of fun: The Australian Magician’s Dream V1.1, 27 Jan 2014
Created by Peter McOwan and Paul Curzon, Queen Mary, University of London for Teaching London Computing: http://teachinglondoncomputing.org
本教材以創用CC 3.0 姓名標示-非商業性-相同方式分享釋出(creative commons 3.0 BY-NC-SA) https://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh_TW
這是一個常見的魔術,猜到別人手上選擇的那張卡片內容是什麼。
這個魔術展示了搜尋演算法與運算的思維是如何運作的。
找一個自願者來協助進行這個魔術,演示它的效果,然後教大家這個魔術的原理並解釋其中所牽涉的運算思維。
在這個單元可以學習到:
- 演算法
- 運算思維
- 抽象化
- 邏輯推理
- 計算模型
- 搜尋
活動說明:
1. 我們需要:一副普通的撲克牌,一張小桌子,另一張紅心8的卡片(大張一點)以及裝得下這張卡片的信封,可以多準備一張止滑墊協助活動進行。
2. 也可以額外再準備:寫上數字1~52的卡片一份,找一張點數小於33的卡片,另外用一張顏色鮮艷的卡片書寫編號,一條長度2到3公尺的彩色鍛帶,52個衣夾子。
3. 告訴學生接下來你要表演一個魔術,之後會向大家解釋它的原理,接著我們還要用電腦實作一次。
4. 預先準備:
(1) 找到普通撲克牌之中的紅心8與紅心A,由上自下算,將紅心8放在第16張牌的位置、將紅心A放在第32張牌的位置。字面朝下放在桌面上。
(2) 將另一張紅心8放在信封裡面,放在準備要展示魔術的桌子底下。
5. 徵求一個自願者,請他字面朝上攤開這副撲克牌,要讓每一張牌的字都清楚可見(確保能看見紅心8與紅心A),並請自願者確認這副牌是正常、沒有被動過手腳的。(小心別被拿去洗牌了)
6. 接下來用看似隨意的方式,把兩隻手掌蓋住紅心8以及紅心A,再請自願者在兩隻手掌之間隨意指出一張牌,以這張牌為基準將整副牌分成左右兩份。
7. 將包含紅心8的那半份撲克牌收攏,字面朝下蓋住。另半份撲克牌收攏之後,置於另外一邊,待會不會再用到它們。
8. 告訴大家,最近你的夢裡面時常有一個魔術師出現,教會你很多神奇的魔術(俗稱託夢)。而等一下要做的事情,是昨天晚上他剛好教會你的。用一個響亮的稱呼來為這個操作的動作命名,為了要有點中國風的神祕感在這裡我們暫且稱為「陰陽」。
9. 「陰陽」的操作動作:
(1) 拿起剩餘牌堆的第一張牌(此時字面朝「下」,發下牌時字面應朝「上」放置)。從左手邊開始放牌,稱呼這個地方為「陰」;拿起第二張牌,字面朝上放在右手邊,稱呼這個地方為「陽」。(紅心8會被放在「陽」之內)
(2) 依此類推,第三張牌放在「陰」、第四張牌放在「陽」…如此反覆操作把所有的牌分完。
(3) 棄置「陰」這一組的所有牌,拿起另一組牌堆繼續做陰陽的分組(手持牌堆時字面一樣朝下,但是發牌時字面朝上),每次分完後都棄置「陰」組的牌。
(4) 最後桌面上只會剩下一張牌,這張牌必定是紅心8,再次確認一開始分堆動作的基準牌是他自由選擇的。
(5) 請自願者從桌子底下找出剛剛你藏好的信封,請他抽出裡面的那張卡片。見證奇蹟的時刻到了,裡面竟然放的也是紅心8!
運算思維:
這個魔術所運用的技法,魔術師稱為「自我運轉(self-working)」,意思是只要按照事先設計好的步驟執行這個魔術,最後的也一定會得到事先設計好的結果。
這個魔術的簡化版本是這樣進行的:將要預測的最後結果牌,放在第16張牌的位置。棄置一半的牌,接著一樣進行分堆的動作,奇數張牌與偶數張牌分開放置,每次都丟棄奇數牌所屬的那一堆。用陰跟陽來稱呼分堆的動作,如前所述,只是為了加點神祕感。
我們必須讓自願者按照設計好的步驟一步一步執行,就像電腦工程師在撰寫程式一樣,魔術師也正在作演算法的思維。在要求自願者執行步驟的時候,同時也運用到了抽象化(abstraction)的概念,我們不會給予太多的、複雜的、艱深的指令,而是用「丟棄那一個牌堆」的方式,直接且清楚地要求自願者照著做。講得太多無助於魔術效果,反而會讓觀眾分心而無法專注在你想要表達的技巧上。
要想知道為什麼最後的桌上一定只會留下紅心8,我們會運用到邏輯推理(logical reasoning)的方式來推導:
原始牌堆(由上到下的編號順序,非點數與花色): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24…51 52
切牌後(假設自願者指定的切牌基準是第24張牌): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
第一次分陰陽堆後: 2 4 6 8 10 12 14 16 18 20 22 24
第二次分陰陽堆後: 4 8 12 16 20 24
第三次分陰陽堆後: 8 16 24
第四次分陰陽堆後: 16
所以最後留下的一定是第16張牌,也就是紅心8。
以上這個推導的過程也算是一種抽象化的概念,我們不管實際上這些牌的花色與點數,我們只關注了第16與32張牌位置的這兩張牌,而且只要知道我們為第16張牌的位置選的牌是什麼花色與點數就好了,其他的一點都不重要。(思考一下,指定第32張牌一定要是紅心A的用意是什麼?)
有另外一種表示這個魔術的方式,效果也不錯。在教室綁一條夠長的緞帶,將52張撲克牌用衣夾子夾在緞帶上。用剛剛選牌的步驟,讓自願者在第16與32張牌之間選擇一個基準牌,將基準牌右手邊的牌全部拆掉。接下來請自願都依序拆下第1、3、5…張牌,從剩下的撲克牌子重覆拆掉奇數張牌的這個動作。最後留在緞帶上的牌一定也是第16張牌。
這個魔術中,緞帶與卡片的角色都屬於計算模型(computational model),一個模型就是一組被簡化過後的概念,像是我們只在乎牌的編號,而非上頭的點數花色,電腦工程師若要透過程式設計來推演這套演算法,他們同樣只需要關心編號就夠了。
延伸活動:
請學生思考這個魔術的技巧,讓他們修改成另一種魔術表演的方式。我們的預測目標一定要放在牌堆裡的第5個位置,那該如何進行這個魔術,才能達成最後準確預測留下最後那一張牌的效果呢?(提示:「陰」堆的牌可能不見得每次都被丟棄,有時候也會被留下來)