aoc/year2020/
day10.rs

1//! # Adapter Array
2//!
3//! Part one uses the [`windows`] function to iterate over all pairs counting the differences.
4//!
5//! Part two is a classic [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming)
6//! problem. The charging outlet can be arranged in exactly one way. Each subsequent adapter can be
7//! arranged in the sum of the number of ways that the adapters at -1, -2 and -3 jolts can be
8//! arranged.
9//!
10//! [`windows`]: slice::windows
11use crate::util::parse::*;
12
13pub fn parse(input: &str) -> Vec<usize> {
14    let mut adapters: Vec<_> = input.iter_unsigned().collect();
15    adapters.sort_unstable();
16    adapters
17}
18
19pub fn part1(input: &[usize]) -> usize {
20    let mut total = [0, 0, 0, 1];
21    total[input[0]] += 1;
22
23    for w in input.windows(2) {
24        let diff = w[0].abs_diff(w[1]);
25        total[diff] += 1;
26    }
27
28    total[1] * total[3]
29}
30
31pub fn part2(input: &[usize]) -> usize {
32    let last = input.last().unwrap();
33    let mut sum = vec![0; last + 1];
34    sum[0] = 1;
35
36    for &i in input {
37        match i {
38            1 => sum[i] = sum[i - 1],
39            2 => sum[i] = sum[i - 1] + sum[i - 2],
40            _ => sum[i] = sum[i - 1] + sum[i - 2] + sum[i - 3],
41        }
42    }
43
44    *sum.last().unwrap()
45}