詩社

詩社

學習練習

簡介

不相交集(一種並查集結構)會把一群值分割成互不重疊的群組,並且能快速回答一個問題:這兩個值是否在同一個群組裡?它位於disjoint-sets詞彙中。

建立不相交集

<disjoint-set>會建立一個空的結構。值,也就是原子,可以用add-atom一次加入一個,也可以用add-atoms從一個序列加入。每個原子一開始都自成一組。

<disjoint-set> ( -- disjoint-set )
add-atom       ( atom disjoint-set -- )
add-atoms      ( seq disjoint-set -- )
USING: disjoint-sets ;

<disjoint-set>
{ 1 2 3 } over add-atoms   ! 1, 2 and 3 each in their own group

不相交集是可變的:add-atom、add-atoms和equate會就地修改它,而不是回傳一個新的。當你希望不相交集在這些詞消耗掉之後回到堆疊上時,keep就很方便。

合併群組

equate會把包含其原子的兩個群組聯集起來。聯集具有遞移性:把兩個原子equate起來,再把其中一個與第三個equate,三個原子最後都會落在同一個群組裡。

equate ( atom1 atom2 disjoint-set -- )

代表

每個群組都有一個標準成員,也就是它的代表。representative會回傳它;兩個原子屬於同一個群組,若且唯若它們的代表相等。

representative ( atom disjoint-set -- representative )
USING: disjoint-sets ;

<disjoint-set>
{ 1 2 3 } over add-atoms
1 2 pick equate
1 over representative .   ! => 1
2 over representative .   ! => 1   (same representative as 1)
3 over representative .   ! => 3   (still on its own)

群組挑選哪個原子當代表是內部細節,永遠不要依賴某個特定原子被選中,只需要依賴同一個群組中的兩個原子代表相同。

說明

當地的詩社正要展開新的季度。詩人加入詩社後,只要其中兩位共同寫下一首詩,他們就屬於同一個寫作圈。詩社想記錄誰和誰共享同一個寫作圈,於是請你寫出管理這套關係的函式。

並查集正好適合這個任務:每位詩人是一個原子,而每個寫作圈是一個群組。

1. 開啟詩社

定義 new-club,接受一個詩人序列,回傳一個全新的並查集,其中每位詩人都已登記。每位詩人一開始都待在自己的寫作圈裡。

{ "Keats" "Byron" "Dickinson" } new-club
! => a disjoint set holding the three poets

2. 記錄一次合作

定義 collaborate,接受兩位詩人和一個詩社。它會合併這兩位詩人的寫作圈,並回傳該詩社,這樣就能接連記錄多筆合作。

{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
! => the club, with Keats and Byron now in one circle

3. 找出詩人的寫作圈

定義 circle-of,接受一位詩人和一個詩社,回傳該詩人寫作圈的代表。共享同一個寫作圈的兩位詩人,永遠會回報相同的代表。

{ "Keats" "Byron" "Dickinson" } new-club
"Dickinson" swap circle-of
! => "Dickinson"   (still in a circle of their own)

4. 共享同一個寫作圈?

定義 same-circle?,接受兩位詩人和一個詩社,當兩位詩人屬於同一個寫作圈時回傳 t,否則回傳 f。請比較兩位詩人的代表,而不是使用內建的等價性測試。

{ "Keats" "Byron" "Dickinson" } new-club
"Keats" "Byron" rot collaborate
dup [ "Keats" "Byron" ] dip same-circle? .      ! => t
    [ "Keats" "Dickinson" ] dip same-circle? .  ! => f
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Factor Exercism

準備好開始 詩社 了嗎?

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