學習軌道
/
Python
Python
/
練習
/
巴斯卡三角形
巴斯卡三角形

巴斯卡三角形

中等

簡介

天氣這麼好,你一點也不想在教室裡待上一個小時。你有些不情願地走進教室,發現黑板上畫著一個形狀奇特、卻令人莫名感到滿足的三角形。在等數學老師來的時候,你不禁注意到這個三角形有幾個規律:最外側的值全都是 1,每一列都比前一列多一個值,而且整個三角形左右對稱。真奇怪!

坐下沒多久,老師就走進教室,解釋說這個三角形就是著名的巴斯卡三角形。

接下來的一小時裡,老師揭開了一些藏在這個三角形裡的奇妙事物:

  • 可以用它來計算從 N 個值中選出 K 個元素有多少種方式。
  • 它包含了費氏數列。
  • 如果把奇數和偶數塗上不同的顏色,就會得到一個美麗的圖案,叫做謝爾賓斯基三角形。

老師懇切地請你和同學們去查查其他用途,並向你保證還有更多更多喔!就在這時,下課鐘聲響了。你這才發現,過去這一個小時,你完全沉浸在認識巴斯卡三角形的世界裡。你迅速從包包裡拿出筆電,走到外面,準備同時享受陽光_和_巴斯卡三角形的奧妙。

說明

你的任務是輸出巴斯卡三角形的前 N 列。

巴斯卡三角形 是一個由正整數構成的三角形陣列。

在巴斯卡三角形中,每一列的數值個數等於它的列號(列號從 1 開始)。 因此,第 1 列有 1 個數值,第 2 列有 2 個數值,依此類推。

第 1 列(最頂端的那一列)只有 1 個數值:1。 之後每一列的數值,是把上一列中,目前位置正右方與正左方的數字相加而得。

如果上一列在目前位置的左方或右方沒有數值(這只會發生在最左邊和最右邊的位置),就把該位置的數值視為零(等於在相加時「忽略」它)。

範例

來看看巴斯卡三角形的前 5 列吧:

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1

最頂端的那一列只有 1 個數值,就是 1。

最左邊和最右邊的數值,各自只有一個相鄰位置要考慮,分別是它右方和左方的位置。 由於最頂端的數值是 1,由此可知,所有最左邊和最右邊的數值也都是 1。

其他數值都有兩個位置要考慮。 舉例來說,第 5 列(1 4 6 4 1)中間的數值是 6,因為上一列中它左方和右方的數值分別是 3 和 3:

這個練習在 Python 中如何實作:遞迴

這個練習的設計是要使用 recursion 來完成,而不是使用迴圈。 遞迴函式是一種會呼叫自身的函式,在解決以自身定義的問題時非常有用。 為了避免無限遞迴(更精確地說,是為了避免堆疊溢位),我們會使用一種稱為「基本情況」的東西。 當達到基本情況時,會回傳一個非遞迴的值,讓前一次的函式呼叫得以解析並回傳它的值,依此類推,一路沿著堆疊往回傳遞,直到第一次的函式呼叫回傳答案。 我們可以寫一個遞迴函式來計算 5!(也就是 5 * 4 * 3 * 2 * 1)的答案,就像這樣:

def factorial(number):
  if number <= 1:  # base case
    return 1

  return number * factorial(number - 1) # recursive case

print(factorial(5)) # returns 120

最後要注意的是,Python 限制了遞迴呼叫的次數(預設為 1000 次),而且不會對尾端遞迴進行最佳化。

例外訊息

有時候我們必須引發例外。 當你這麼做時,一定要附上有意義的錯誤訊息,指出錯誤的來源是什麼。 這讓你的程式碼更容易閱讀,也對除錯有相當大的幫助。 如果你知道錯誤來源會是某一種類型,可以選擇引發其中一種內建錯誤類型,但仍然要附上有意義的訊息。

這個練習要求你在rows()函式收到負數時,使用 raise 敘述「拋出」多個ValueErrors。 只有當你同時raise這個exception並附上訊息時,測試才會通過。

若要引發帶有訊息的ValueError,請把訊息寫成exception類型的引數:

# if the rows function is passed a negative number.
raise ValueError("number of rows is negative")
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Python Exercism

準備好開始 巴斯卡三角形 了嗎?

註冊 Exercism,透過 17 個概念146 個練習 和真人引導來學習並精通 Python,全部免費。