bjorng
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
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
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
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
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
Here is my solution:
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







