make mix tasks work again - fix comp errors with day11 2022
This commit is contained in:
parent
8a4323bd16
commit
cbd541911a
4 changed files with 137 additions and 70 deletions
|
@ -1,26 +1,46 @@
|
||||||
defmodule MonkeyUtil do
|
defmodule MonkeyUtil do
|
||||||
def parse_op(z, s) do
|
def parse_op(z, s) do
|
||||||
"Operation: new = " <> z, s -> parse_op(z, s)
|
(fn
|
||||||
"old " <> z, s -> parse_op(z, [:old | s])
|
"Operation: new = " <> z, s ->
|
||||||
"old" <> z, s -> parse_op(z, [:old | s])
|
parse_op(z, s)
|
||||||
"+ " <> z, s -> parse_op(z, [:plus | s])
|
|
||||||
"- " <> z, s -> parse_op(z, [:minus | s])
|
"old " <> z, s ->
|
||||||
"* " <> z, s -> parse_op(z, [:mul | s])
|
parse_op(z, [:old | s])
|
||||||
"/ " <> z, s -> parse_op(z, [:div | s])
|
|
||||||
"", _, s -> s |> Enum.reverse()
|
"old" <> z, s ->
|
||||||
|
parse_op(z, [:old | s])
|
||||||
|
|
||||||
|
"+ " <> z, s ->
|
||||||
|
parse_op(z, [:plus | s])
|
||||||
|
|
||||||
|
"- " <> z, s ->
|
||||||
|
parse_op(z, [:minus | s])
|
||||||
|
|
||||||
|
"* " <> z, s ->
|
||||||
|
parse_op(z, [:mul | s])
|
||||||
|
|
||||||
|
"/ " <> z, s ->
|
||||||
|
parse_op(z, [:div | s])
|
||||||
|
|
||||||
|
"", s ->
|
||||||
|
s |> Enum.reverse()
|
||||||
|
|
||||||
n, s ->
|
n, s ->
|
||||||
[a | b] = String.split( n, " ")
|
[a | b] = String.split(n, " ")
|
||||||
a = String.trim(a) |> String.to_integer()
|
a = String.trim(a) |> String.to_integer()
|
||||||
parse_op(b |> Enum.join(" "), [a | s])
|
parse_op(b |> Enum.join(" "), [a | s])
|
||||||
|
end).(z, s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def subs(b, a), do: if b == :old, do: a, else: b
|
def subs(b, a), do: if(b == :old, do: a, else: b)
|
||||||
|
|
||||||
def resolve_stack(x, y) do
|
def resolve_stack(x, y) do
|
||||||
(fn
|
(fn
|
||||||
old, [a, :plus, b] -> subs(a, old) + subs(b, old)
|
old, [a, :plus, b] -> subs(a, old) + subs(b, old)
|
||||||
old, [a, :minus, b] -> subs(a, old) - subs(b, old)
|
old, [a, :minus, b] -> subs(a, old) - subs(b, old)
|
||||||
old, [a, :mul, b] -> subs(a, old) * subs(b, old)
|
old, [a, :mul, b] -> subs(a, old) * subs(b, old)
|
||||||
old, [a, :div, b] -> subs(a, old) / subs(b, old) end).(x, y)
|
old, [a, :div, b] -> subs(a, old) / subs(b, old)
|
||||||
|
end).(x, y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,14 +50,21 @@ end
|
||||||
|
|
||||||
defmodule MonkeyMachine do
|
defmodule MonkeyMachine do
|
||||||
def load(instructions) do
|
def load(instructions) do
|
||||||
{barrel, _} = for instruction <- instructions, reduce: {%{}, nil} do
|
{barrel, _} =
|
||||||
|
for instruction <- instructions, reduce: {%{}, nil} do
|
||||||
{barrel, monkey} ->
|
{barrel, monkey} ->
|
||||||
(fn
|
(fn
|
||||||
{:break} ->
|
{:break} ->
|
||||||
{barrel |> Map.put(monkey.id, monkey), nil}
|
{barrel |> Map.put(monkey.id, monkey), nil}
|
||||||
{:add_monkey, id} -> {barrel, %Monkey{id: id}}
|
|
||||||
{:starting_items, i} -> {barrel, %{monkey | items: i }}
|
{:add_monkey, id} ->
|
||||||
{a, o} -> {barrel, %{monkey | a => o }}
|
{barrel, %Monkey{id: id}}
|
||||||
|
|
||||||
|
{:starting_items, i} ->
|
||||||
|
{barrel, %{monkey | items: i}}
|
||||||
|
|
||||||
|
{a, o} ->
|
||||||
|
{barrel, %{monkey | a => o}}
|
||||||
end).(instruction)
|
end).(instruction)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,13 +76,21 @@ defmodule MonkeyMachine do
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(barrel, :part2) do
|
def run(barrel, :part2) do
|
||||||
run(barrel, 0, (Map.keys(barrel) |> Enum.count()) - 1, Map.values(barrel) |> Stream.map(&(&1.mod)) |> Enum.product())
|
run(
|
||||||
|
barrel,
|
||||||
|
0,
|
||||||
|
(Map.keys(barrel) |> Enum.count()) - 1,
|
||||||
|
Map.values(barrel) |> Stream.map(& &1.mod) |> Enum.product()
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp run(barrel, i, n) when i > n, do: barrel
|
defp run(barrel, i, n) when i > n, do: barrel
|
||||||
|
|
||||||
defp run(barrel, id, n) do
|
defp run(barrel, id, n) do
|
||||||
monkey = Map.get(barrel, id)
|
monkey = Map.get(barrel, id)
|
||||||
barrel = for item <- monkey.items, reduce: barrel do
|
|
||||||
|
barrel =
|
||||||
|
for item <- monkey.items, reduce: barrel do
|
||||||
b ->
|
b ->
|
||||||
item = div(monkey.op.(item), 3)
|
item = div(monkey.op.(item), 3)
|
||||||
dest = if rem(item, monkey.mod) == 0, do: monkey.if_true, else: monkey.if_false
|
dest = if rem(item, monkey.mod) == 0, do: monkey.if_true, else: monkey.if_false
|
||||||
|
@ -63,15 +98,19 @@ defmodule MonkeyMachine do
|
||||||
b
|
b
|
||||||
|> Map.update!(dest, fn d -> %{d | items: [item | d.items]} end)
|
|> Map.update!(dest, fn d -> %{d | items: [item | d.items]} end)
|
||||||
|> Map.update!(id, fn m -> Map.update!(m, :inspections, &(&1 + 1)) end)
|
|> Map.update!(id, fn m -> Map.update!(m, :inspections, &(&1 + 1)) end)
|
||||||
end |> Map.update!(id, fn m -> %{m | items: []} end)
|
end
|
||||||
|
|> Map.update!(id, fn m -> %{m | items: []} end)
|
||||||
|
|
||||||
run(barrel, id + 1, n)
|
run(barrel, id + 1, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp run(barrel, i, n, _) when i > n, do: barrel
|
defp run(barrel, i, n, _) when i > n, do: barrel
|
||||||
|
|
||||||
defp run(barrel, id, n, m) do
|
defp run(barrel, id, n, m) do
|
||||||
monkey = Map.get(barrel, id)
|
monkey = Map.get(barrel, id)
|
||||||
barrel = for item <- monkey.items, reduce: barrel do
|
|
||||||
|
barrel =
|
||||||
|
for item <- monkey.items, reduce: barrel do
|
||||||
b ->
|
b ->
|
||||||
r = rem(monkey.op.(item), m)
|
r = rem(monkey.op.(item), m)
|
||||||
item = if r == 0, do: m, else: r
|
item = if r == 0, do: m, else: r
|
||||||
|
@ -80,7 +119,8 @@ defmodule MonkeyMachine do
|
||||||
b
|
b
|
||||||
|> Map.update!(dest, fn d -> %{d | items: [item | d.items]} end)
|
|> Map.update!(dest, fn d -> %{d | items: [item | d.items]} end)
|
||||||
|> Map.update!(id, fn m -> Map.update!(m, :inspections, &(&1 + 1)) end)
|
|> Map.update!(id, fn m -> Map.update!(m, :inspections, &(&1 + 1)) end)
|
||||||
end |> Map.update!(id, fn m -> %{m | items: []} end)
|
end
|
||||||
|
|> Map.update!(id, fn m -> %{m | items: []} end)
|
||||||
|
|
||||||
run(barrel, id + 1, n, m)
|
run(barrel, id + 1, n, m)
|
||||||
end
|
end
|
||||||
|
@ -89,30 +129,45 @@ end
|
||||||
defmodule MonkeySolver do
|
defmodule MonkeySolver do
|
||||||
# part := :part1 || :part2
|
# part := :part1 || :part2
|
||||||
def solve(input, part) do
|
def solve(input, part) do
|
||||||
barrel = input
|
barrel =
|
||||||
|
input
|
||||||
|> String.split("\n")
|
|> String.split("\n")
|
||||||
|> Stream.map(&String.trim/1)
|
|> Stream.map(&String.trim/1)
|
||||||
|> Enum.map(
|
|> Enum.map(fn
|
||||||
fn
|
"Monkey " <> z ->
|
||||||
"Monkey " <> z -> {:add_monkey, z |> String.split(":") |> Enum.at(0) |> String.to_integer()}
|
{:add_monkey, z |> String.split(":") |> Enum.at(0) |> String.to_integer()}
|
||||||
"Starting items: " <> i -> {:starting_items, i |> String.split(",", trim: true) |> Enum.map(&String.to_integer(String.trim(&1)))}
|
|
||||||
"Operation: " <> _ = u -> {:op, fn o -> MonkeyUtil.resolve_stack(o, MonkeyUtil.parse_op(u, [])) end}
|
"Starting items: " <> i ->
|
||||||
"Test: divisible by " <> n -> {:mod, String.to_integer(n)}
|
{:starting_items,
|
||||||
"If true: throw to monkey " <> n -> {:if_true, String.to_integer(n)}
|
i |> String.split(",", trim: true) |> Enum.map(&String.to_integer(String.trim(&1)))}
|
||||||
"If false: throw to monkey " <> n -> {:if_false, String.to_integer(n)}
|
|
||||||
"" -> {:break}
|
"Operation: " <> _ = u ->
|
||||||
u -> u
|
{:op, fn o -> MonkeyUtil.resolve_stack(o, MonkeyUtil.parse_op(u, [])) end}
|
||||||
end
|
|
||||||
)
|
"Test: divisible by " <> n ->
|
||||||
|
{:mod, String.to_integer(n)}
|
||||||
|
|
||||||
|
"If true: throw to monkey " <> n ->
|
||||||
|
{:if_true, String.to_integer(n)}
|
||||||
|
|
||||||
|
"If false: throw to monkey " <> n ->
|
||||||
|
{:if_false, String.to_integer(n)}
|
||||||
|
|
||||||
|
"" ->
|
||||||
|
{:break}
|
||||||
|
|
||||||
|
u ->
|
||||||
|
u
|
||||||
|
end)
|
||||||
|> MonkeyMachine.load()
|
|> MonkeyMachine.load()
|
||||||
|
|
||||||
iterations = if part == :part1, do: 20, else: 10_000 end
|
iterations = if part == :part1, do: 20, else: 10_000
|
||||||
|
|
||||||
for _ <- 1..iterations, reduce: barrel do
|
for _ <- 1..iterations, reduce: barrel do
|
||||||
b -> MonkeyMachine.run(b, part)
|
b -> MonkeyMachine.run(b, part)
|
||||||
end
|
end
|
||||||
|> Map.values()
|
|> Map.values()
|
||||||
|> Stream.map(&(&1.inspections))
|
|> Stream.map(& &1.inspections)
|
||||||
|> Enum.sort(:desc)
|
|> Enum.sort(:desc)
|
||||||
|> Enum.take(2)
|
|> Enum.take(2)
|
||||||
|> Enum.product()
|
|> Enum.product()
|
||||||
|
|
|
@ -3,8 +3,6 @@ defmodule AoC do
|
||||||
defp get_request_headers!(), do: [Cookie: "session=#{get_session!()}"]
|
defp get_request_headers!(), do: [Cookie: "session=#{get_session!()}"]
|
||||||
|
|
||||||
def fetch_input!(year, day) do
|
def fetch_input!(year, day) do
|
||||||
Application.ensure_all_started(:req)
|
|
||||||
|
|
||||||
Req.get!(
|
Req.get!(
|
||||||
"https://adventofcode.com/#{year}/day/#{day}/input",
|
"https://adventofcode.com/#{year}/day/#{day}/input",
|
||||||
headers: get_request_headers!()
|
headers: get_request_headers!()
|
||||||
|
@ -17,7 +15,9 @@ defmodule AoC do
|
||||||
import String, only: [split: 2, trim: 1, contains?: 2, to_integer: 1]
|
import String, only: [split: 2, trim: 1, contains?: 2, to_integer: 1]
|
||||||
|
|
||||||
day_class = fn classes -> classes |> split(" ") |> at(0) |> split("-") |> at(1) |> trim() end
|
day_class = fn classes -> classes |> split(" ") |> at(0) |> split("-") |> at(1) |> trim() end
|
||||||
days_complete = fn classes -> cond do
|
|
||||||
|
days_complete = fn classes ->
|
||||||
|
cond do
|
||||||
contains?(classes, "verycomplete") -> 2
|
contains?(classes, "verycomplete") -> 2
|
||||||
contains?(classes, "complete") -> 1
|
contains?(classes, "complete") -> 1
|
||||||
true -> 0
|
true -> 0
|
||||||
|
@ -25,14 +25,15 @@ defmodule AoC do
|
||||||
end
|
end
|
||||||
|
|
||||||
session = get_session!()
|
session = get_session!()
|
||||||
|
|
||||||
Req.get!("https://adventofcode.com/#{year}", headers: [cookie: "session=#{session}"]).body
|
Req.get!("https://adventofcode.com/#{year}", headers: [cookie: "session=#{session}"]).body
|
||||||
|> Floki.parse_document!(html_parser: Floki.HTMLParser.Html5ever)
|
|> Floki.parse_document!(html_parser: Floki.HTMLParser.Html5ever)
|
||||||
|> Floki.find("pre.calendar > a")
|
|> Floki.find("pre.calendar > a")
|
||||||
|> Stream.map(fn e ->
|
|> Stream.map(fn e ->
|
||||||
"#{Floki.attribute(e, "class")}\n"
|
"#{Floki.attribute(e, "class")}\n"
|
||||||
end)
|
end)
|
||||||
|> Stream.map(fn classes -> { day_class.(classes), days_complete.(classes) } end)
|
|> Stream.map(fn classes -> {day_class.(classes), days_complete.(classes)} end)
|
||||||
|> Stream.map(fn {day, c} -> {day |> split("day") |> at(1) |> to_integer(), c} end)
|
|> Stream.map(fn {day, c} -> {day |> split("day") |> at(1) |> to_integer(), c} end)
|
||||||
|> sort_by(&(elem(&1, 0)))
|
|> sort_by(&elem(&1, 0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
defmodule Mix.Tasks.GetInput do
|
defmodule Mix.Tasks.GetInput do
|
||||||
def run(args) do
|
def run(args) do
|
||||||
|
Application.ensure_all_started(:req)
|
||||||
|
|
||||||
[year, day] = args
|
[year, day] = args
|
||||||
write_file = &File.write("./input/#{year}_#{day}.txt", &1)
|
write_file = &File.write("./input/#{year}_#{day}.txt", &1)
|
||||||
|
|
9
elixir/lib/mix/tasks/get_report_card.ex
Normal file
9
elixir/lib/mix/tasks/get_report_card.ex
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Mix.Tasks.GetReportCard do
|
||||||
|
def run([year | _]) do
|
||||||
|
Application.ensure_all_started(:req)
|
||||||
|
|
||||||
|
AoC.fetch_reportcard!(year)
|
||||||
|
|> inspect()
|
||||||
|
|> IO.puts()
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue