diff options
author | cos <cos> | 2020-12-10 08:46:00 +0100 |
---|---|---|
committer | cos <cos> | 2020-12-12 00:31:41 +0100 |
commit | fb10e41b64192cf2aa0961d43426e12a8fb7ba1c (patch) | |
tree | 5844dccb9d846519b0d00fe0403a5ab5095d2b02 /2020/rust/day10 | |
parent | 881aff60c703f3929048405fd8bbf8f0533ded72 (diff) | |
download | adventofcode-fb10e41b64192cf2aa0961d43426e12a8fb7ba1c.zip |
Add day10, 2020
Diffstat (limited to '2020/rust/day10')
-rw-r--r-- | 2020/rust/day10/Cargo.toml | 9 | ||||
-rw-r--r-- | 2020/rust/day10/src/main.rs | 94 |
2 files changed, 103 insertions, 0 deletions
diff --git a/2020/rust/day10/Cargo.toml b/2020/rust/day10/Cargo.toml new file mode 100644 index 0000000..75eae97 --- /dev/null +++ b/2020/rust/day10/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day10" +version = "0.1.0" +authors = ["cos <cos>"] +edition = "2018" + +[dependencies] +aoc = { path = "../aoc" } +anyhow = "1.0" diff --git a/2020/rust/day10/src/main.rs b/2020/rust/day10/src/main.rs new file mode 100644 index 0000000..905c525 --- /dev/null +++ b/2020/rust/day10/src/main.rs @@ -0,0 +1,94 @@ +use anyhow::Result; +use std::collections::HashMap; +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<usize>> { + let f = File::open(filename)?; + let reader = BufReader::new(f); + + let values = reader.lines() + .map(|v| v?.parse::<usize>().map_err(anyhow::Error::new)).collect(); + + values +} + +fn part1(input: &[usize]) -> Option<usize> { + let mut sorted = input.to_vec(); + sorted.push(0); + sorted.sort(); + let max = sorted[sorted.len()-1]; + sorted.push(max+3); + let (_prev, count) = sorted.iter().fold((None, vec![0, 0, 0, 0]), |acc, jolt| { + let mut res = acc.1.clone(); + if let Some(prev) = acc.0 { + let diff = jolt - prev; + res[diff] += 1; + } + (Some(jolt), res) + }); + + Some(count[1] * count[3]) +} + +fn part2(input: &[usize]) -> Option<u128> { + let mut sorted = input.to_vec(); + sorted.push(0); + sorted.sort(); + let max = sorted[sorted.len()-1]; + sorted.push(max+3); + let mut paths: HashMap<usize, u128> = HashMap::new(); + paths.insert(max+3, 1); + sorted.iter().rev().fold(0, |_, elem| { + let count = (1..=3).map(|jump| { + let pos = *elem + jump; + if sorted.contains(&pos) { + paths.get(&pos).copied().unwrap_or(0) + } else { + 0 + } + }).sum(); + let lm = paths.entry(*elem).or_insert(0); + *lm += count; + count + }); + + Some(paths[&0]) +} + +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: {}", solution), + None => { + eprintln!("Part1, no solution found"); + std::process::exit(1); + } + }; + } + if do_part_2 { + match part2(&input) { + Some(solution) => println!("Part2: {}", solution), + None => { + eprintln!("Part2, no solution found"); + std::process::exit(1); + } + }; + } + }, + Err(err) => eprintln!("Could not read input: {}", err), + } +} |