summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2024-12-10 21:49:02 +0000
committerAlexandre Jesus <adbjesus@gmail.com>2024-12-10 21:49:02 +0000
commitdc1cd90aa65dfa391decf7346f3515207633ad29 (patch)
tree7b6639928911c2bf9baf2ee641ce226ec24ef47f /src
parentb0f15c1c678a28702203eb1667f8a56924ef6e52 (diff)
downloadaoc2024-dc1cd90aa65dfa391decf7346f3515207633ad29.tar.gz
aoc2024-dc1cd90aa65dfa391decf7346f3515207633ad29.zip
Day 10
Diffstat (limited to 'src')
-rw-r--r--src/day10.exs74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/day10.exs b/src/day10.exs
new file mode 100644
index 0000000..7530903
--- /dev/null
+++ b/src/day10.exs
@@ -0,0 +1,74 @@
+defmodule Day10 do
+ def part1(data) do
+ grid = data
+ |> String.split("\n", trim: true)
+ |> Enum.map(&String.codepoints/1)
+ |> Enum.map(fn v -> Enum.map(v, &String.to_integer/1) end)
+
+ values = for {l, i} <- Enum.with_index(grid),
+ {v, j} <- Enum.with_index(l) do
+ {v, {i, j}}
+ end
+ |> Enum.group_by(fn {v, _} -> v end, fn {_, p} -> p end)
+
+ dist = fn {a, b}, {c, d} -> abs(a-c) + abs(b-d) end
+ ends = fn p, prev ->
+ for {_, v} <- Enum.filter(prev, fn {p2, _} -> dist.(p, p2) == 1 end),
+ reduce: MapSet.new() do
+ acc -> MapSet.union(acc, v)
+ end
+ end
+
+ for i <- 8..0//-1,
+ reduce: Map.get(values, 9, []) |> Enum.map(& {&1, MapSet.new([&1])}) do
+ acc -> Map.get(values, i, [])
+ |> Enum.map(fn p -> {p, ends.(p, acc)} end)
+ |> Enum.filter(fn {_, m} -> MapSet.size(m) > 0 end)
+ end
+ |> Enum.map(fn {_, m} -> MapSet.size(m) end)
+ |> Enum.sum()
+ end
+
+ def part2(data) do
+ grid = data
+ |> String.split("\n", trim: true)
+ |> Enum.map(&String.codepoints/1)
+ |> Enum.map(fn v -> Enum.map(v, &String.to_integer/1) end)
+
+ values = for {l, i} <- Enum.with_index(grid),
+ {v, j} <- Enum.with_index(l) do
+ {v, {i, j}}
+ end
+ |> Enum.group_by(fn {v, _} -> v end, fn {_, p} -> p end)
+
+ acc = values
+ |> Map.get(9, [])
+ |> Enum.map(fn p -> {p, 1} end)
+
+ dist = fn {a, b}, {c, d} -> abs(a-c) + abs(b-d) end
+ count = fn p, prev ->
+ prev
+ |> Enum.filter(fn {p2, _} -> dist.(p, p2) == 1 end)
+ |> Enum.map(fn {_, c} -> c end)
+ |> Enum.sum()
+ end
+
+ for i <- 8..0//-1, reduce: acc do
+ acc -> Map.get(values, i, [])
+ |> Enum.map(fn p -> {p, count.(p, acc)} end)
+ |> Enum.filter(fn {_, c} -> c > 0 end)
+ end
+ |> Enum.map(fn {_, c} -> c end)
+ |> Enum.sum()
+ end
+end
+
+data = IO.read(:stdio, :eof)
+
+{time1 , ans1} = :timer.tc(fn -> Day10.part1(data) end)
+IO.puts("Time : #{time1 / 1000000}")
+IO.puts("Answer: #{ans1}")
+
+{time2 , ans2} = :timer.tc(fn -> Day10.part2(data) end)
+IO.puts("Time : #{time2 / 1000000}")
+IO.puts("Answer: #{ans2}")