math.combinatorics 詞彙可以回答關於一群項目的兩類問題:
每個問題都有一個會回傳數字的計數詞,以及一個會回傳實際選取結果的列出詞。
nCk("n choose k")會回傳從n個項目中可以選出多少個含k個元素的組合:
nCk ( n k -- m )
USING: math.combinatorics prettyprint ;
5 2 nCk . ! => 10
6 3 nCk . ! => 20
5 5 nCk . ! => 1
nPk 會回傳從n個項目中可以做出多少個含k個元素的有序選取(排列)。由於順序很重要,這個數量至少會和對應的nCk一樣大:
nPk ( n k -- m )
5 2 nPk . ! => 20
6 3 nPk . ! => 120
all-combinations 會回傳一個序列中所有含k個元素的子集。每個組合內的元素會保持原本的順序,而這些組合會以字典序回傳:
all-combinations ( seq k -- combinations )
{ 1 2 3 } 2 all-combinations .
! => { { 1 2 } { 1 3 } { 2 3 } }
如果你只想在每個組合產生時就處理它,而不是先把它們全部收集起來,請使用串流形式的each-combination,它會針對每個組合呼叫 quotation:
each-combination ( seq k quot -- )
{ 1 2 3 } 2 [ . ] each-combination
! => { 1 2 }
! => { 1 3 }
! => { 2 3 }
all-permutations 會回傳一個序列的每一種排序:
all-permutations ( seq -- permutations )
{ 1 2 } all-permutations .
! => { { 1 2 } { 2 1 } }
{ 1 2 3 } all-permutations .
! => { { 1 2 3 } { 1 3 2 } { 2 1 3 } { 2 3 1 } { 3 1 2 } { 3 2 1 } }
它的串流對應版本是each-permutation,會針對每一種排序呼叫 quotation:
each-permutation ( seq quot -- )
{ 1 2 } [ . ] each-permutation
! => { 1 2 }
! => { 2 1 }
Ozan 正在打造一張完美的混音帶:先決定哪些歌曲能入選,再敲定它們的播放順序。你將在mixtape-maker詞彙中,打造他這些選擇背後的組合數學工具喔。
定義count-combinations,回傳從n中選出k個項目的方法數,不計順序。
5 2 count-combinations .
! => 10
定義count-permutations,回傳從n中選出k個項目的方法數,且順序有別。
5 2 count-permutations .
! => 20
定義list-combinations,回傳一個序列中所有由k個元素組成的組合。
{ 1 2 3 } 2 list-combinations .
! => { { 1 2 } { 1 3 } { 2 3 } }
定義list-permutations,回傳一個序列的每一種排列順序。
{ 1 2 } list-permutations .
! => { { 1 2 } { 2 1 } }
定義combinations-summing-to,只回傳序列中元素加總等於target的那些k組合。
{ 1 2 3 4 } 2 5 combinations-summing-to .
! => { { 1 4 } { 2 3 } }