rugyoga

rugyoga

Advent of Code 2024 - Day 8

27 lines

Most Liked

billylanchantin

billylanchantin

The grid ones are tricky to golf.

LOC: 23

defmodule Aoc2024.Day08 do
  import Enum

  def part1(file), do: main(file, 1..1)
  def part2(file), do: main(file)

  def main(file, range \\ nil) do
    {grid, n} = file_to_charmap_grid(file)

    for {{x1, y1}, z1} <- grid, {{x2, y2}, z2} <- grid, z1 == z2, z1 != ?., x1 < x2 do
      map(range || -n..n, fn m -> {m * (x2 - x1), m * (y2 - y1)} end)
      |> flat_map(fn {dx, dy} -> [[x1 - dx, y1 - dy], [x2 + dx, y2 + dy]] end)
      |> filter(fn coor -> all?(coor, &(&1 in 0..(n - 1))) end)
    end
    |> reduce(MapSet.new(), &MapSet.union(&2, MapSet.new(&1)))
    |> MapSet.size()
  end

  def file_to_charmap_grid(f) do
    r = f |> File.read!() |> String.trim() |> String.split("\n") |> map(&String.to_charlist/1)
    {for({s, i} <- with_index(r), {x, j} <- with_index(s), into: %{}, do: {{i, j}, x}), length(r)}
  end
end

This one made me wish I could reach for the extra comprehension powers hinted at in the for let proposal.

sevenseacat

sevenseacat

Author of Ash Framework

There’s always previous year puzzles to do, if you haven’t done those!

https://everybody.codes/ is anothe one that popped up last month for more puzzley goodness

bjorng

bjorng

Erlang Core Team

I used Enum.dedup/1 instead of Enum.uniq/1 when attempting to solve part 1. This mistake hid another bug, and so I got the correct result for the example but not for my input.

The following solution is refactored to share most of the code for the solution:

adamu

adamu

Pretty tame after Friday’s loop detection, I was expecting worse for Sunday (although I took a break yesterday so I’m not sure how that was).

Each part completes in under a millisecond.

def calc_resonant_harmonics({{x_a, y_a}, {x_b, y_b}}, max_x, max_y) do
  dx = x_a - x_b
  dy = y_a - y_b

  [{x_a, y_a}, {x_b, y_b}] ++
    resonate(x_a, y_a, dx, dy, max_x, max_y) ++
    resonate(x_b, y_b, dx * -1, dy * -1, max_x, max_y)
end

def resonate(x, y, dx, dy, max_x, max_y, multiplier \\ 1) do
  next_x = x + dx * multiplier
  next_y = y + dy * multiplier

  if next_x < 0 or next_x >= max_x or next_y < 0 or next_y >= max_y do
    []
  else
    [{next_x, next_y} | resonate(x, y, dx, dy, max_x, max_y, multiplier + 1)]
  end
end
lud

lud

Sundays are supposed to be harder but today was quite easy:)

defmodule AdventOfCode.Solutions.Y24.Day08 do
  alias AdventOfCode.Grid
  alias AoC.Input

  def parse(input, _part) do
    {_grid, _bounds} =
      input
      |> Input.stream!()
      |> Grid.parse_lines(fn
        _, ?. -> :ignore
        _, ?\n -> raise "parses new line"
        _, c -> {:ok, c}
      end)
  end

  def part_one({grid, bounds}) do
    for({xy_l, l} <- grid, {xy_r, r} <- grid, l == r, xy_l < xy_r, do: antinodes_p1(xy_l, xy_r))
    |> :lists.flatten()
    |> Enum.uniq()
    |> Enum.filter(&in_bounds?(&1, bounds))
    |> length()
  end

  defp antinodes_p1({xl, yl}, {xr, yr}) do
    x_diff = xr - xl
    y_diff = yr - yl

    [
      # Lower node
      {xl - x_diff, yl - y_diff},

      # Higher node
      {xr + x_diff, yr + y_diff}
    ]
  end

  defp in_bounds?({x, y}, {xa, xo, ya, yo}) do
    x >= xa and x <= xo and
      y >= ya and y <= yo
  end

  def part_two({grid, bounds}) do
    for(
      {xy_l, l} <- grid,
      {xy_r, r} <- grid,
      l == r,
      xy_l < xy_r,
      do: antinodes_p2(xy_l, xy_r, bounds)
    )
    |> :lists.flatten()
    |> Enum.uniq()
    |> length()
  end

  defp antinodes_p2({xl, yl}, {xr, yr}, bounds) do
    x_diff = xr - xl
    y_diff = yr - yl

    higher =
      {xr, yr}
      |> Stream.iterate(fn {x, y} -> {x + x_diff, y + y_diff} end)
      |> Enum.take_while(&in_bounds?(&1, bounds))

    lower =
      {xl, yl}
      |> Stream.iterate(fn {x, y} -> {x - x_diff, y - y_diff} end)
      |> Enum.take_while(&in_bounds?(&1, bounds))

    [higher, lower]
  end
end

No optimization at all :slight_smile: its under 1ms as well.

Where Next?

Popular in Challenges Top

ehayun
I have 2 arrays: a1 can be any combination of value or nil like that a1 = [1,nil,3] and array 2 the same a2 = [4,2, nil] How do I com...
New
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
kwando
Phew, this one took a while to get right. My naive attempts was way to slow so I reached for Dijkstras shortest path algorithm… and that ...
New
groovyda
Today’s challenge for me was about using reduce: defmodule Prob5 do def move([[h1 | rest] = _list1, list2]) do [rest, [h1 | list2]...
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
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New
New
Aetherus
This topic is about Day 16 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
kwando
Took a while, but another use case for “move vectors” today and pattern matching. :slight_smile: The trick was to first generate a list...
New
rvnash
Anyone have a solution to Part 2 today? Part 1 was straight forward, but I can’t figure out a programatic way to do part 2. I understand ...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
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