Small changes.
This commit is contained in:
125
2015/09/src/main.rs
Normal file
125
2015/09/src/main.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
#[macro_use] extern crate lazy_static;
|
||||
extern crate regex;
|
||||
|
||||
use std::io::{self, Read};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
|
||||
type Map<'a> = BTreeMap<&'a str, BTreeMap<&'a str, i64>>;
|
||||
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Route<'a> {
|
||||
vec: Vec<&'a str>,
|
||||
distance: i64
|
||||
}
|
||||
|
||||
impl<'a> Route<'a> {
|
||||
fn new() -> Route<'a> {
|
||||
Route {
|
||||
vec: Vec::new(),
|
||||
distance: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn process<'a>(input: &'a str) -> Route<'a> {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(r"^([a-zA-Z]+) to ([a-zA-Z]+) = (\d+)$").unwrap();
|
||||
}
|
||||
|
||||
let mut map: Map = BTreeMap::new();
|
||||
|
||||
for line in input.lines() {
|
||||
let caps = RE.captures(&line).unwrap();
|
||||
|
||||
let a = caps.at(1).unwrap();
|
||||
let b = caps.at(2).unwrap();
|
||||
|
||||
let distance = caps.at(3).unwrap().parse::<i64>().unwrap();
|
||||
|
||||
map.entry(a).or_insert(BTreeMap::new()).insert(b, distance);
|
||||
map.entry(b).or_insert(BTreeMap::new()).insert(a, distance);
|
||||
}
|
||||
|
||||
let mut routes = iterate(&map, None);
|
||||
|
||||
routes.sort_by_key(|x| x.distance);
|
||||
|
||||
routes.remove(0)
|
||||
}
|
||||
|
||||
fn iterate<'a>(map: &Map<'a>, route: Option<Route<'a>>) -> Vec<Route<'a>> {
|
||||
let mut routes = Vec::new();
|
||||
|
||||
if let Some(mut route) = route {
|
||||
let prev = *route.vec.last().unwrap();
|
||||
|
||||
let mut end = true;
|
||||
|
||||
for (city, distance) in map.get(prev).unwrap().iter() {
|
||||
if route.vec.contains(city) {
|
||||
continue;
|
||||
}
|
||||
|
||||
route.vec.push(*city);
|
||||
route.distance += *distance;
|
||||
|
||||
{
|
||||
let mut sub_routes = iterate(&map, Some(route.clone()));
|
||||
|
||||
routes.append(&mut sub_routes);
|
||||
}
|
||||
|
||||
end = false;
|
||||
}
|
||||
|
||||
if end {
|
||||
routes.push(route);
|
||||
}
|
||||
} else {
|
||||
for city in map.keys() {
|
||||
let mut route = Route::new();
|
||||
|
||||
route.vec.push(*city);
|
||||
|
||||
{
|
||||
let mut sub_routes = iterate(&map, Some(route));
|
||||
|
||||
routes.append(&mut sub_routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
routes
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_to_string(&mut input).unwrap();
|
||||
|
||||
let result = process(&input);
|
||||
|
||||
println!("{:?}", result);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::process;
|
||||
|
||||
#[test]
|
||||
fn example_01() {
|
||||
let input = "London to Dublin = 464\n\
|
||||
London to Belfast = 518\n\
|
||||
Dublin to Belfast = 141";
|
||||
|
||||
let result = process(input);
|
||||
|
||||
assert_eq!(605, result.distance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user