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

Day 01

day_01.livemd

Day 01

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

Input

{:ok, raw_input} =
  KinoAOC.download_puzzle("2023", "1", System.fetch_env!("LB_AOC_SESSION"))
parse = fn input ->
  input
  |> String.trim()
  |> String.split("\n")
end
input = parse.(raw_input)
input_example =
  parse.("""
  1abc2
  pqr3stu8vwx
  a1b2c3d4e5f
  treb7uchet
  """)
input_example_2 =
  parse.("""
  two1nine
  eightwothree
  abcone2threexyz
  xtwone3four
  4nineeightseven2
  zoneight234
  7pqrstsixteen
  """)

Utils

defmodule Util do
  def parse_number(input) do
    {num, _leftovers} = Integer.parse(input)
    num
  end

  def is_digit("0"), do: true
  def is_digit("1"), do: true
  def is_digit("2"), do: true
  def is_digit("3"), do: true
  def is_digit("4"), do: true
  def is_digit("5"), do: true
  def is_digit("6"), do: true
  def is_digit("7"), do: true
  def is_digit("8"), do: true
  def is_digit("9"), do: true
  def is_digit(_), do: false

  def word_to_digit("zero"), do: "0"
  def word_to_digit("one"), do: "1"
  def word_to_digit("two"), do: "2"
  def word_to_digit("three"), do: "3"
  def word_to_digit("four"), do: "4"
  def word_to_digit("five"), do: "5"
  def word_to_digit("six"), do: "6"
  def word_to_digit("seven"), do: "7"
  def word_to_digit("eight"), do: "8"
  def word_to_digit("nine"), do: "9"
end

Part 1

defmodule Part1 do
  def calculate(input) do
    input
    |> Enum.map(&String.split(&1, "", trim: true))
    |> Enum.map(fn line ->
      Enum.filter(line, &Util.is_digit/1)
    end)
    |> Enum.map(fn line ->
      List.first(line) <> List.last(line)
    end)
    |> Enum.map(&amp;Util.parse_number/1)
    |> Enum.sum()
  end
end
Part1.calculate(input_example)
Part1.calculate(input)

Part 2

defmodule Part2 do
  @replacements [
    {"one", "one1one"},
    {"two", "two2two"},
    {"three", "three3three"},
    {"four", "four4four"},
    {"five", "five5five"},
    {"six", "six6six"},
    {"seven", "seven7seven"},
    {"eight", "eight8eight"},
    {"nine", "nine9nine"}
  ]

  def replace_words_with_numbers(input) do
    for {word, worse_word} <- @replacements, reduce: input do
      str -> String.replace(str, word, worse_word)
    end
  end

  def calculate(input) do
    input
    |> Enum.map(&amp;replace_words_with_numbers/1)
    |> Part1.calculate()
  end
end
Part2.calculate(input_example_2)
Part2.calculate(input)