54 lines
1 KiB
Elixir
54 lines
1 KiB
Elixir
|
defmodule Parser do
|
||
|
@doc """
|
||
|
Parse file with instructions.
|
||
|
"""
|
||
|
def parse_file(filepath) do
|
||
|
File.stream!(filepath)
|
||
|
|> Stream.map(&String.trim_trailing/1)
|
||
|
|> Enum.to_list()
|
||
|
|> parse_input()
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Parse instructions.
|
||
|
|
||
|
# Examples:
|
||
|
|
||
|
iex> Parser.parse_input(["LLR", "", "AAA = (AAA, ZZZ)", "ZZZ = (ZZZ, ZZZ)"])
|
||
|
{["L", "L", "R"], %{"AAA" => ["AAA", "ZZZ"], "ZZZ" => ["ZZZ", "ZZZ"]}}
|
||
|
"""
|
||
|
def parse_input(lines) do
|
||
|
instructions =
|
||
|
lines
|
||
|
|> hd()
|
||
|
|> String.graphemes()
|
||
|
|
||
|
steps =
|
||
|
lines
|
||
|
|> Stream.drop(2)
|
||
|
|> Stream.map(&parse_instruction/1)
|
||
|
|> Map.new()
|
||
|
|
||
|
{instructions, steps}
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Parse instruction string.
|
||
|
|
||
|
## Examples
|
||
|
|
||
|
iex> Parser.parse_instruction("BBB = (AAA, ZZZ)")
|
||
|
{"BBB", ["AAA", "ZZZ"]}
|
||
|
"""
|
||
|
def parse_instruction(src) do
|
||
|
[key, tuple] = String.split(src, " = ")
|
||
|
|
||
|
destinations =
|
||
|
tuple
|
||
|
|> String.slice(1..-2//1)
|
||
|
|> String.split(", ")
|
||
|
|
||
|
{key, destinations}
|
||
|
end
|
||
|
end
|