Day 14
This commit is contained in:
@@ -4,12 +4,11 @@ defmodule Aoc2023 do
|
||||
import Aoc2023.Common
|
||||
|
||||
def main(input) do
|
||||
{took, _} = :timer.tc fn ->
|
||||
parsed = parse(input)
|
||||
IO.puts("Part 1: #{part1(parsed)}")
|
||||
IO.puts("Part 2: #{part2(parsed)}")
|
||||
end
|
||||
IO.puts("Took #{took / 1_000}ms")
|
||||
{t_parse, parsed} = :timer.tc fn -> parse(input) end
|
||||
{t_p1, _} = :timer.tc fn -> IO.puts("Part 1: #{part1(parsed)}") end
|
||||
|
||||
{t_p2, _} = :timer.tc fn -> IO.puts("Part 2: #{part2(parsed)}") end
|
||||
IO.puts("Took #{(t_parse + t_p1 + t_p2) / 1_000}ms (parse: #{t_parse / 1_000}ms, part1: #{t_p1 / 1_000}ms, part2: #{t_p2 / 1_000}ms)")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
77
lib/day14.ex
Normal file
77
lib/day14.ex
Normal file
@@ -0,0 +1,77 @@
|
||||
defmodule Aoc2023.Day14 do
|
||||
use Aoc2023
|
||||
|
||||
def parse(input) do
|
||||
input
|
||||
|> lines
|
||||
|> Enum.map(&String.to_charlist/1)
|
||||
end
|
||||
|
||||
defp replace_many_at(lst, idxs, val) do
|
||||
idxs |> Enum.reduce(lst, &List.replace_at(&2, &1, val))
|
||||
end
|
||||
|
||||
defp slide(grid) do
|
||||
iter = fn recur, grid ->
|
||||
case grid do
|
||||
[last | [next | rest]] ->
|
||||
idxs =
|
||||
last
|
||||
|> Enum.with_index()
|
||||
|> Enum.filter(pipe(elem(0) |> Kernel.==(?O)))
|
||||
|> Enum.map(pipe(elem(1)))
|
||||
|> Enum.filter(&(Enum.at(next, &1) == ?.))
|
||||
|
||||
[
|
||||
last |> replace_many_at(idxs, ?.)
|
||||
| recur.(recur, [next |> replace_many_at(idxs, ?O) | rest])
|
||||
]
|
||||
|
||||
[last] ->
|
||||
[last]
|
||||
end
|
||||
end
|
||||
|
||||
loop = fn recur, grid ->
|
||||
grid_ = iter.(iter, grid)
|
||||
if grid_ == grid, do: grid, else: recur.(recur, grid_)
|
||||
end
|
||||
|
||||
loop.(loop, grid |> Enum.reverse())
|
||||
end
|
||||
|
||||
defp cycle(grid) do
|
||||
for _ <- 1..4, reduce: grid do
|
||||
# reverse |> transpose is rotation clockwise, but slide already reverses
|
||||
grid -> grid |> slide |> transpose
|
||||
end
|
||||
end
|
||||
|
||||
defp cycles(grid, n \\ 1_000_000_000, {cache_to_n, cache_from_n} \\ {%{}, %{}}) when n > 0 do
|
||||
rep_n = Map.get(cache_to_n, grid)
|
||||
if rep_n do
|
||||
n_ = rep_n - Integer.mod(n, rep_n - n)
|
||||
cache_from_n |> Map.get(n_)
|
||||
else
|
||||
grid_ = cycle(grid)
|
||||
cycles(grid_, n - 1, {Map.put(cache_to_n, grid, n), Map.put(cache_from_n, n, grid)})
|
||||
end
|
||||
end
|
||||
|
||||
def part1(input) do
|
||||
input
|
||||
|> slide
|
||||
|> Enum.with_index(1)
|
||||
|> Enum.map(fn {row, i} -> Enum.count(row, &(&1 == ?O)) * i end)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def part2(input) do
|
||||
input
|
||||
|> cycles()
|
||||
|> Enum.reverse
|
||||
|> Enum.with_index(1)
|
||||
|> Enum.map(fn {row, i} -> Enum.count(row, &(&1 == ?O)) * i end)
|
||||
|> Enum.sum()
|
||||
end
|
||||
end
|
||||
@@ -15,6 +15,7 @@ defmodule Mix.Tasks.Aoc do
|
||||
defp module(11), do: Aoc2023.Day11
|
||||
defp module(12), do: Aoc2023.Day12
|
||||
defp module(13), do: Aoc2023.Day13
|
||||
defp module(14), do: Aoc2023.Day14
|
||||
# [MODULE INSERTION POINT]
|
||||
|
||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||
@@ -107,6 +108,10 @@ defmodule Mix.Tasks.Aoc do
|
||||
create_file("#{tests_dir(day)}#{last + 1}", IO.read(:stdio, :eof))
|
||||
end
|
||||
|
||||
defp run(day, ["test", "expected", test, part, value]) do
|
||||
create_file("#{tests_dir(day)}#{test}.#{part}", value)
|
||||
end
|
||||
|
||||
defp run(day, ["test", "expected", test, part]) do
|
||||
create_file("#{tests_dir(day)}#{test}.#{part}", IO.read(:stdio, :eof))
|
||||
end
|
||||
@@ -162,6 +167,19 @@ defmodule Mix.Tasks.Aoc do
|
||||
run_file(day, "#{base_dir()}/inputs/day#{day}")
|
||||
end
|
||||
|
||||
defp run(day, ["run", "submit", part]) do
|
||||
run(day, ["fetch"])
|
||||
mod = module(day)
|
||||
parsed = mod.parse(read("#{base_dir()}/inputs/day#{day}"))
|
||||
val = case part do
|
||||
"1" -> mod.part1(parsed)
|
||||
"2" -> mod.part2(parsed)
|
||||
end
|
||||
HTTPoison.start()
|
||||
resp = HTTPoison.post!("https://adventofcode.com/2023/day/#{day}/answer", {:form, [level: part, answer: stringify(val)]}, "user-agent": "aoc-ex by ben@soroos.net", cookie: "session=#{System.get_env("AOC_SESSION")}")
|
||||
resp |> dbg
|
||||
end
|
||||
|
||||
defp run(day, ["run", "-"]) do
|
||||
run_file(day)
|
||||
end
|
||||
|
||||
10
tests/day14/1
Normal file
10
tests/day14/1
Normal file
@@ -0,0 +1,10 @@
|
||||
O....#....
|
||||
O.OO#....#
|
||||
.....##...
|
||||
OO.#O....O
|
||||
.O.....O#.
|
||||
O.#..O.#.#
|
||||
..O..#O..O
|
||||
.......O..
|
||||
#....###..
|
||||
#OO..#....
|
||||
1
tests/day14/1.1
Normal file
1
tests/day14/1.1
Normal file
@@ -0,0 +1 @@
|
||||
136
|
||||
1
tests/day14/1.2
Normal file
1
tests/day14/1.2
Normal file
@@ -0,0 +1 @@
|
||||
64
|
||||
Reference in New Issue
Block a user