2021 day 14 part 1, naive
This commit is contained in:
parent
ff42567b1a
commit
a1ad866646
1 changed files with 99 additions and 0 deletions
99
2021/lib/2021/14.ex
Normal file
99
2021/lib/2021/14.ex
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import AOC
|
||||||
|
|
||||||
|
aoc 2021, 14 do
|
||||||
|
use AOCHelpers
|
||||||
|
|
||||||
|
def input(input_string \\ input_string()) do
|
||||||
|
[sequence, insertion_mappings_string] =
|
||||||
|
input_string
|
||||||
|
|> String.split("\n\n", trim: true)
|
||||||
|
|
||||||
|
insertion_mappings =
|
||||||
|
insertion_mappings_string
|
||||||
|
|> String.split("\n", trim: true)
|
||||||
|
|> Enum.map(fn line ->
|
||||||
|
[from, to] = String.split(line, " -> ")
|
||||||
|
{from, to}
|
||||||
|
end)
|
||||||
|
|> Map.new()
|
||||||
|
|
||||||
|
{sequence, insertion_mappings}
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform_insertions(<<a::binary-size(1), b::binary-size(1), rest::binary>>, mappings) do
|
||||||
|
case Map.fetch(mappings, a <> b) do
|
||||||
|
{:ok, c} -> a <> c <> perform_insertions(b <> rest, mappings)
|
||||||
|
_ -> a <> perform_insertions(b <> rest, mappings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform_insertions(base, _), do: base
|
||||||
|
|
||||||
|
def perform_insertions_lossy(sequence, mappings) when is_binary(sequence),
|
||||||
|
do:
|
||||||
|
sequence
|
||||||
|
|> to_frequencies()
|
||||||
|
|> perform_insertions_lossy(mappings)
|
||||||
|
|
||||||
|
def perform_insertions_lossy({letter_freqs, pair_freqs}, mappings) do
|
||||||
|
[pair_ops, letter_ops] =
|
||||||
|
for {from, to} <- mappings, Map.has_key?(pair_freqs, from) do
|
||||||
|
existing_pairs = Map.get(pair_freqs, from, 0)
|
||||||
|
# Additional letters
|
||||||
|
<<front::binary-size(1), back::binary-size(1)>> = from
|
||||||
|
|
||||||
|
{[{from, -existing_pairs}, {front <> to, existing_pairs}, {to <> back, existing_pairs}],
|
||||||
|
[{to, existing_pairs}]}
|
||||||
|
end
|
||||||
|
|> Enum.unzip()
|
||||||
|
|> Tuple.to_list()
|
||||||
|
|> Enum.map(&List.flatten/1)
|
||||||
|
|
||||||
|
letter_freqs = apply_ops(letter_freqs, letter_ops)
|
||||||
|
pair_freqs = apply_ops(pair_freqs, pair_ops)
|
||||||
|
|
||||||
|
{letter_freqs, pair_freqs}
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_ops(map, ops) do
|
||||||
|
map
|
||||||
|
|> Enum.concat(ops)
|
||||||
|
|> Enum.group_by(&elem(&1, 0), &elem(&1, 1))
|
||||||
|
|> Enum.map(fn {k, v} -> {k, Enum.sum(v)} end)
|
||||||
|
|> Map.new()
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_frequencies(sequence) do
|
||||||
|
sequence_list = String.split(sequence, "", trim: true)
|
||||||
|
pairs_list = Enum.zip_with(sequence_list, Enum.drop(sequence_list, 1), &<>/2)
|
||||||
|
|
||||||
|
letter_frequencies = sequence_list |> Enum.frequencies()
|
||||||
|
pair_frequencies = pairs_list |> Enum.frequencies()
|
||||||
|
|
||||||
|
{letter_frequencies, pair_frequencies}
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate_score_of_iteration(input \\ input(), n) do
|
||||||
|
{final_sequence, _} =
|
||||||
|
iterate(n, input, fn {sequence, mappings} ->
|
||||||
|
next = perform_insertions(sequence, mappings)
|
||||||
|
{next, mappings}
|
||||||
|
end)
|
||||||
|
|
||||||
|
{{_, min}, {_, max}} =
|
||||||
|
final_sequence
|
||||||
|
|> String.split("", trim: true)
|
||||||
|
|> Enum.frequencies()
|
||||||
|
|> Enum.min_max_by(&elem(&1, 1))
|
||||||
|
|
||||||
|
max - min
|
||||||
|
end
|
||||||
|
|
||||||
|
def p1, do: calculate_score_of_iteration(10)
|
||||||
|
|
||||||
|
def p2 do
|
||||||
|
{sequence, _mappings} = input()
|
||||||
|
|
||||||
|
to_frequencies(sequence)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue