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