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,它会用每个组合调用一次引用:
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,它会用每一种排序调用一次引用:
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 } }