Powered by AppSignal & Oban Pro

Day 18

2022/day18.livemd

Day 18

Mix.install([
  {:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
])
:ok

Section

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2022", "18", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
{:ok,
 "9,2,13\n12,12,4\n3,8,14\n9,3,4\n15,5,7\n9,5,4\n7,3,10\n12,8,2\n8,12,16\n12,16,12\n5,15,8\n16,7,12\n4,5,6\n11,7,2\n10,14,16\n9,3,15\n6,7,3\n14,10,15\n7,12,3\n13,8,3\n9,1,12\n7,15,5\n8,6,16\n17,9,12\n3,13,6\n7,2,10\n9,14,3\n16,12,6\n13,4,15\n17,14,11\n14,4,5\n15,4,14\n3,4,9\n13,12,17\n15,11,3\n12,14,3\n12,5,4\n16,5,12\n14,16,6\n4,3,11\n9,16,13\n10,6,3\n17,9,7\n5,5,14\n14,13,15\n16,12,8\n7,11,2\n14,9,4\n12,11,15\n13,7,4\n4,15,13\n9,13,2\n7,16,9\n17,13,6\n11,0,11\n15,4,11\n4,12,8\n13,3,13\n5,12,17\n16,14,9\n6,5,4\n9,17,8\n6,10,2\n3,10,7\n1,9,7\n5,14,12\n7,12,5\n3,5,10\n5,15,14\n6,3,11\n15,13,13\n7,4,5\n11,7,4\n11,16,12\n2,11,8\n7,15,4\n9,5,17\n12,14,4\n14,4,6\n7,8,2\n11,3,7\n15,13,7\n12,11,2\n11,6,16\n18,10,10\n4,12,5\n11,10,2\n7,17,9\n3,14,9\n7,17,5\n10,8,17\n10,1,11\n11,11,1\n16,8,14\n2,7,10\n7,9,17\n12,12,2\n11,17,11\n15,10,16\n9,1,8\n1,10,12\n6,2,11\n17,11,8\n9,2,11\n13,5,4\n2,9,11\n4,5,9\n8,3,5\n3,14,11\n3,13,12\n10,8,16\n12,14,16\n15,12,13\n5,3,12\n16,9,12\n1,10,10\n17,6,10\n10,18,8\n8,13,17\n13,7,2\n3,12,13\n2,12,5\n6,9,16\n3,6,9\n6,16,6\n0,9,9\n6,17,10\n15,10,14\n2,8,12\n13,3,8\n11,12,17\n9,17,11\n4,6,8\n15,11,2\n4,6,15\n11,4,12\n11,8,1\n7,1,10\n12,11,3\n18,11,12\n8,16,12\n1,9,11\n16,14,14\n15,8,5\n15,5,5\n6,10,17\n13,4,16\n8,12,2\n10,5,15\n4,11,16\n4,10,4\n12,10,3\n10,5,2\n5,15,7\n14,15,7\n16,10,5\n6,3,3\n12,17,10\n4,7,14\n6,4,12\n13,5,11\n7,15,6\n1,8,9\n4,11,15\n14,4,4\n2,13,8\n5,4,5\n4,13,13\n4,14,8\n17,12,11\n7,16,15\n16,13,11\n11,3,12\n17,9,8\n11,6,15\n11,15,16\n6,17,9\n17,6,8\n13,15,15\n10,17,8\n3,5,5\n3,9,14\n17,10,13\n16,9,13\n13,8,16\n12,5,3\n12,15,15\n5,10,14\n16,15,11\n7,2,9\n9,16,12\n2,14,9\n14,17,8\n13,16,8\n7,3,5\n5,3,10\n11,5,16\n17,10,10\n6,7,16\n1,12,10\n6,14,2\n7,2,12\n12,17,9\n17,6,12\n2,13,13\n8,4,3\n16,8,13\n3,15,7\n16,5,13\n16,13,12\n16,12,5\n16,5,9\n4,13,8\n9,13,17\n13,10,15\n4,6,4\n10,11,17\n13,14,5\n9,14,14\n11,2,7\n12,10,2\n12,18,10\n12,6,16\n17,11,6\n8,14,16\n10,15,3\n3,6,5\n7,10,17\n15,5,12\n16,11,14\n8,12,18\n15,13,9\n6,8,3\n15,12,2\n14,13,6\n15,4,10\n11,1,8\n10,1,6\n5,7,16\n9,7,2\n13,3,6\n8,2,7\n14,14,5\n9,3,13\n6,3,8\n8,5,4\n7,4,4\n10,14,15\n10,16,5\n16,11,10\n3,8,11\n4,13,15\n8,13,5\n10,4,5\n15,14,14\n13,12,16\n11,14,3\n11,17,8\n6,5,2\n15,15,13\n5,5,5\n14,9,2\n5,5,9\n3,7,13\n2,15,9\n15,15,7\n7,17,8\n11,8,2\n16,5,7\n9,16,7\n11,4,4\n7,5,15\n10,12,1\n7,4,14\n9,16,6\n15,10,9\n14,7,16\n7,15,15\n15,11,5\n8,4,14\n13,14,10\n10,12,2\n11,15,14\n13,13,3\n4,13,4\n8,8,17\n9,4,3\n13,5,3\n2,10,8\n6,16,9\n4,8,14\n7,2,11\n14,1,10\n17,8,7\n14,9,13\n14,6,6\n5,6,16\n4,13,10\n8,13,16\n16,9,15\n5,8,3\n18,9,10\n13,14,15\n14,4,13\n17,12,10\n17,7,7\n10,17,6\n16,10,14\n6,11,2\n16,10,10\n12,8,16\n12,13,18\n12,2,8\n17,8,9\n12,6,4\n13,17,10\n17,6,6\n15,8,15\n7,17,13\n4,15,11\n10,12,17\n2,7,11\n17,13,10\n5,12,4\n11,3,13\n5,11,4\n14,3,10\n11,4,14\n10,1,13\n5,6,6\n2,10,12\n5,8,15\n13,7,3\n12,7,4\n15,14,7\n5,7,13\n8,6,3\n9,6,16\n16,5,11\n15,13,15\n9,14,17\n15,14,13\n14,5,6\n2,7,6\n13,15,5\n4,11,5\n8,4,6\n14,14,15\n17,5,10\n5,9,3\n11,5,4\n5,9,13\n16,8,15\n11,11,17\n10,3,4\n14,5,16\n6,9,15\n9,14,16\n9,5,5\n5,15,13\n9,11,3\n7,6,4\n12,13,3\n2,13,7\n10,13,17\n10,17,10\n13,3,9\n14,4,8\n18,8,8\n4,12,7\n6,17,12\n9,9,1\n16,8,12\n12,3,6\n6,5,14\n4,14,12\n15,11,13\n5,4,15\n4,15,12\n5,14,5\n10,4,16\n12,6,2\n15,13,4\n8,15,4\n14,5,14\n16,10,12\n6,17,11\n17,15,10\n16,13,10\n16,12,14\n10,14,3\n11,12,1\n4,10,14\n10,2,15\n16,13,14\n6,14,5\n2,9,7\n12,9,2\n8,18,11\n13,12,2\n7,9,3\n8,16,15\n12,3,15\n9,16,11\n16,9,7\n6,15,7\n12,2,13\n5,12,16\n6,12,17\n12,1,10\n11,13,14\n9,8,18\n15,10,17\n7,13,16\n11,2,11\n10,11,2\n13,16,14\n8,15,14\n8,4,13\n7,7,2\n13,10,1\n7,3,12\n12,2,10\n10,17,11\n3,13,9\n5,10,13\n10,10,16\n6,14,6\n7,6,2\n13,12,4\n15,3,13\n4,3,12\n7,10,18\n4,14,7\n15,9,4\n7,16,4\n11,3,6\n5,11,2\n2,9,13\n14,7,4\n14,15,10\n4,8,4\n7,6,16\n15,12,14\n17,7,10\n13,15,4\n16,4,8\n13,3,5\n6,16,8\n3,6,12\n6,16,7\n15,9,15\n4,6,10\n12,12,16\n2,8,10\n3,13,11\n8,5,6\n14,4,12\n10,9,18\n9,6,2\n6,9,3\n12,14,15\n10,5,12\n17,7,12\n7,11,17\n14,12,15\n18,9,8\n10,5,16\n14,9,16\n4,5,11\n5,13,8\n3,4,6\n2,6,11\n6,15,15\n9,5,2\n11,15,15\n7,16,13\n2,9,12\n1,9,10\n9,7,16\n9,11,17\n16,11,6\n14,16,8\n9,3,12\n8,14,4\n17,8,10\n17,5,9\n4,11,12\n3,5,13\n7,15,14\n11,8,17\n13,2,9\n10,17,12\n8,5,2\n16,16,12\n10,6,16\n16,6,7\n9,10,1\n9,16,15\n7,11,18\n4,9,16\n8,2,11\n7,16,11\n8,7,2\n7,9,2\n2,11,5\n6,3,7\n10,7,17\n6,5,16\n4,4,8\n11,9,4\n5,13,13\n14,6,14\n2,8,7\n14,5,5\n13,14,3\n15,14,8\n9,5,3\n16,4,11\n3,7,15\n7,16,12\n14,14,14\n4,9,5\n4,4,10\n2,14,12\n15,2,9\n9,15,4\n16,13,6\n7,7,3\n4,11,6\n1,12,9\n12,10,17\n5,12,14\n16,12,12\n6,6,5\n15,11,11\n11,4,5\n11,13,5\n18,13,9\n17,6,13\n12,4,12\n5,16,9\n10,9,17\n3,14" <> ...}
cubes =
  puzzle_input
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    line
    |> String.split(",")
    |> Enum.map(&String.to_integer/1)
    |> List.to_tuple()
  end)
  |> MapSet.new()
