轨道
/
Factor
Factor
/
练习
/
混音带制作器
混音带制作器

混音带制作器

学习练习

简介

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词汇表中构建支撑他这些选择的组合数学辅助函数。

1. 计算组合数

定义count-combinations,返回从n个元素中选出k个元素、不考虑顺序的选法数量。

5 2 count-combinations .
! => 10

2. 计算排列数

定义count-permutations,返回从n个元素中选出k个元素、考虑顺序时的选法数量。

5 2 count-permutations .
! => 20

3. 列出组合

定义list-combinations,返回一个序列的所有k元组合。

{ 1 2 3 } 2 list-combinations .
! => { { 1 2 } { 1 3 } { 2 3 } }

4. 列出排列

定义list-permutations,返回一个序列的所有排列。

{ 1 2 } list-permutations .
! => { { 1 2 } { 2 1 } }

5. 和等于目标值的组合

定义combinations-summing-to,只返回序列中元素之和等于target的k元组合。

{ 1 2 3 4 } 2 5 combinations-summing-to .
! => { { 1 4 } { 2 3 } }
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Factor Exercism

准备好开始 混音带制作器 了吗?

注册 Exercism,借助 47 个概念163 个练习 和真人导师指导,学习并掌握 Factor,全部免费。