This commit is contained in:
2018-11-30 22:12:18 +01:00
parent 045ea63bd9
commit 40eb43173e

View File

@@ -1,14 +1,18 @@
use std::io::{self, Read};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::io::{self, Read};
fn parse(input: &str) -> (usize, Vec<usize>) { fn parse(input: &str) -> (usize, Vec<usize>) {
let parts = input.split("<->").collect::<Vec<_>>(); let parts = input.split("<->").collect::<Vec<_>>();
let from = parts[0].trim().parse::<usize>() let from = parts[0]
.trim()
.parse::<usize>()
.expect("faild to parse from"); .expect("faild to parse from");
let to = parts[1].split(',').filter_map(|to| to.trim().parse::<usize>().ok()).collect::<Vec<_>>(); let to = parts[1]
.split(',')
.filter_map(|to| to.trim().parse::<usize>().ok())
.collect::<Vec<_>>();
(from, to) (from, to)
} }
@@ -16,59 +20,61 @@ fn parse(input: &str) -> (usize, Vec<usize>) {
fn main() { fn main() {
let mut input = String::new(); let mut input = String::new();
io::stdin().read_to_string(&mut input) io::stdin()
.read_to_string(&mut input)
.expect("faild to read input"); .expect("faild to read input");
let pipes = input.lines().filter(|line| !line.is_empty()).map(parse).collect::<Vec<_>>(); let pipes = input
.lines()
.filter(|line| !line.is_empty())
.map(parse)
.collect::<HashMap<usize, Vec<_>>>();
let mut groups = HashMap::new(); let mut groups = Vec::new();
let mut visited = HashSet::new();
groups.entry(0).or_insert_with(HashSet::new).insert(0); for (to, from) in &pipes {
if visited.contains(&to) {
continue;
}
loop { let mut group = HashSet::new();
let mut done = true; let mut visit = Vec::new();
pipes.iter().for_each(|&(from, ref to)| { group.insert(to);
let mut create = true; visited.insert(to);
for group in groups.values_mut() { for id in from {
if group.contains(&from) { visit.push(id);
create = false; }
for id in to { while let Some(id) = visit.pop() {
if group.insert(*id) { group.insert(id);
done = false; visited.insert(id);
for id in pipes.get(&id).unwrap() {
if !group.contains(&id) {
visit.push(id);
} }
} }
} }
groups.push(group);
} }
if create { let group_0 = groups
let group = groups.entry(from).or_insert_with(HashSet::new); .iter()
.find(|group| group.contains(&0))
.expect("found no group");
group.insert(from); println!("part.one={}", group_0.len());
println!("part.two={}", groups.len());
for id in to {
group.insert(*id);
}
}
});
if done {
break;
}
}
println!("part_one={}", groups[&0].len());
println!("part_two={}", groups.len());
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_parse() { fn test_parse() {
assert_eq!(parse("0 <-> 2"), (0, vec![2])); assert_eq!(parse("0 <-> 2"), (0, vec![2]));