summaryrefslogtreecommitdiff
path: root/2020/rust/day06/src
diff options
context:
space:
mode:
Diffstat (limited to '2020/rust/day06/src')
-rw-r--r--2020/rust/day06/src/main.rs92
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),
+ }
+}