運算思維及 Ruby 初體驗

醫學專業養成中,或許因為我們直面的困境過於龐雜,一個活生生的人(或家屬)出現在我們面前,在有限的時間內拋出了層層疊嶂、盤根錯節、追溯遠古的故事,我們大腦的神經元最好在眾多鑑別診斷中挑出最適配的前幾個,配合理學檢查和生命徵象決定進一步的檢查。但我很少有時間回頭審視自己的臨床推理邏輯 (Clinical thinking process) 如何形成?怎麼抽絲剝繭並條理分明地找出相應的解答?運算思維 (Computational thinking) 作為一種思考方法及過程,確實讓我耳目一新,並試著讓它與我熟悉的日常難題產生關聯。

維基百科說:

運算思維是一個思考的程序。它的目的是闡明問題,並呈現其解決方案,因而讓「運算器」(包括機器與人) 能夠有效率地執行。(Computational thinking is the thought processes involved in formulating a problem and expressing its solution(s) in such a way that a computer—human or machine—can effectively carry out.)

大航道教導我的「運算思維」有以下四個核心步驟:

  1. 解構 (Decomposition) 將複雜的問題或系統分解成更⼩、更易於管理的問題 – 照顧住院病人時的 POMR,會有不同的 Problems,整體彙總成病人來住院的原因
  2. 模式識別 (Pattern Recognition) 將每個⼩問題分別檢視,思考之前是否有解過類似的問題 – 每個 Problems 都會有不同的 Assessment 及 Treatment (但病人太多真是很難啊~)
  3. 抽象化 (Abstraction) 抓出重要的細節,將它轉化爲解決⽅案中的步驟 – 每個疾病的檢查或治療總會有些先後順序、輕重緩急,資源有限 (加上老師的偏好?) 總是需要先做最重要緊急的,加上參考學長姐或小麻之類大神的分享,把處置方式具體地內化
  4. 演算法設計 (Algorithm Design) 歸納出簡單的步驟或原則來解決每個⼩問題 – 等到往後碰到類似問題、疾病,就知道怎麼制定出符合治療指引、健保規範、又足夠個別化的診療方式

今天總算開始練習大航道「判斷 n 是否為 2 的次方」的邏輯問題,給定一個正整數 n,判斷 n 是不是 2 的次方。

對我來說,最困難的還是解構思考流程並寫出足夠清晰的 Pseudocode,比如老師們給出的演算法步驟及 Pseudocode 為:

#

步驟 1

步驟 2

步驟內容

測試 n 是否等於 1,如果是 ⇒ n 是 2 的次方

在 n >= 2 的情況,把 n 除以 2,如果:
餘數不是 0 ⇒ n 不是 2 的次方
餘數是 0 而答案是 1 ⇒ n 是 2 的次方
餘數是 0 而答案 > 1 ⇒ 重複此步驟

Photo copyright: 大航道
def is_power_of_two(n)
# 先處理例外:如果 n 等於 1,它就是 2的次方
# 把 n 除以 2,如果
# 餘數是 1 ⇒ n 不是 2 的次方
# 餘數是 0 而答案是 1 ⇒ n 是 2 的次方
# 餘數是 0 而答案 > 1 ⇒ 重複此步驟
end

苦思了差不多三小時(太遜了XD),原本我還想先把 n % 2 = a, n / 2 = b 來解,但寫到重複步驟這關就卡住了,只好去參考些其他大大的解法,最後的答案是(我看也有學長姐在例外寫完是直接用 elsif 接其他非例外狀況):

def is_power_of_two(n)

  # 先處理例外:如果 n 等於 1,它就是 2的次方 
if n == 1
  return true
end

  # 把 n 除以 2,如果
    # 餘數是 1 ⇒ n 不是 2 的次方
    # 餘數是 0 而答案是 1 ⇒ n 是 2 的次方
    # 餘數是 0 而答案 > 1 ⇒ 重複此步驟
  if ( n % 2 == 0 && n / 2 > 1 )
      (n = n / 2) until n <= 3
     if n % 2 == 1
      return false
     else
      return true
     end
  else
    return false
  end

end

puts "When n = 1, #{is_power_of_two(1)}" # should return true.
puts "When n = 99, #{is_power_of_two(99)}" # should return true.
puts "When n = 7, #{is_power_of_two(7)}" # should return false.
puts "When n = 1256, #{is_power_of_two(1256)}" # should return false.
puts "When n = -6, #{is_power_of_two(-6)}" # should return true.

亂玩了一下,總算跑得出來了(掩面)

[~] $ ruby power_of_two.rb
When n = 1, true
When n = 99, false
When n = 7, false
When n = 1256, true
When n = -6, false

**這是參考其他大神學長姐的程式碼

def is_power_of_two(n)

# 先處理例外:如果 n 等於 1,它就是 2的次方
if n == 1
result = "true"

把 n 除以 2,如果
餘數是 1 ⇒ n 不是 2 的次方
elsif n%2 == 1
return "false"
餘數是 0 而答案是 1 ⇒ n 是 2 的次方
elsif n%2 == 0 && n/2 == 1
return "true"
餘數是 0 而答案 > 1 ⇒ 重複此步驟
else n%2 == 0 && n/2 >1
n = n/2
return is_power_of_two(n)
end
end

好厲害,原來用「return」就可以解決我卡一小時的問題,看來我找答案的功力還要再加把勁~

以下是大航道提供的四支國外講解運算思維 (Computational Thinking) 的影片,讓我們能對運算思維的每一步驟有更深入的了解:
解構 Computational Thinking: Decomposition
https://www.youtube.com/watch?v=yQVTijX437c&t=209s (11 分鐘)
模式識別 Computational Thinking: Pattern Recognition
https://www.youtube.com/watch?v=SixLnIDV1yY (10 分鐘)
抽象化 Computational Thinking: Abstraction and Pattern Generalization
https://www.youtube.com/watch?v=RdzYOtxhuDc (10 分鐘)
演算法設計 Computational Thinking: Algorithm Design
https://www.youtube.com/watch?v=N91oCQbWUvA (14 分鐘)

Leave a Reply

Your email address will not be published. Required fields are marked *