diff options
Diffstat (limited to '2020/rust/day06/src/main.rs')
-rw-r--r-- | 2020/rust/day06/src/main.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/2020/rust/day06/src/main.rs b/2020/rust/day06/src/main.rs new file mode 100644 index 0000000..948276a --- /dev/null +++ b/2020/rust/day06/src/main.rs @@ -0,0 +1,92 @@ +use anyhow::Result; +use std::collections::HashSet; +use std::env::args; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::Path; + +fn read_input<T: AsRef<Path>>(filename: T) -> Result<Vec<Vec<String>>> { + let f = File::open(filename)?; + let reader = BufReader::new(f); + let mut group = vec![]; + let mut groups = vec![]; + + for line in reader.lines() { + let line = line?; + if line.is_empty() { + groups.push(group); + group = vec![]; + continue; + } + group.push(line); + } + groups.push(group); + + Ok(groups) +} + +fn part1(input: &[Vec<String>]) -> Option<usize> { + let mut groups = vec![]; + for group in input { + let mut set = HashSet::new(); + for form in group.iter() { + for answer in form.clone().drain(..) { + set.insert(answer); + } + } + groups.push(set); + } + Some(groups.iter().map(|g| g.len()).sum()) +} + +fn part2(input: &[Vec<String>]) -> Option<usize> { + let mut groups = vec![]; + for group in input { + let sets: Vec<_> = group.iter().map(|form| { + let mut set = HashSet::new(); + for answer in form.clone().drain(..) { + set.insert(answer); + } + set + }).collect(); + let combined: HashSet<_> = match sets.get(0) { + Some(first) => sets.iter() + .fold(first.clone(), |a, s| s.intersection(&a).cloned().collect()), + None => return None, + }; + + groups.push(combined); + } + Some(groups.iter().map(|g| g.len()).sum()) +} + +fn main() { + let (do_part_1, do_part_2) = aoc::do_parts(); + + let filename = match args().nth(1) { + Some(f) => f, + None => { + eprintln!("Missing input filename"); + std::process::exit(1); + }, + }; + match read_input(filename) { + Ok(input) => { + if do_part_1 { + match part1(&input) { + Some(solution) => + println!("Part1, sum of all groups combined yes answers: {}", solution), + None => eprintln!("Part1, no soluton found"), + } + } + if do_part_2 { + match part2(&input) { + Some(solution) => + println!("Part2, sum of all groups common yes answers: {}", solution), + None => eprintln!("Part2, no soluton found"), + } + } + }, + Err(err) => eprintln!("Could not read input: {}", err), + } +} |