Day 10
Mix.install([
{:kino, "~> 0.14.2"}
])
IEx.Helpers.c("/Users/johnb/dev/2015adventOfCode/advent_of_code.ex")
alias AdventOfCode, as: AOC
alias Kino.Input
require Integer
use Bitwise
# Note: when making the next template, something like this works well:
# `cat day01.livemd | sed 's/01/02/' > day02.livemd`
#
Installation and Data
input_p1example = Kino.Input.textarea("Example Data")
input_p1puzzleInput = Kino.Input.textarea("Puzzle Input")
input_source_select =
Kino.Input.select("Source", [{:example, "example"}, {:puzzle_input, "puzzle input"}])
p1data = fn ->
(Kino.Input.read(input_source_select) == :example &&
Kino.Input.read(input_p1example)) ||
Kino.Input.read(input_p1puzzleInput)
end
Part 1
defmodule Day10 do
def look_and_say(text) do
text
|> String.split("", trim: true)
|> Enum.chunk_every(2, 1)
|> Enum.reduce({1, []}, fn pair, {count, next_line} ->
cond do
Enum.count(pair) == 1 ->
(next_line ++ ["#{count}", List.first(pair)])
|> Enum.join()
List.first(pair) == List.last(pair) -> {count + 1, next_line}
true -> {1, next_line ++ ["#{count}", List.first(pair)]}
end
end)
# |> IO.inspect()
end
def solve1(text) do
IO.inspect([String.length(text), text])
Enum.reduce(1..40, text, fn iteration, acc ->
str = look_and_say(acc)
IO.inspect([iteration, Time.utc_now(), String.length(str)])
str
end)
# |> IO.inspect()
|> String.length()
end
def solve2(text) do
# Switch to a regex to make it much much faster
#. https://stackoverflow.com/questions/47402863/regex-to-match-number-with-different-digits-and-minimum-length
Enum.reduce(1..50, text, fn iteration, acc ->
str = Regex.scan(~r/(\d)\1*(?!\1)/, acc)
|> Enum.map(fn [match, char] ->
"#{String.length(match)}#{char}"
end)
|> Enum.join()
IO.inspect([iteration, Time.utc_now(), String.length(str)])
str
end)
|> String.length()
end
end
# Example data:
# 1
# 11
# 21
# 1211
# 111221
# 312211
# p1data.()
# |> Day10.solve1()
# |> IO.inspect(label: "\n*** Part 1 solution (example: 6 for 5 iterations, 82350 for 40 iterations)")
# 492982 after ~20 min
p1data.()
|> Day10.solve2()
|> IO.inspect(label: "\n*** Part 2 solution (example: 2)")
# 50 iterations... 6989950 in less than a minute