MapSet.new([
  {12, 9, 18},
  {11, 4, 5},
  {2, 10, 6},
  {12, 2, 8},
  {14, 15, 15},
  {5, 14, 12},
  {10, 6, 18},
  {6, 4, 6},
  {11, 4, 3},
  {6, 14, 3},
  {4, 8, 4},
  {17, 7, 9},
  {7, 12, 16},
  {14, 13, 3},
  {12, 3, 16},
  {13, 6, 2},
  {5, 6, 5},
  {17, 10, 11},
  {4, 16, 9},
  {17, 9, 9},
  {6, 2, 10},
  {13, 17, 13},
  {12, 13, 3},
  {3, 13, 7},
  {13, 7, 4},
  {17, 12, 7},
  {7, 3, 13},
  {12, 15, 15},
  {15, 6, 4},
  {17, 10, 8},
  {9, 14, 13},
  {3, 9, 4},
  {14, 13, 9},
  {15, 13, 4},
  {13, 4, 15},
  {7, 7, 15},
  {6, 14, 8},
  {11, 2, 16},
  {7, 2, 8},
  {3, 14, 13},
  {4, 5, 6},
  {3, 9, 14},
  {4, 16, 12},
  {14, 12, 12},
  {14, 5, 15},
  {17, 9, 12},
  {15, 10, 15},
  {8, 17, ...},
  {2, ...},
  {...},
  ...
])

Task 1

sides =
  for {x, y, z} <- cubes,
      {place, {dx, dy, dz}} <- [
        x: {-1, 0, 0},
        y: {0, -1, 0},
        z: {0, 0, -1},
        x: {0, 0, 0},
        y: {0, 0, 0},
        z: {0, 0, 0}
      ],
      reduce: MapSet.new() do
    set ->
      side = {place, {x + dx, y + dy, z + dz}}

      if side in set do
        MapSet.delete(set, side)
      else
        MapSet.put(set, side)
      end
  end

MapSet.size(sides)
3636

Task 2

max =
  Enum.reduce(cubes, {0, 0, 0}, fn {x, y, z}, {mx, my, mz} ->
    {max(x, mx), max(y, my), max(z, mz)}
  end)
{19, 19, 19}
defmodule Cave do
  def bfs([], _sides, outer, _visited), do: outer

  def bfs([{x, y, z} = p | queue], sides, outer, visited) do
    {min, max} = Enum.min_max([x, y, z])

    if p in visited or max > 25 or min < -5 do
      bfs(queue, sides, outer, visited)
    else
      visited = MapSet.put(visited, p)

      {outer, xs1} = check(:x, p, {x + 1, y, z}, sides, outer, visited)
      {outer, xs2} = check(:x, {x - 1, y, z}, {x - 1, y, z}, sides, outer, visited)
      {outer, ys1} = check(:y, p, {x, y + 1, z}, sides, outer, visited)
      {outer, ys2} = check(:y, {x, y - 1, z}, {x, y - 1, z}, sides, outer, visited)
      {outer, zs1} = check(:z, p, {x, y, z + 1}, sides, outer, visited)
      {outer, zs2} = check(:z, {x, y, z - 1}, {x, y, z - 1}, sides, outer, visited)

      bfs(queue ++ xs1 ++ xs2 ++ ys1 ++ ys2 ++ zs1 ++ zs2, sides, outer, visited)
    end
  end

  defp check(axis, curr, next, sides, outer, visited) do
    cond do
      {axis, curr} in sides ->
        {MapSet.put(outer, {axis, curr}), []}

      next in visited ->
        {outer, []}

      true ->
        {outer, [next]}
    end
  end
end
{:module, Cave, <<70, 79, 82, 49, 0, 0, 14, ...>>, {:check, 6}}
outer = Cave.bfs([{-5, -5, -5}], sides, MapSet.new(), MapSet.new())
MapSet.new([
  x: {10, 19, 11},
  z: {15, 16, 12},
  z: {2, 16, 10},
  z: {5, 13, 2},
  y: {4, 3, 15},
  x: {0, 13, 10},
  x: {17, 12, 6},
  z: {10, 11, 0},
  z: {10, 5, 17},
  z: {4, 7, 2},
  x: {15, 16, 9},
  x: {2, 7, 4},
  z: {2, 8, 5},
  y: {16, 13, 5},
  x: {2, 6, 14},
  x: {18, 12, 11},
  y: {13, 17, 7},
  z: {3, 9, 14},
  y: {11, 3, 16},
  x: {4, 10, 17},
  y: {11, 2, 15},
  z: {13, 4, 3},
  x: {10, 17, 5},
  y: {3, 12, 4},
  y: {11, 18, 10},
  z: {5, 17, 8},
  y: {15, 16, 6},
  y: {3, 3, 7},
  z: {7, 1, 5},
  x: {14, 2, 9},
  y: {18, 5, 8},
  x: {10, 1, 13},
  x: {9, 16, 3},
  x: {2, 15, 8},
  y: {7, 4, 2},
  x: {17, 6, 12},
  x: {0, 9, 7},
  x: {12, 8, 1},
  x: {0, 11, 10},
  z: {10, 16, 3},
  x: {16, 5, 6},
  z: {5, 10, 1},
  z: {7, 4, 15},
  z: {12, 11, 18},
  y: {11, 17, 12},
  z: {3, 5, 4},
  z: {6, 1, 9},
  x: {16, 8, ...},
  z: {14, ...},
  z: {...},
  ...
])
MapSet.size(outer)
2102