# til /advent of code 2021: day 1 - sonar sweep

It’s that time of year, Advent of Code is here! Advent of Code is an advent calendar of programming puzzles. It’s been held from December 1st to December 25th since 2015.

Last year I did the solutions using Rust and had such a great time doing them that I’m going to use Rust again this year. This year, if I got the time for it, I’ll also try to do a post about my solution each day. My hope is that it might help someone and make me retain the solution better. A bit of Learning in public.

## Part 1 #

The puzzles usually start out simple and get harder as we get closer to Christmas. The first solution was straight-forward. We’re given a list of integers and told to find how many times the value increases between each step.

`````` 1// I'm using cargo-aoc to set up boilerplate and handle inputs
2#[aoc(day1, part1)]
3pub fn solve_part_01(input: &[u32]) -> u32 {
4    // Create a value for number of increases
5    let mut increases = 0;
6    // Use the first value from our input data as the initial value
7    let mut previous_value = input;
8
9    for i in input {
10        // Add one to increases if the current value
11        // is bigger than the last value
12        if i > &previous_value {
13            increases += 1
14        }
15
16        // Update the last value
17        // *i dereferences i. This means that we are
18        // getting the actual value. This is needed since the
19        // loop returns a reference to i (&i)
20        previous_value = *i
21    }
22
23    // Return the number of increases
24    increases
25}
``````

This was my fastest solve ever with a time of `04:17` putting me at rank 2376. My previous fastest time was 11 minutes (last year), albeit with a better rank.

## Part 2 #

The second part of each puzzle always builds on or slightly alters the solution of part 1. This time we’re told to compare sums of a three-measurement sliding window instead of each single entry.

We’re given the hint to use “sliding window” which is a technique that can help reduce the amount of time a calculation takes by making it run in linear, or close to, time. Or in other words, using one loop instead of nested loops. To learn more about sliding windows read this great article.

Luckily for us Rust has a built-in windows() method for slices.

`````` 1#[aoc(day1, part2)]
2pub fn solve_part_02(input: &[u32]) -> u32 {
3    // Set the initial value to the sum of the first
4    // window, i.e. sum of the first three values
5    let mut previous_sum: u32 = input.windows(3).next().unwrap().iter().sum();
6    let mut increases = 0;
7
8    // Loop over the windows with three values in each window
9    for i in input.windows(3) {
10        // Sum the values
11        let new_sum = i.iter().sum();
12
13        // Add one to increases if the new sum
14        // is larger than the last
15        if new_sum > previous_sum {
16            increases += 1;
17        }
18
19        // Update the last sum
20        previous_sum = new_sum;
21    }
22
23    // Return the number of increases
24    increases
25}
``````

## Performance #

For fun I benchmark my solutions. It’s also hilarious to see how fast Rust is. Benchmarking comes included with cargo-aoc which means there’s no hassle to do it either, just run `cargo aoc bench`.

Part Time
1 272.11 ns (that’s nanoseconds, 10^-9)
2 923.48 ns