bjorng

bjorng

Erlang Core Team

Advent of Code 2021 - Day 2

This topic is about Day 2 of the Advent of Code 2021.

We have a private leaderboard (shared with users of Erlang Forums):

https://adventofcode.com/2021/leaderboard/private/view/370884

The entry code is:
370884-a6a71927

Most Liked

mudasobwa

mudasobwa

Creator of Cure

I wonder why nearly all the solutions do String.split/2 when we can directly pattern-match strings

  defp d2_destination_reducer("forward " <> value, acc),
    do: %{acc | h: acc.h + String.to_integer(value)}

  defp d2_destination_reducer("down " <> value, acc),
    do: %{acc | v: acc.v + String.to_integer(value)}

  defp d2_destination_reducer("up " <> value, acc),
    do: %{acc | v: acc.v - String.to_integer(value)}

  defp d2_destination_reducer(_, acc), do: acc
code-shoily

code-shoily

In Part 1, you could’ve used Tuple.product and get rid of that then ? I was contemplating on representing my data structure as tuple only so that I could use Tuple.product - one of my favourite functions :smiley: but since I was in a noisy room, I made the representation more verbose so I don’t mentally keep track of the which position means what.

Clever way to represent the positions though!

hauleth

hauleth

My LiveBook:


Day 2

Load input

We do parsing there, as it will help us with the latter tasks. Pattern matching
is the simplest approach there, as input is in form of:

forward 10
up 20
down 30

We need to trim/1 input to make sure that the last newline will not interrupt
String.to_integer/1 calls.

stream =
  File.stream!("day2.txt")
  |> Stream.map(fn input ->
    case String.trim(input) do
      "forward " <> n -> {:forward, String.to_integer(n)}
      "up " <> n -> {:up, String.to_integer(n)}
      "down " <> n -> {:down, String.to_integer(n)}
    end
  end)

Task 1

{h, d} =
  stream
  |> Enum.reduce({0, 0}, fn
    {:forward, n}, {h, d} -> {h + n, d}
    {:up, n}, {h, d} -> {h, d - n}
    {:down, n}, {h, d} -> {h, d + n}
  end)

h * d

Task 2

{h, d, _} =
  stream
  |> Enum.reduce({0, 0, 0}, fn
    {:forward, n}, {h, d, a} -> {h + n, d + a * n, a}
    {:up, n}, {h, d, a} -> {h, d, a - n}
    {:down, n}, {h, d, a} -> {h, d, a + n}
  end)

h * d
bjorng

bjorng

Erlang Core Team

Here is my solution:

code-shoily

code-shoily

This one wasn’t as fun as the day 1 one for me.

defmodule AdventOfCode.Y2021.Day02 do
  @moduledoc """
  --- Day 2: Dive! ---
  Problem Link: https://adventofcode.com/2021/day/2
  """
  use AdventOfCode.Helpers.InputReader, year: 2021, day: 2

  def run_1, do: input!() |> parse() |> track_positions() |> then(& &1.depth * &1.horizontal)
  def run_2, do: input!() |> parse() |> track_aims() |> then(& &1.depth * &1.horizontal)

  def parse(data) do
    data
    |> String.split("\n")
    |> Enum.map(fn line ->
      [direction, value] = String.split(line, " ")
      {String.to_existing_atom(direction), String.to_integer(value)}
    end)
  end

  defp track_positions(directions) do
    directions
    |> Enum.reduce(%{horizontal: 0, depth: 0}, fn
      {:forward, v}, %{horizontal: horizontal} = acc -> %{acc | horizontal: horizontal + v}
      {:backward, v}, %{horizontal: horizontal} = acc -> %{acc | horizontal: horizontal - v}
      {:up, v}, %{depth: depth} = acc -> %{acc | depth: depth - v}
      {:down, v}, %{depth: depth} = acc -> %{acc | depth: depth + v}
    end)
  end

  defp track_aims(directions) do
    directions
    |> Enum.reduce(%{horizontal: 0, depth: 0, aim: 0}, fn
      {:forward, v}, %{horizontal: horizontal, depth: depth, aim: aim} = acc ->
        %{acc | horizontal: horizontal + v, depth: depth + aim * v}

      {:backward, v}, %{horizontal: horizontal} = acc ->
        %{acc | horizontal: horizontal - v}

      {:up, v}, %{aim: aim} = acc ->
        %{acc | aim: aim - v}

      {:down, v}, %{aim: aim} = acc ->
        %{acc | aim: aim + v}
    end)
  end
end

Where Next?

Popular in Challenges Top

sneako
Note by the Moderators: This topic is to talk about the first day of the Advent of Code. For general discussion about the Advent of Code...
New
sukhmeetsd
All in all, from what I understand, it is better not to use GenServer.cast when we want some concurrent operations to happen for sure, be...
New
bjorng
Note: This topic is to talk about Day 3 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can jo...
New
Aetherus
The second part of today’s puzzle is very misleading. FYI, each of the ghosts has only one possible position that ends with a "Z" on its...
New
jkwchui
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
New
New
bjorng
Note: This topic is to talk about Day 18 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
bjorng
Here is my solution for day 1 of Advent of Code: defmodule Day01 do def part1(input) do all = parse(input) {first, second} = E...
New
bjorng
This topic is about Day 10 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums ): https://adv...
New
igorb
So… that’s it? Everyone is stuck on part 2? :slight_smile: I looked at Reddit hints and thought I probably wouldn’t have come up with the...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement