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::io::{self, Read};
fn parse(input: &str) -> (usize, Vec<usize>) {
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");
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)
}
@@ -16,59 +20,61 @@ fn parse(input: &str) -> (usize, Vec<usize>) {
fn main() {
let mut input = String::new();
io::stdin().read_to_string(&mut input)
io::stdin()
.read_to_string(&mut 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 done = true;
let mut group = HashSet::new();
let mut visit = Vec::new();
pipes.iter().for_each(|&(from, ref to)| {
let mut create = true;
group.insert(to);
visited.insert(to);
for group in groups.values_mut() {
if group.contains(&from) {
create = false;
for id in from {
visit.push(id);
}
for id in to {
if group.insert(*id) {
done = false;
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);
}
if create {
let group = groups.entry(from).or_insert_with(HashSet::new);
let group_0 = groups
.iter()
.find(|group| group.contains(&0))
.expect("found no group");
group.insert(from);
for id in to {
group.insert(*id);
println!("part.one={}", group_0.len());
println!("part.two={}", groups.len());
}
}
});
if done {
break;
}
}
println!("part_one={}", groups[&0].len());
println!("part_two={}", groups.len());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse() {
assert_eq!(parse("0 <-> 2"), (0, vec![2]));