8 个版本 (破坏性更新)
0.8.0 | 2024 年 3 月 16 日 |
---|---|
0.7.0 | 2024 年 3 月 15 日 |
0.6.0 | 2024 年 3 月 15 日 |
0.5.0 | 2024 年 3 月 12 日 |
0.1.0 | 2024 年 3 月 2 日 |
143 在 数学
每月 374 次下载
37KB
790 代码行
xensieve
泽纳基斯筛的实现,提供从字符串表达式创建筛的功能,将整数序列过滤成整数迭代器、布尔状态或区间宽度。筛是由余数构成的,余数定义为模数(M)和位移(S),表示为 M@S
。筛字符串表达式和筛结构体支持对余数进行补集、交集、对称差和并集操作,分别使用运算符 !
、&
、^
和 |
。
泽纳基斯筛是一种生成离散区间模式的工具。这种模式在创意领域有无限的应用:泽纳基斯筛可用于生成音阶或多八度音高序列、节奏和多节奏,也可用于控制无数其他方面,如图形或建筑设计。
此 Rust 实现遵循 Ariza(2005 年)中的 Python 实现,具有显著的性能和界面改进:[链接](https://direct.mit.edu/comj/article/29/2/40/93957)
代码:[链接](https://github.com/flexatone/xensieve-rs)
文档:[链接](https://docs.rs/xensieve)
仓库:[链接](https://crates.io/crates/xensieve)
创建筛的策略
首先,我们可以检查由单个余数构建的筛的输出。如上所示,余数定义为模数(M)和位移(S),表示为 M@S
。在下面的图中,显示了三个余数:5@0
、4@2
和 30@10
。如上图所示,对于每个 M 单位,在位移 S 处都有一个值。最后的例子展示了单值反转运算符 !30@10
的应用。
复杂筛将余数与逻辑运算符(如补码、交集、对称差和并集)相结合。在下面的例子中,余数 5@0
和 4@2
通过并集表达式 5@0|4@2
进行结合。通过并集组合许多余数是构建序列的实际方法。最后的例子 (5@0|4@2)&!30@10
显示了通过与倒置的余数(!30@10
)相交来“移除”所选值。
根据定义,所有筛都是周期的,但余数的组合可以产生具有高度局部复杂性和内部模式的序列。
xensieve.Sieve
接口
上述筛可以使用 xensieve.Sieve
创建,并用于生成整数的迭代器、布尔状态或区间宽度。构造函数 Sieve::new
接受任意复杂的筛表达式。
use xensieve::Sieve;
let s1 = Sieve::new("5@0");
let s2 = Sieve::new("30@10");
let s3 = Sieve::new("(5@0|4@2)&!30@10");
iter_value()
方法接受一个整数迭代器,可以用来“驱动”筛,无论是有序连续整数还是任意序列。迭代器生成筛内整数的子集。
use xensieve::Sieve;
assert_eq!(s1.iter_value(0..50).collect::<Vec<_>>(), vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
assert_eq!(s2.iter_value(0..50).collect::<Vec<_>>(), vec![10, 40]);
assert_eq!(s3.iter_value(0..50).collect::<Vec<_>>(), vec![0, 2, 5, 6, 14, 15, 18, 20, 22, 25, 26, 30, 34, 35, 38, 42, 45, 46]);
xensieve.Sieve
有两个替代迭代器,允许在不同的上下文中使用筛。迭代器 iter_state()
对于每个提供的整数返回相应的布尔状态。
assert_eq!(s1.iter_state(0..10).collect::<Vec<_>>(), vec![true, false, false, false, false, true, false, false, false, false]);
assert_eq!(s3.iter_state(0..10).collect::<Vec<_>>(), vec![true, false, true, false, false, true, true, false, false, false]);
iter_interval()
迭代器对于在筛内的提供的整数序列,返回相应的区间。
assert_eq!(s2.iter_interval(0..50).collect::<Vec<_>>(), vec![30]);
assert_eq!(s3.iter_interval(0..50).collect::<Vec<_>>(), vec![2, 3, 1, 8, 1, 3, 2, 2, 3, 1, 4, 4, 1, 3, 4, 3, 1]);
可以使用 contains()
方法来测试任意整数是否包含在筛中。
assert_eq!(s1.contains(5), true);
assert_eq!(s1.contains(6), false);
assert_eq!(s3.contains(10), false);
assert_eq!(s3.contains(30), true);
xensieve
的新功能
0.8.0
文档和CI改进。
0.7.0
文档和CI改进。
0.6.0
CI改进。
0.5.0
文档改进。
0.4.0
实现了对 &Sieve
的操作符支持。
改进文档。
0.3.0
代码清理和改进文档字符串。
0.2.0
在 Sieve
上实现了对称差运算符 ^
。
0.1.0
首次发布。