From 5db6b005f990512544b5a81e01bd0b9e6037a482 Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 10 Dec 2020 10:56:13 +0100 Subject: [PATCH] Add 2020/10 --- 2020/inputs/day10 | 92 +++++++++++++++++++++++++++++++ 2020/src/bin/day10.rs | 125 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 2020/inputs/day10 create mode 100644 2020/src/bin/day10.rs diff --git a/2020/inputs/day10 b/2020/inputs/day10 new file mode 100644 index 0000000..fc15d97 --- /dev/null +++ b/2020/inputs/day10 @@ -0,0 +1,92 @@ +76 +51 +117 +97 +7 +77 +63 +18 +137 +10 +23 +14 +130 +131 +8 +91 +17 +29 +2 +36 +110 +35 +113 +30 +112 +61 +83 +122 +28 +75 +124 +82 +101 +135 +42 +44 +128 +32 +55 +85 +119 +114 +72 +111 +107 +123 +54 +3 +98 +96 +11 +62 +22 +49 +37 +1 +104 +43 +24 +31 +129 +69 +4 +21 +48 +39 +9 +38 +58 +125 +81 +89 +65 +90 +118 +64 +25 +138 +16 +78 +92 +102 +88 +95 +132 +47 +50 +15 +68 +84 +136 +103 diff --git a/2020/src/bin/day10.rs b/2020/src/bin/day10.rs new file mode 100644 index 0000000..b2ebe98 --- /dev/null +++ b/2020/src/bin/day10.rs @@ -0,0 +1,125 @@ +#![feature(test)] +extern crate test; +use std::{env, iter}; + +use itertools::Itertools; + +type Parsed = Vec; + +fn read_input() -> String { + std::fs::read_to_string( + env::args() + .nth(1) + .filter(|n| n != "--bench") + .unwrap_or(String::from("inputs/day10")), + ) + .unwrap() +} + +fn parse_input(raw: &str) -> Parsed { + let mut xs: Vec = raw.lines().map(|l| l.parse().unwrap()).collect(); + // faster than using sorted() directly on the iterator + xs.sort_unstable(); + xs +} + +fn part1(input: &Parsed) -> (usize, usize) { + iter::once(&0) + .chain(input.iter()) + .tuple_windows() + .fold((0, 1), |(one, three), (a, b)| match b - a { + 1 => (one + 1, three), + 2 => (one, three), + 3 => (one, three + 1), + _ => unreachable!(), + }) +} + +fn part2(input: &Parsed) -> usize { + let max = *input.last().unwrap(); + let mut paths = vec![0; max + 4]; + paths[max] = 1; + for i in input.iter().rev().skip(1) { + let mut n = 0; + for j in 1..=3 { + n += paths[i + j]; + } + paths[*i] = n; + } + paths[1] + paths[2] + paths[3] +} + +fn main() { + let input = parse_input(&read_input()); + let (ones, threes) = part1(&input); + println!("Part 1: {}", ones * threes); + println!("Part 2: {}", part2(&input)); +} + +#[cfg(test)] +mod tests { + use super::*; + use test::black_box; + + const TEST_INPUT: &str = "28 +33 +18 +42 +31 +14 +46 +20 +48 +47 +24 +23 +49 +45 +19 +38 +39 +11 +1 +32 +25 +35 +8 +17 +7 +9 +4 +2 +34 +10 +3"; + + #[test] + fn part1_test() { + let input = parse_input(TEST_INPUT); + assert_eq!(part1(&input), (22, 10)); + } + + #[test] + fn part2_test() { + let input = parse_input(TEST_INPUT); + assert_eq!(part2(&input), 19208); + } + + #[bench] + fn bench_input_parsing(b: &mut test::Bencher) { + let raw = read_input(); + b.iter(|| parse_input(black_box(&raw))) + } + + #[bench] + fn bench_part1(b: &mut test::Bencher) { + let input = parse_input(&read_input()); + b.iter(|| assert_eq!(part1(black_box(&input)), (69, 24))); + } + + #[bench] + fn bench_part2(b: &mut test::Bencher) { + let input = parse_input(&read_input()); + b.iter(|| assert_eq!(part2(black_box(&input)), 56693912375296)); + } +}