Powered by AppSignal & Oban Pro

Day 2: Dive!

2021/day_02_dive.livemd

Day 2: Dive!

Setup

Mix.install([:kino, :nx])

input = Kino.Input.textarea("Please paste your input:")
inputs =
  input
  |> Kino.Input.read()
  |> String.split("\n", trim: true)
  |> Enum.map(fn input ->
    [direction, n_string] =
      input
      |> String.split()

    [direction, _n = String.to_integer(n_string)]
  end)

Part 1

https://adventofcode.com/2021/day/2

Solve: Part 1

{horizontal_position, depth} =
  inputs
  |> Enum.reduce({0, 0}, fn [direction, n], {horizontal_position, depth} ->
    case direction do
      "forward" -> {horizontal_position + n, depth}
      "down" -> {horizontal_position, depth + n}
      "up" -> {horizontal_position, depth - n}
    end
  end)

_answer = horizontal_position * depth

Solve: Part 1 - Nx

https://github.com/josevalim/aoc/blob/main/2021/day-02.livemd

defmodule Day2.Part1.Nx do
  import Nx.Defn

  defn run(tensor) do
    {length, _} = Nx.shape(tensor)

    {_, horizontal_position, depth, _} =
      while {i = 0, horizontal_position = 0, depth = 0, tensor}, i < length do
        direction = tensor[i][0]
        n = tensor[i][1]

        {next_horizontal_position, next_depth} =
          cond do
            direction == 0 -> {horizontal_position + n, depth}
            direction == 1 -> {horizontal_position, depth + n}
            direction == 2 -> {horizontal_position, depth - n}
            true -> {horizontal_position, depth}
          end

        {i + 1, next_horizontal_position, next_depth, tensor}
      end

    horizontal_position * depth
  end
end

inputs
|> Enum.map(fn [direction, n] ->
  direction_num =
    case direction do
      "forward" -> 0
      "down" -> 1
      "up" -> 2
    end

  [direction_num, n]
end)
|> Nx.tensor()
|> Day2.Part1.Nx.run()
|> Nx.to_number()

Part 2

https://adventofcode.com/2021/day/2#part2

Solve: Part 2

{horizontal_position, depth, _aim} =
  inputs
  |> Enum.reduce({0, 0, 0}, fn [direction, n], {horizontal_position, depth, aim} ->
    case direction do
      "forward" -> {horizontal_position + n, depth + aim * n, aim}
      "down" -> {horizontal_position, depth, aim + n}
      "up" -> {horizontal_position, depth, aim - n}
    end
  end)

_answer = horizontal_position * depth