2017/12
This commit is contained in:
@@ -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]));
|
||||
|
||||
Reference in New Issue
Block a user