Powered by AppSignal & Oban Pro

2023 - day 1

2023/elixir/day-1.livemd

2023 - day 1

Mix.install([
  {:kino_aoc, "~> 0.1.5"}
])

Section

sample_input = """
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
"""
{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2023", "1", System.fetch_env!("LB_SESSION"))

Part 1

defmodule Part1 do
  def solve(input) do
    input
    |> String.trim()
    |> String.split("\n")
    |> Enum.map(&parse_to_num/1)
    |> Enum.sum()
  end

  defp parse_to_num(str, first \\ nil, last \\ nil)

  defp parse_to_num("", first, last) do
    first * 10 + last
  end

  defp parse_to_num(<>, first, _) when num in ?0..?9 do
    first = first || num - ?0
    parse_to_num(rest, first, num - ?0)
  end

  defp parse_to_num(<<_::utf8, rest::binary>>, first, last) do
    parse_to_num(rest, first, last)
  end
end

Part1.solve(sample_input)
Part1.solve(puzzle_input)

Part2

defmodule Part2 do
  def solve(input) do
    input
    |> String.trim()
    |> String.split("\n")
    |> Enum.map(&amp;parse_to_num/1)
    |> Enum.sum()
  end

  def parse_to_num(str, first \\ nil, last \\ nil)

  def parse_to_num("", first, last) when first in 1..9 and last in 1..9 do
    first * 10 + last
  end

  for {name, n} <-
        Enum.with_index(
          ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"],
          1
        ) do
    def parse_to_num(unquote(name) <> _rest = str, first, _) do
      num = unquote(n)
      first = first || num
      <<_::utf8, rest::binary>> = str
      parse_to_num(rest, first, num)
    end
  end

  def parse_to_num(<>, first, _) when num in ?1..?9 do
    first = first || num - ?0
    parse_to_num(rest, first, num - ?0)
  end

  def parse_to_num(<<_::utf8, rest::binary>>, first, last) do
    parse_to_num(rest, first, last)
  end
end

sample_input = """
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
"""

Part2.solve(sample_input)
Part2.solve(puzzle_input)