Powered by AppSignal & Oban Pro

Day 1 - Sonar Sweep

2021/day-01.livemd

Day 1 - Sonar Sweep

Puzzle 1

Puzzle 1

Given a sequence of sonar measurements (integers), count the number of measurements that are larger than the previous one.

As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.

For example, suppose you had the following report:

199
200
208
210
200
207
240
269
260
263

This report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on.

The first order of business is to figure out how quickly the depth increases, just so you know what you’re dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.

To do this, count the number of times a depth measurement increases from the previous measurement.

In this example, there are 7 measurements that are larger than the previous measurement.

raw_input = File.read!("./input-01.txt")
samples = [199, 200, 208, 210, 200, 207, 240, 269, 260, 263]

measurements =
  raw_input
  |> String.split("\n")
  |> Enum.map(&String.trim/1)
  |> Enum.filter(&(&1 != ""))
  |> Enum.map(&String.to_integer/1)
{increases, _} =
  measurements
  |> Enum.reduce({0, 999_999}, fn current, {count, prev} ->
    if current > prev do
      {count + 1, current}
    else
      {count, current}
    end
  end)

Puzzle 2

This time, consider 3-day sliding windwows

199  A      
200  A B    
208  A B C  
210    B C D
200  E   C D
207  E F   D
240  E F G  
269    F G H
260      G H
263        H

Start by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased.

Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren’t enough measurements left to create a new three-measurement sum.

defmodule Puzzle2 do
  # NOTE: the 'window' is backwards so we can easily put the new item onto the head
  def increased?(measurement, prev_window) do
    case prev_window do
      [_c, _b, a] -> measurement > a
      _ -> false
    end
  end

  def next_window(measurement, prev_window) do
    case prev_window do
      [c, b, _a] -> [measurement, c, b]
      list -> [measurement | list]
    end
  end

  def reduce_window(measurement, {count, prev_window}) do
    new_count =
      if increased?(measurement, prev_window) do
        count + 1
      else
        count
      end

    {new_count, next_window(measurement, prev_window)}
  end
end

{increases, window} = Enum.reduce(measurements, {0, []}, &Puzzle2.reduce_window/2)