diff options
-rw-r--r-- | 2020/rust/Cargo.toml | 2 | ||||
-rw-r--r-- | 2020/rust/day06/Cargo.toml | 10 | ||||
-rw-r--r-- | 2020/rust/day06/src/main.rs | 92 |
3 files changed, 103 insertions, 1 deletions
diff --git a/2020/rust/Cargo.toml b/2020/rust/Cargo.toml index 9c02f59..7c6ce52 100644 --- a/2020/rust/Cargo.toml +++ b/2020/rust/Cargo.toml @@ -6,7 +6,7 @@ members = [ "day03", "day04", "day05", -# "day06", + "day06", # "day07", # "day08", # "day09", diff --git a/2020/rust/day06/Cargo.toml b/2020/rust/day06/Cargo.toml new file mode 100644 index 0000000..0a1e5f4 --- /dev/null +++ b/2020/rust/day06/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day06" +version = "0.1.0" +authors = ["cos <cos>"] +edition = "2018" + +[dependencies] +aoc = { path = "../aoc" } +anyhow = "1.0" +thiserror = "1.0" 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), + } +} |