bjorng

bjorng

Erlang Core Team

Advent of Code 2021 - Day 5

This topic is about Day 5 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

epilgrim

epilgrim

maybe you will like my way of parsing the input?

      File.read!("day_5.txt")
      |> String.split(["\n", ",", " -> "], trim: true)
      |> Enum.map(&String.to_integer/1)
      |> Enum.chunk_every(4)
      |> Enum.map(&List.to_tuple/1)

We can split the file in all the special content we have, and then just take numbers 4 at a time. No need to nest anything

epilgrim

epilgrim

My solution

Today was significatively simpler than yesterday, but I had to remember my vector algebra :slight_smile:
To calculate the intermediate points, I used:

  def fill_points({x1,y1,x2,y2}) do
    {dx, dy} = {x2 - x1, y2 - y1}
    slope = {step(dx), step(dy)}
    do_fill({x1, y1}, {x2, y2}, slope, [])
  end

  defp step(0), do: 0
  defp step(x) when x > 0, do: 1
  defp step(x) when x < 0, do: -1

  defp do_fill(point, point, _slope, acc) do
    [point | acc]
  end

  defp do_fill({x1, y1} = point, end_point, {dx, dy} = slope, acc) do
    new_point = {x1 + dx, y1 + dy}
    do_fill(new_point, end_point, slope, [point | acc])
  end
ruslandoga

ruslandoga

IO.puts would work, I think:

iex(5)> input = "1.1...11.\n.111...2...\n...2.1.111.\n...1.2.2...\n.112313211\n...1.2...\n...1...1...\n.1...1...\n1...1.\n222111..."
iex(6)> IO.puts input
1.1...11.
.111...2...
...2.1.111.
...1.2.2...
.112313211
...1.2...
...1...1...
.1...1...
1...1.
222111...
qhwa

qhwa

Here’s my take:

defmodule Y2021.Day05 do
  def p1 do
    AOC.Input.stream("2021/day05.txt", &parse_seg/1)
    |> Stream.filter(fn [x1, y1, x2, y2] -> x1 == x2 || y1 == y2 end)
    |> count_overlap()
  end

  def p2 do
    AOC.Input.stream("2021/day05.txt", &parse_seg/1)
    |> count_overlap()
  end

  defp parse_seg(line) do
    Regex.run(~r/(\d+),(\d+) -> (\d+),(\d+)/, line, capture: :all_but_first)
    |> Enum.map(&String.to_integer/1)
  end

  defp count_overlap(segs) do
    segs
    |> Stream.flat_map(fn [x1, y1, x2, y2] ->
      max_step = max(abs(x2 - x1), abs(y2 - y1))
      dx = div(x2 - x1, max_step)
      dy = div(y2 - y1, max_step)

      Stream.iterate({x1, y1}, fn {x, y} -> {x + dx, y + dy} end)
      |> Stream.take(max_step + 1)
      |> Enum.to_list()
    end)
    |> Enum.frequencies()
    |> Enum.count(fn {_, count} -> count > 1 end)
  end
end

full file

Klohto

Klohto

Wow, today was an absolute breeze (looking at you Day 4…)

  • Learned about pairing Stream.cycle with Enum.zip
  • Had to switch from Livebook native input (looks like it’s deprecated at edge) to Kino input
  • Pattern matching makes this easy
  • Just expanded all coordinates and counted frequencies bigger than 1
# Day 4

## Deps & preparation

```elixir
Mix.install([
  {:kino, "~> 0.4.0"}
])

input = Kino.Input.textarea("Please paste your input file:")
```

## Input

```elixir
coordinates =
  Kino.Input.read(input)
  |> String.split(["\n", ",", " -> "], trim: true)
  |> Enum.map(&String.to_integer/1)
  |> Enum.chunk_every(4)
```

## Part 1

```elixir
coordinates
|> Enum.reduce(
  [],
  fn
    [x, y, x1, y1], map when y == y1 ->
      Enum.zip(x..x1, Stream.cycle([y])) ++ map

    [x, y, x1, y1], map when x == x1 ->
      Enum.zip(Stream.cycle([x]), y..y1) ++ map

    _, map ->
      map
  end
)
|> Enum.frequencies()
|> Enum.count(fn {_k, v} -> v > 1 end)
```

## Part 2

```elixir
coordinates
|> Enum.reduce(
  [],
  fn
    [x, y, x1, y1], map when y == y1 ->
      Enum.zip(x..x1, Stream.cycle([y])) ++ map

    [x, y, x1, y1], map when x == x1 ->
      Enum.zip(Stream.cycle([x]), y..y1) ++ map

    [x, y, x1, y1], map ->
      Enum.zip(x..x1, y..y1) ++ map
  end
)
|> Enum.frequencies()
|> Enum.count(fn {_k, v} -> v > 1 end)
```

EDIT: Updated with @epilgrim split approach, thanks!

Where Next?

Popular in Challenges Top

Aetherus
I tried to use combinatorial to solve today’s puzzles but failed (my brain burned out :exploding_head:). In the end I just used brute for...
New
Aetherus
This topic is about the Advent of Code 2021 - Day 4. Thanks to @bjorng , we now have a new Private Leaderboard. The entry code is: 370...
New
sasajuric
Note by the Moderators: This topic is to talk about Day 5 of the Advent of Code. For general discussion about the Advent of Code 2018 an...
New
lud
At first I was scared but I found is a simple way to compute the sides. defmodule AdventOfCode.Solutions.Y24.Day12 do alias AdventOfCo...
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
Aetherus
Hello, guys. I’m back again, but only for the weekends, maybe. This topic is about Day 13 of the Advent of Code 2020 . Thanks to @egze,...
New
adamu
Probably not the most efficient implementation, because part 1 took &gt;1 ms and part 2 &gt;4ms, but the code was simple enough. def p...
New
Qqwy
Note by the Moderators: This topic is to talk about Day 6 of the Advent of Code. For general discussion about the Advent of Code 2018 an...
New
mattbaker
I’m having so much fun working on the “Protohackers” challenges, I never got into Advent of Code much but this has been amazing. The chal...
New
coen.bakker
Since I started using Elixir, I have benefited greatly from being able to study various open-source projects. The codebase of LiveBook, i...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
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