53 lines
1 KiB
Elixir
53 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
|