From fbf79992097520c152a4a53960463939e5a8af87 Mon Sep 17 00:00:00 2001 From: sloane Date: Thu, 28 Nov 2024 19:33:42 -0500 Subject: [PATCH] solve 2015 day 23 --- 2015/README.md | 14 ++--- 2015/lib/2015/23.ex | 121 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 3 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 2015/lib/2015/23.ex diff --git a/2015/README.md b/2015/README.md index a0ee495..cf82aec 100644 --- a/2015/README.md +++ b/2015/README.md @@ -12,12 +12,12 @@ ``` -| S | M | T | W | T | F | S | -| :--: | :--: | :-: | :-: | :-: | :-: | :-: | -| | | [1] | [2] | [3] | [4] | [5] | -| [6] | [7] | [8] | [9] | [10] | [11] | [12] | -| [13] | [14] | [15] | [16]| [17] | [18] | [19] | -| [20] | [21] | 22 | 23 | 24 | 25 | | +| S | M | T | W | T | F | S | +| :--: | :--: | :-: | :-: | :-: | :-: | :-: | +| | | [1] | [2] | [3] | [4] | [5] | +| [6] | [7] | [8] | [9] | [10] | [11] | [12] | +| [13] | [14] | [15] | [16] | [17] | [18] | [19] | +| [20] | [21] | 22 | [23] | 24 | 25 | | [1]: ./lib/2015/1.ex [2]: ./lib/2015/2.ex @@ -40,3 +40,5 @@ [19]: ./lib/2015/19.ex [20]: ./lib/2015/20.ex [21]: ./lib/2015/21.ex + +[23]: ./lib/2015/23.ex diff --git a/2015/lib/2015/23.ex b/2015/lib/2015/23.ex new file mode 100644 index 0000000..42b33b0 --- /dev/null +++ b/2015/lib/2015/23.ex @@ -0,0 +1,121 @@ +import AOC + +aoc 2015, 23 do + defmodule Program do + import Integer, only: [is_even: 1] + + @enforce_keys [:instructions] + defstruct [:instructions, ptr: 0, a: 0, b: 0] + + def new(inp) do + instructions = + for {line, idx} <- Enum.with_index(inp), into: %{} do + {idx, parse_line(line)} + end + + %Program{instructions: instructions} + end + + def run(%Program{ptr: ptr, instructions: instructions} = prgm) do + case Map.fetch(instructions, ptr) do + {:ok, inst} -> + prgm + |> exec_inst(inst) + |> run() + + :error -> + prgm + end + end + + defp exec_inst(prgm, {:hlf, r}) do + prgm + |> update!(r, &div(&1, 2)) + |> step() + end + + defp exec_inst(prgm, {:tpl, r}) do + prgm + |> update!(r, &(&1 * 3)) + |> step() + end + + defp exec_inst(prgm, {:inc, r}) do + prgm + |> update!(r, &(&1 + 1)) + |> step() + end + + defp exec_inst(prgm, {:jmp, offset}) do + update!(prgm, :ptr, &(&1 + offset)) + end + + defp exec_inst(prgm, {:jie, r, offset}) do + if prgm |> fetch!(r) |> is_even() do + update!(prgm, :ptr, &(&1 + offset)) + else + step(prgm) + end + end + + defp exec_inst(prgm, {:jio, r, offset}) do + if fetch!(prgm, r) == 1 do + update!(prgm, :ptr, &(&1 + offset)) + else + step(prgm) + end + end + + def reg(%Program{} = prgm, r) do + prgm + |> Map.get(reg_key(r)) + end + + defp reg_key("a"), do: :a + defp reg_key("b"), do: :b + defp reg_key(other), do: other + + defp update!(%Program{} = prgm, r, fun) do + Map.update!(prgm, reg_key(r), fun) + end + + def fetch!(%Program{} = prgm, r) do + Map.fetch!(prgm, reg_key(r)) + end + + defp step(prgm), do: update!(prgm, :ptr, &(&1 + 1)) + + defp parse_line("hlf " <> r), do: {:hlf, r} + defp parse_line("tpl " <> r), do: {:tpl, r} + defp parse_line("inc " <> r), do: {:inc, r} + defp parse_line("jmp +" <> offset), do: {:jmp, String.to_integer(offset)} + defp parse_line("jmp -" <> offset), do: {:jmp, 0 - String.to_integer(offset)} + + defp parse_line(<<"jie ", <>, ", +", offset::binary>>), + do: {:jie, r, String.to_integer(offset)} + + defp parse_line(<<"jie ", <>, ", -", offset::binary>>), + do: {:jie, r, 0 - String.to_integer(offset)} + + defp parse_line(<<"jio ", <>, ", +", offset::binary>>), + do: {:jio, r, String.to_integer(offset)} + + defp parse_line(<<"jio ", <>, ", -", offset::binary>>), + do: {:jio, r, 0 - String.to_integer(offset)} + end + + def p1 do + input_stream() + |> Program.new() + |> Program.run() + |> Program.fetch!(:b) + end + + def p2 do + input_stream() + |> Program.new() + |> Map.put(:a, 1) + |> Program.run() + |> Program.fetch!(:b) + end +end diff --git a/README.md b/README.md index cced555..a90a087 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ | Year | Stars | Languages | | - | - | - | -| [2015] | **42/50** 🌟 | Elixir | +| [2015] | **44/50** 🌟 | Elixir | | 2016 | | | | [2017] | **18/50** 🌟 | Haskell | | 2018 | | |