Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Created December 25, 2017 08:13
Show Gist options
  • Save sasa1977/fd62451b7e73da57d125f30e2c093dc9 to your computer and use it in GitHub Desktop.
Save sasa1977/fd62451b7e73da57d125f30e2c093dc9 to your computer and use it in GitHub Desktop.
defmodule Day25 do
def part1(), do:
input()
|> run_machine()
|> tape()
|> Stream.filter(&match?({_pos, 1}, &1))
|> Enum.count()
defp run_machine(input), do:
Enum.reduce(
1..input.steps,
{input.blueprint, input.initial_state, 0, %{}},
fn _, {blueprint, state, pos, tape} ->
current_value = Map.get(tape, pos, 0)
{new_value, direction, new_state} = Map.fetch!(blueprint, {state, current_value})
{blueprint, new_state, pos + offset(direction), Map.put(tape, pos, new_value)}
end
)
defp tape({_blueprint, _state, _pos, tape}), do: tape
defp offset(:right), do: 1
defp offset(:left), do: -1
defp input(), do:
"input.txt"
|> File.stream!()
|> Stream.map(&String.trim/1)
|> Stream.reject(&(&1 == ""))
|> Enum.split(2)
|> parse_input()
defp parse_input({[initial_state, steps], blueprint}), do:
%{
initial_state: extract(initial_state, ~r/Begin in state (.)/),
steps: steps |> extract(~r/Perform a diagnostic checksum after (\d+)/) |> String.to_integer(),
blueprint: parse_blueprint(blueprint)
}
defp parse_blueprint(blueprint), do:
blueprint |> Stream.chunk_every(9) |> Stream.flat_map(&parse_state_transition/1) |> Map.new()
defp parse_state_transition([state | instructions]) do
current_state = extract(state, ~r/In state (.)/)
instructions
|> Stream.chunk_every(4)
|> Stream.map(&parse_instruction(current_state, &1))
end
defp parse_instruction(current_state, [if_current, write, move, state]), do:
{
{
current_state,
if_current |> extract(~r/If the current value is (\d)/) |> String.to_integer()
},
{
write |> extract(~r/Write the value (\d)/) |> String.to_integer(),
move |> extract(~r/Move one slot to the ((right)|(left))/) |> String.to_existing_atom(),
extract(state, ~r/Continue with state (.)/)
}
}
defp extract(string, regex), do:
regex |> Regex.run(string, capture: :all_but_first) |> hd()
end
Day25.part1() |> IO.inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment