diff --git a/input/2020/day10.txt b/input/2020/day10.txt new file mode 100644 index 0000000..90bde44 --- /dev/null +++ b/input/2020/day10.txt @@ -0,0 +1,96 @@ +70 +102 +148 +9 +99 +63 +40 +52 +91 +39 +55 +28 +54 +22 +95 +61 +118 +35 +14 +21 +129 +82 +137 +45 +7 +87 +81 +25 +3 +108 +41 +11 +145 +18 +65 +80 +115 +29 +136 +42 +97 +104 +117 +141 +62 +121 +23 +96 +24 +128 +48 +1 +112 +8 +34 +144 +134 +116 +58 +147 +51 +84 +17 +126 +64 +68 +135 +10 +77 +105 +127 +73 +111 +90 +16 +103 +109 +98 +146 +123 +130 +69 +133 +110 +30 +122 +15 +74 +33 +38 +83 +92 +2 +53 +140 +4 diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..617dcf0 --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,72 @@ +use aoc_runner_derive::aoc; + +#[derive(Debug,Copy,Clone,PartialEq,Eq,PartialOrd,Ord)] +struct Jolts(usize); +impl std::ops::Add for Jolts { + type Output = Jolts; + fn add(self, b: Jolts) -> Jolts { + Jolts(self.0 + b.0) + } +} +impl std::ops::Sub for Jolts { + type Output = Jolts; + fn sub(self, b: Jolts) -> Jolts { + Jolts(self.0 - b.0) + } +} + +#[aoc(day10, part1)] +pub fn solve_d10_p1(input: &str) -> usize { + let jolts = { + let mut jolts: Vec = std::iter::once(Jolts(0)) + .chain(input.split('\n').map(|x| Jolts(x.parse().unwrap()))) + .collect(); + jolts.sort(); + jolts.push(*jolts.last().unwrap() + Jolts(3)); // The devices built-in adapter is always 3 more than the highest. + jolts + }; + + // Count the number of 1-jolt differences and 3-jolt differences in the + // chain. + let (j1_diff, j3_diff) = + jolts + .windows(2) + .fold((0, 0), |(j1_diff, j3_diff), entry| match entry { + &[a, b] if b - a == Jolts(1) => (j1_diff + 1, j3_diff), + &[a, b] if b - a == Jolts(3) => (j1_diff, j3_diff + 1), + _ => panic!("fail"), + }); + j1_diff * j3_diff +} + +#[aoc(day10, part2)] +pub fn solve_d10_p2(input: &str) -> usize { + let jolts = { + let mut jolts: Vec = std::iter::once(Jolts(0)) + .chain(input.split('\n').map(|x| Jolts(x.parse().unwrap()))) + .collect(); + jolts.sort(); + jolts.push(*jolts.last().unwrap() + Jolts(3)); // The devices built-in adapter is always 3 more than the highest. + jolts + }; + + // Iterate over the list of jolt value for the adapters. For each entry + // store the number of combinations this adapter has that lead back to zero + // in `combinations_count` + // To calculate the number of combinations the current adapter has you first + // determine which are the potential upstream adapters and then sum their + // combinations. + let mut combinations_count = Vec::with_capacity(jolts.len()); + combinations_count.push(1); + for (idx, current_jolts) in jolts.iter().copied().enumerate().skip(1) { + let mut adapter_paths_to_zero = 0; + + for upstream_idx in idx.saturating_sub(3) .. idx { + if current_jolts - jolts[upstream_idx] <= Jolts(3) { + adapter_paths_to_zero += combinations_count[upstream_idx]; + } + } + combinations_count.push(adapter_paths_to_zero); + } + *combinations_count.last().unwrap() +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c80140b..f61e4e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,5 +7,6 @@ pub mod day6; pub mod day7; pub mod day8; pub mod day9; +pub mod day10; aoc_runner_derive::aoc_lib! { year = 2020 }