Commit d3097465 by Andrew Fontaine

### Day 12 DONE

parent ea92af78
lib/Y2019/12.ex 0 → 100644
 import AdventOfCode aoc 2019, 12 do @line_pattern ~r/.+), y=(?.+), z=(?.+)>/ def p1(), do: s1(input_stream(), 1000) def s1(stream, x) do moons = Enum.map(stream, &parse/1) Range.new(1, x) |> Enum.reduce(moons, fn _, moons -> run_step(moons) end) |> Enum.map(fn %{p: {x1, y1, z1}, v: {xv, yv, zv}} -> (abs(x1) + abs(y1) + abs(z1)) * (abs(xv) + abs(yv) + abs(zv)) end) |> Enum.sum() end def p2(), do: s2(input_stream()) def s2(stream) do moons = Enum.map(stream, &parse/1) moons |> Enum.map(fn %{p: {x, y, z}, v: {xv, yv, zv}} -> [{x, xv}, {y, yv}, {z, zv}] end) |> Enum.reduce([[], [], []], fn [x, y, z], [xs, ys, zs] -> [[x | xs], [y | ys], [z | zs]] end) |> Task.async_stream(fn ps -> 1 |> Stream.iterate(&(&1 + 1)) |> Enum.reduce_while(ps, fn c, moons -> moons = run_step(moons) if moons == ps do {:halt, c} else {:cont, moons} end end) end) |> Stream.map(fn {:ok, x} -> x end) |> Enum.reduce(1, fn x, y -> div(x * y, Integer.gcd(x, y)) end) end defp run_step(moons) do moons |> Enum.map(fn moon -> Enum.reduce(moons -- [moon], moon, fn m1, m2 -> set_velocity(m2, m1) end) end) |> Enum.map(&apply_velocity/1) end defp apply_velocity({p, v}), do: {p + v, v} defp apply_velocity(%{p: {x1, y1, z1}, v: {x2, y2, z2} = v}) do %{p: {x1 + x2, y1 + y2, z1 + z2}, v: v} end defp set_velocity(%{p: p1, v: v1}, %{p: p2}) do %{p: p1, v: apply_gravity(v1, gravity_diff(p1, p2))} end defp set_velocity({p1, v1}, {p2, _v2}) do {p1, apply_gravity(v1, gravity_diff(p1, p2))} end defp apply_gravity({x1, y1, z1}, {x2, y2, z2}) do {x1 + x2, y1 + y2, z1 + z2} end defp apply_gravity(p, v), do: p + v defp gravity_diff({x1, y1, z1}, {x2, y2, z2}) do {gravity_diff(x1, x2), gravity_diff(y1, y2), gravity_diff(z1, z2)} end defp gravity_diff(p1, p2) when p1 > p2, do: -1 defp gravity_diff(p1, p2) when p1 == p2, do: 0 defp gravity_diff(p1, p2) when p1 < p2, do: 1 defp parse(line) do %{"x" => x, "y" => y, "z" => z} = Regex.named_captures(@line_pattern, line) %{p: {String.to_integer(x), String.to_integer(y), String.to_integer(z)}, v: {0, 0, 0}} end end
priv/2019/12.txt 0 → 100644

 defmodule AdventOfCode.Y2019.D12Test do use ExUnit.Case, async: true alias AdventOfCode.Y2019.D12 test "s1" do moons = [ "", "", "", "" ] assert 179 = D12.s1(moons, 10) end test "s2" do moons = [ "", "", "", "" ] assert 2772 = D12.s2(moons) moons = [ "", "", "", "" ] assert 4_686_774_924 = D12.s2(moons) end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!