Powered by AppSignal & Oban Pro

Day 1

elixir/Day 1.livemd

Day 1

Part 1

defmodule Day1 do
  def first_number(list) do
    Enum.map(list, &Integer.parse/1)
    |> Enum.find(fn n -> n != :error end)
    |> elem(0)
  end
end
{:module, Day1, <<70, 79, 82, 49, 0, 0, 7, ...>>, {:first_number, 1}}
lines = String.split(File.read!("../input/day1.txt"), "\n", trim: true)

firsts =
  Enum.map(lines, &String.codepoints/1)
  |> Enum.map(&Day1.first_number/1)
  |> Enum.map(fn n -> n * 10 end)
  |> Enum.sum()

lasts =
  Enum.map(lines, &String.codepoints/1)
  |> Enum.map(&Enum.reverse/1)
  |> Enum.map(&Day1.first_number/1)
  |> Enum.sum()

firsts + lasts
55621

Part 2

defmodule Parser do
  def parse(func, interval, line) do
    letters = [
      {"1", 1},
      {"2", 2},
      {"3", 3},
      {"4", 4},
      {"5", 5},
      {"6", 6},
      {"7", 7},
      {"8", 8},
      {"9", 9},
      {"one", 1},
      {"two", 2},
      {"three", 3},
      {"four", 4},
      {"five", 5},
      {"six", 6},
      {"seven", 7},
      {"eight", 8},
      {"nine", 9}
    ]

    values =
      Enum.filter(letters, fn {k, _} -> func.(line, k) end)
      |> Enum.map(fn {_, v} -> v end)

    case values do
      [] -> parse(func, interval, String.slice(line, interval))
      [hd | _] -> hd
    end
  end

  def first(string) do
    parse(&String.starts_with?/2, 1..-1, string)
  end

  def last(string) do
    parse(&String.ends_with?/2, 0..-2, string)
  end
end
{:module, Parser, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:last, 1}}
lines = String.split(File.read!("../input/day1.txt"), "\n", trim: true)

first =
  Enum.map(lines, &Parser.first/1)
  |> Enum.map(fn n -> n * 10 end)
  |> Enum.sum()

last =
  Enum.map(lines, &Parser.last/1)
  |> Enum.sum()

first + last
53592