Day 23: Opening the Turing Lock
Section
defmodule Computer do
def run_instructions(instructions, registers \\ %{a: 0, b: 0}) do
execute(instructions, registers, 0)
end
defp execute(instructions, registers, pointer) when pointer >= length(instructions),
do: registers
defp execute(instructions, registers, pointer) do
{new_registers, new_pointer} =
case Enum.at(instructions, pointer) do
{:hlf, r} ->
{Map.update!(registers, r, &div(&1, 2)), pointer + 1}
{:tpl, r} ->
{Map.update!(registers, r, &(&1 * 3)), pointer + 1}
{:inc, r} ->
{Map.update!(registers, r, &(&1 + 1)), pointer + 1}
{:jmp, offset} ->
{registers, pointer + offset}
{:jie, r, offset} ->
if rem(Map.get(registers, r), 2) == 0,
do: {registers, pointer + offset},
else: {registers, pointer + 1}
{:jio, r, offset} ->
if Map.get(registers, r) == 1,
do: {registers, pointer + offset},
else: {registers, pointer + 1}
end
execute(instructions, new_registers, new_pointer)
end
end
defmodule InputParser do
def parse(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(&parse_instruction/1)
end
defp parse_instruction(line) do
case String.split(line) do
["hlf", r] ->
{:hlf, String.to_atom(r)}
["tpl", r] ->
{:tpl, String.to_atom(r)}
["inc", r] ->
{:inc, String.to_atom(r)}
["jmp", offset] ->
{:jmp, String.to_integer(offset)}
["jie", r, offset] ->
{:jie, String.to_atom(String.trim_trailing(r, ",")), String.to_integer(offset)}
["jio", r, offset] ->
{:jio, String.to_atom(String.trim_trailing(r, ",")), String.to_integer(offset)}
end
end
end
parsed_instructions =
"/Users/eli/Desktop/input.txt"
|> File.read!()
|> InputParser.parse()
Computer.run_instructions(parsed_instructions)
%{a: 1, b: 184}
Computer.run_instructions(parsed_instructions, %{a: 1, b: 0})
%{a: 1, b: 231}