Rust程序偶尔会产生不一致的结果

时间:2017-08-08 20:50:33

标签: rust

我正在Rust的Advent of Code第9天的第1部分工作,遇到了一个奇怪的问题。我编写了以下代码,它通常有效,但大约有10%的时间它会给出错误的答案。

extern crate permutohedron;

use std::fs::File;
use std::io::{BufRead, BufReader};
use std::collections::HashMap;
use std::rc::Rc;

use permutohedron::LexicalPermutation;

fn get_distance(cities: &[Rc<String>], paths: &HashMap<(Rc<String>, Rc<String>), i64>) -> i64 {
    cities.iter().fold((0, None), |(sum, last_city), city| {
        (last_city.map_or(0, |last_city| {
            sum + *paths.get(&(last_city, city.clone())).unwrap()
        }), Some(city.clone()) )
    }).0
}

fn main() {

    let file = File::open("input_9.txt").unwrap();
    let file = BufReader::new(file);

    let mut paths = HashMap::new();
    let mut cities = HashMap::new();

    for line in file.lines() {
        let line = line.unwrap();
        let mut words = line.split(' ');
        let from = words.nth(0).unwrap();
        let to = words.nth(1).unwrap();

        if !cities.contains_key(from) {
            cities.insert(from.to_owned(), Rc::new(from.to_owned()));
        }
        if !cities.contains_key(to) {
            cities.insert(to.to_owned(), Rc::new(to.to_owned()));
        }

        let from = cities.get(from).unwrap();
        let to = cities.get(to).unwrap();

        let dist = words.nth(1).unwrap().parse::<i64>().unwrap();
        paths.insert((from.clone(), to.clone()), dist);
        paths.insert((to.clone(), from.clone()), dist);
    }

    let mut cities_perm: Vec<_> = cities.values().map(|k| k.clone()).collect();

    let mut min_path = None;
    loop {
        let dist = get_distance(&cities_perm, &paths);

        min_path = Some(min_path.map_or(dist, |v|
            *[v, dist].iter().min().unwrap()
        ));

        if !cities_perm.next_permutation() { break }
    }

    println!("{}", min_path.unwrap());

}

我正在使用cargo run运行它,并且永远不会更改文件input_9.txt,所以我认为没有理由给出不同的答案。我也尝试构建它,然后运行它直接构建的可执行文件,如./target/debug/day_9,同样的事情发生。我注意到它在构建之后很快就会给出错误的结果,而不是以后。

通常,我得到141,这是正确的。但是,它有时会打印210204155之类的内容。为什么会发生这种情况?

以下是程序的输入,以防它帮助您:https://pastebin.com/XJzsMy5A

1 个答案:

答案 0 :(得分:4)

问题在于,调用next_permutation会为您提供下一个&#34;有序排列&#34; (link to the docs)。

这里需要注意的是,您没有迭代在输入切片之前排序的词汇排列 - 例如,如果您从这条路径开始:

["Norrath", "Faerun", "Tristram", "Tambi", "Straylight", "Snowdin", "Arbre", "AlphaCentauri"]

你永远不会走到这条道路上:

["Arbre", "Snowdin", "Norrath", "Faerun", "Tambi", "Tristram", "AlphaCentauri", "Straylight"]

由于HashMap不保证键或值排序,cities_perm排序在每次运行时都不同,因此您迭代所有可能排列的不同子集并获得不同的结果。

一种解决方案可能是在开始排列之前对城市进行排序:

cities_perm.sort();