-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_05.ex
53 lines (46 loc) · 1.54 KB
/
day_05.ex
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
defmodule AdventOfCode.Y2022.Day05 do
@moduledoc """
--- Day 5: Supply Stacks ---
Problem Link: https://adventofcode.com/2022/day/5
Difficulty: s
Tags: parse-heavy stack linked-list
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
def input, do: InputReader.read_from_file(2022, 5, false)
def run(input \\ input()) do
with input <- parse(input),
do: {top(transfer(input)), top(transfer(input, false))}
end
def parse(data \\ input()) do
[stacks, moves] = String.split(data, ~r{(\r\n\r\n|\r\r|\n\n)})
{parse_stacks(stacks), parse_moves(moves)}
end
defp transfer({stack, moves}, single? \\ true) do
Enum.reduce(moves, stack, fn {amount, source, target}, acc ->
{m, u} = Enum.split(acc[source], amount)
%{acc | source => u, target => ((single? && Enum.reverse(m)) || m) ++ acc[target]}
end)
end
defp parse_stacks(stacks) do
stacks
|> String.replace(~r"\[|\]", " ")
|> Transformers.lines()
|> Enum.map(fn row ->
row
|> String.split(" ")
|> Enum.map(&String.trim/1)
|> Enum.with_index(1)
end)
|> List.flatten()
|> Enum.slice(1..-2//1)
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
|> Map.new(fn {k, v} -> {k, Enum.drop_while(v, &(&1 == ""))} end)
end
defp parse_moves(moves) do
for move <- Transformers.lines(moves) do
[_, q, _, x, _, y] = Transformers.words(move)
{String.to_integer(q), String.to_integer(x), String.to_integer(y)}
end
end
defp top(xs), do: Enum.map_join(xs, fn {_, [x | _]} -> x end)
end