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) {
loop { continue;
let mut done = true;
pipes.iter().for_each(|&(from, ref to)| {
let mut create = true;
for group in groups.values_mut() {
if group.contains(&from) {
create = false;
for id in to {
if group.insert(*id) {
done = false;
}
}
}
}
if create {
let group = groups.entry(from).or_insert_with(HashSet::new);
group.insert(from);
for id in to {
group.insert(*id);
}
}
});
if done {
break;
} }
let mut group = HashSet::new();
let mut visit = Vec::new();
group.insert(to);
visited.insert(to);
for id in from {
visit.push(id);
}
while let Some(id) = visit.pop() {
group.insert(id);
visited.insert(id);
for id in pipes.get(&id).unwrap() {
if !group.contains(&id) {
visit.push(id);
}
}
}
groups.push(group);
} }
println!("part_one={}", groups[&0].len()); let group_0 = groups
println!("part_two={}", groups.len()); .iter()
} .find(|group| group.contains(&0))
.expect("found no group");
println!("part.one={}", group_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]));