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

Advent of Code 2023

2023/day01.livemd

Advent of Code 2023

Mix.install([
  {:req, "~> 0.3.2"}
])

Day 1

input =
  "https://adventofcode.com/2023/day/1/input"
  |> Req.get!(headers: [cookie: "session=#{System.get_env("AOC_COOKIE")}"])
  |> Map.get(:body)
sample = """
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
"""
sample2 = """
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
"""
defmodule A do
  def parse(input) do
    input
    |> String.split("\n", trim: true)
  end

  def first_and_last_digits(lines) do
    lines
    |> Enum.map(fn line ->
      [_, a] = Regex.run(~r/^[^\d]*(\d)/, line)
      [_, b] = Regex.run(~r/(\d)[^\d]*$/, line)

      [a, b]
      |> Enum.join("")
      |> String.to_integer()
    end)
  end

  def part1(input) do
    parse(input)
    |> first_and_last_digits()
    |> Enum.sum()
  end

  def part2(input) do
    parse(input)
    |> Enum.map(fn line ->
      a =
        Regex.replace(
          ~r/(one|two|three|four|five|six|seven|eight|nine)/,
          line,
          fn _, match ->
            case match do
              "one" -> "1"
              "two" -> "2"
              "three" -> "3"
              "four" -> "4"
              "five" -> "5"
              "six" -> "6"
              "seven" -> "7"
              "eight" -> "8"
              "nine" -> "9"
            end
          end
        )

      b =
        Regex.replace(
          ~r/(eno|owt|eerht|ruof|evif|xis|neves|thgie|enin)/,
          String.reverse(line),
          fn _, match ->
            case match do
              "eno" -> "1"
              "owt" -> "2"
              "eerht" -> "3"
              "ruof" -> "4"
              "evif" -> "5"
              "xis" -> "6"
              "neves" -> "7"
              "thgie" -> "8"
              "enin" -> "9"
            end
          end
        )

      c = String.replace(a, ~r/[^\d]/, "")
      d = String.replace(b, ~r/[^\d]/, "")

      # [line, a, b, c, d, String.first(c), String.first(d)]
      [String.first(c), String.first(d)]
      |> Enum.join("")
      |> String.to_integer()
    end)
    |> Enum.sum()
  end
end

Part 1

input
|> A.part1()

Part 2

input
|> A.part2()