kwando

kwando

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

Showing Posts 1 to 2

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:

stevensonmt

stevensonmt

Still going to try and work through as many days as I can. Very frustrated that I got stuck on a stupid input parsing error for so long on day 17 as this day was actually pretty straight forward. Going to look through other solutions to see how part two was handled as the method I took is pretty inefficient.
https://github.com/stevensonmt/advent_of_code/blob/2022/2022/day18/lib/day18.ex

@kwando looking at your solution is really nice but I don’t understand how you account for air that is within the overall structure of the droplet but has a connection to outside the droplet. I had initially tried a similar approach but got the wrong answer b/c some air pockets were only partially enclosed. How does collect_connected/3 avoid that?

— All posts loaded —

Where Next? Top

Trending in Challenges Top

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews