kwando
Advent of Code 2022 - Day 18
Today was fun and I got it right the first time
MapSets saves the day again.
https://github.com/kwando/AoC2022/blob/main/18/day18.livemd
First Post!
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 ![]()
Popular in Challenges
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
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
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
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
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
part 1:
https://github.com/rugyoga/aoc2021/blob/main/day8.exs
part 2:
https://github.com/rugyoga/aoc2021/blob/main/day8b.exs
New
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
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
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
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
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the...
New
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
Hello, how can I check the Phoenix version ?
Thanks !
New
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
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
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
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
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...
New
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
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
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








