Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 14

live/day14.livemd

Day 14

Mix.install([
  {:kino, "~> 0.6.2"}
])

Input

input = Kino.Input.textarea("In put here:")
[polymer, table] =
  input
  |> Kino.Input.read()
  |> String.split("\n\n", trim: true)

template = polymer |> to_charlist |> Enum.chunk_every(2, 1, [0])

pairs =
  table
  |> String.split("\n")
  |> Map.new(fn < ", c>> -> {[a, b], c} end)
defmodule Chem do
  def polymerize(map, pol, n) do
    Enum.reduce(1..n, pol, fn _, pol ->
      Enum.flat_map(pol, fn
        [a, b] = pair ->
          case map do
            %{^pair => [o]} -> [[a, o], [o, b]]
            %{} -> [pair]
          end

        c ->
          [c]
      end)
    end)
  end
end

Part 1

freqs =
  pairs
  |> Chem.polymerize(template, 10)
  |> Enum.map(&amp;hd/1)
  |> IO.inspect()
  |> tap(&amp;IO.inspect(length(&amp;1)))
  |> Enum.frequencies()
  |> Enum.map(fn {k, v} -> {[k], v} end)
  |> Enum.into(%{})
  |> IO.inspect()
  |> Map.values()

Enum.max(freqs) - Enum.min(freqs)

Part 2

template = Enum.frequencies(template)
{{_, mins}, {_, maxes}} =
  1..40
  |> Enum.reduce(template, fn n, template ->
    IO.inspect(n)

    Enum.reduce(template, %{}, fn {[a, b] = tok, cnt}, acc ->
      case pairs do
        %{^tok => o} ->
          acc
          |> Map.update([a, o], cnt, &amp;(&amp;1 + cnt))
          |> Map.update([o, b], cnt, &amp;(&amp;1 + cnt))

        %{} ->
          Map.put(acc, tok, cnt)
      end
    end)
  end)
  |> Enum.group_by(&amp;hd(elem(&amp;1, 0)), &amp;elem(&amp;1, 1))
  |> Enum.min_max_by(fn {_, counts} -> Enum.sum(counts) end)

Enum.sum(maxes) - Enum.sum(mins)