4个版本 (破坏性更新)

使用旧的Rust 2015

0.4.0 2018年2月12日
0.3.0 2018年2月6日
0.2.0 2018年2月6日
0.1.0 2018年2月4日

#2100 in 算法

MIT 许可证

41KB
842

Packing Puzzle构建状态覆盖率状态pack on crates.io

拼图问题的求解器。

安装

您可以通过在Cargo.toml中添加依赖项来使用此库。

[dependencies]
pack = "*"

如果您想指定特定版本,请输入版本号。

Slothouber-Graatsma 拼图

Slohouber-Graatsma 拼图要求将

六个 1 × 2 × 2 的块和三个 1 × 1 × 1 的块拼入一个 3 × 3 × 3 的盒子中。

我们将使用pack库来解决这个问题。

首先,我们声明外部包的使用。

extern crate pack;

在我们开始解决拼图之前,我们需要几样东西。一个是pack::puzzle::solver::Target。目标指定要填充的体积。目标使用pack::puzzle::piece::Position的向量创建。

fn brick3x3x3() -> Target {
    Target::new(vec!(
        Position::new(0, 0, 0),
        Position::new(1, 0, 0),
        Position::new(2, 0, 0),
        Position::new(0, 1, 0),
        Position::new(1, 1, 0),
        Position::new(2, 1, 0),
        Position::new(0, 2, 0),
        Position::new(1, 2, 0),
        Position::new(2, 2, 0),

        Position::new(0, 0, 1),
        Position::new(1, 0, 1),
        Position::new(2, 0, 1),
        Position::new(0, 1, 1),
        Position::new(1, 1, 1),
        Position::new(2, 1, 1),
        Position::new(0, 2, 1),
        Position::new(1, 2, 1),
        Position::new(2, 2, 1),

        Position::new(0, 0, 2),
        Position::new(1, 0, 2),
        Position::new(2, 0, 2),
        Position::new(0, 1, 2),
        Position::new(1, 1, 2),
        Position::new(2, 1, 2),
        Position::new(0, 2, 2),
        Position::new(1, 2, 2),
        Position::new(2, 2, 2),
    ))
}

因为砖块经常被用作目标,所以有一个实用函数pack::util::target::brick,它正好可以做到这一点。上面的代码可以用brick(3, 3, 3)替换。

我们还需要一个pack::puzzle::pieces::Bag,其中包含pack::puzzle::piece:Template。模板是可以通过迭代以不同方式定位的形状。袋是一个用于保存模板的容器。

模板是通过提供它们所占据的位置向量创建的。

fn slothouber_graatsma_bag() -> Bag {
    Bag::new(vec!(
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
            Position::new(1, 0, 0),
            Position::new(0, 1, 0),
            Position::new(1, 1, 0),
        )),

        Template::new(vec!(
            Position::new(0, 0, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
        )),
        Template::new(vec!(
            Position::new(0, 0, 0),
        )),
    ))
}

最后,我们需要告诉 solve 函数在找到解时应该做什么。这可以通过传递一个 clojure 来实现。对于这个例子,我们将只打印出解。

我们的 main 函数可能看起来像以下代码。

fn main(){
    let target = brick(3, 3, 3);
    let bag = slothouber_graatsma_bag();

    solve(&target, bag, &mut |solution|{
        println!("{}", solution)
    });
}

运行它将打印出 Slothouber-Graatsma 棋盘游戏的解。这个例子的完整源代码可以在 examples/slothouber-graatsma.rs 中找到。更多文档请参阅 wiki

开发

如果您想为此库做出贡献,请阅读 CONTRIBUTING.md

运行 clippy

按照 clippy 的安装说明进行安装,并运行以下命令。

cargo +nightly clippy

无运行时依赖