我正在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
,这是正确的。但是,它有时会打印210
,204
或155
之类的内容。为什么会发生这种情况?
以下是程序的输入,以防它帮助您:https://pastebin.com/XJzsMy5A
答案 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();