kwando

kwando

Advent of Code 2022 - Day 18

Today was fun and I got it right the first time :slight_smile: MapSets saves the day again.
https://github.com/kwando/AoC2022/blob/main/18/day18.livemd

First Post!

lud

lud

A slightly different take on the same general idea:

defmodule Aoe.Y22.Day18 do
  alias Aoe.Input, warn: false

  def read_file!(file, _part) do
    Input.stream_file_lines(file, trim: true)
  end

  def parse_input!(input, _part) do
    input |> Enum.map(&parse_line/1)
  end

  defp parse_line(line) do
    [x, y, z] = line |> String.split(",") |> Enum.map(&String.to_integer/1)
    {x, y, z}
  end

  def part_one(cube_list) do
    lookup_map = Map.new(cube_list, &{&1, true})

    surf_map =
      Enum.reduce(cube_list, %{}, fn cube, surf_map ->
        Map.put(surf_map, cube, n_uncovered(cube, lookup_map))
      end)

    surf_map |> Map.values() |> Enum.sum()
  end

  def part_two(cube_list) do
    lookup_map = Map.new(cube_list, &{&1, true})

    xl = Enum.reduce(cube_list, &min_x/2) - 1
    yl = Enum.reduce(cube_list, &min_y/2) - 1
    zl = Enum.reduce(cube_list, &min_z/2) - 1

    xh = Enum.reduce(cube_list, &max_x/2) + 1
    yh = Enum.reduce(cube_list, &max_y/2) + 1
    zh = Enum.reduce(cube_list, &max_z/2) + 1

    path_start = {xl, yl, zl}
    max_range = {xh, yh, zh}

    explored = explore([path_start], {path_start, max_range}, lookup_map, %{})

    explored |> Map.values() |> Enum.sum()
  end

  defp explore([cur | open], minmax, lookup_map, explored) do
    {lava_neighs, free_neighs} = split_neighs(cur, lookup_map, minmax)
    faces = length(lava_neighs)
    explored = Map.put(explored, cur, faces)
    free_neighs = Enum.filter(free_neighs, &(&1 not in open and not Map.has_key?(explored, &1)))
    explore(free_neighs ++ open, minmax, lookup_map, explored)
  end

  defp explore([], _, _, explored) do
    explored
  end

  defp split_neighs(cube, lookup_map, minmax) do
    neighs = cardinal_neighbours(cube)
    {lava_neighs, free_neighs} = Enum.split_with(neighs, &Map.has_key?(lookup_map, &1))
    free_neighs = clamp_neighs(free_neighs, minmax)
    {lava_neighs, free_neighs}
  end

  defp clamp_neighs(cubes, minmax) do
    Enum.filter(cubes, &in_boundary(&1, minmax))
  end

  defp in_boundary({x, y, z}, {{xl, yl, zl}, {xh, yh, zh}}) do
    x >= xl and x <= xh and
      y >= yl and y <= yh and
      z >= zl and z <= zh
  end

  defp n_uncovered(cube, lookup_map) do
    cube |> cardinal_neighbours() |> Enum.reject(&Map.has_key?(lookup_map, &1)) |> Enum.count()
  end

  defp cardinal_neighbours({x, y, z}) do
    [
      {x - 1, y, z},
      {x + 1, y, z},
      {x, y - 1, z},
      {x, y + 1, z},
      {x, y, z - 1},
      {x, y, z + 1}
    ]
  end

  defp max_x({a, _, _}, {b, _, _}), do: max(a, b)
  defp max_x({a, _, _}, b) when is_integer(b), do: max(a, b)
  defp min_x({a, _, _}, {b, _, _}), do: min(a, b)
  defp min_x({a, _, _}, b) when is_integer(b), do: min(a, b)
  defp max_y({_, a, _}, {_, b, _}), do: max(a, b)
  defp max_y({_, a, _}, b) when is_integer(b), do: max(a, b)
  defp min_y({_, a, _}, {_, b, _}), do: min(a, b)
  defp min_y({_, a, _}, b) when is_integer(b), do: min(a, b)
  defp max_z({_, _, a}, {_, _, b}), do: max(a, b)
  defp max_z({_, _, a}, b) when is_integer(b), do: max(a, b)
  defp min_z({_, _, a}, {_, _, b}), do: min(a, b)
  defp min_z({_, _, a}, b) when is_integer(b), do: min(a, b)
end

Quick and fun today :smiley:

Where Next?

Popular in Challenges Top

adamu
I said I was on a break, but I took a sneak peak and it looked fun so… Part 1 completes in half a millisecond with a single pass of the ...
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
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
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
bjorng
This topic is about Day 5 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums ): https://adve...
New
rugyoga
part 1: https://github.com/rugyoga/aoc2021/blob/main/day8.exs part 2: https://github.com/rugyoga/aoc2021/blob/main/day8b.exs
New
bjorng
Note: This topic is to talk about Day 5 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
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
connorlay
Note by the Moderators: This topic is for general discussion about the Advent of Code 2018. To prevent people from being spoiled about s...
New
bjorng
Note: This topic is to talk about Day 9 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New

Other popular topics Top

New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
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
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
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
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement