adamu

adamu

Advent of Code 2023 - Day 1

Nobody’s doing Advent of Code this year? :smile:

I might do the first week or so.

For Day 1, first I solved it using regular expressions and String.replace, which took about 10ms for each part.

Then I rewrote it using binaries and recursion, which got each part under 1ms.

  def filter_digits2(<<>>), do: <<>>
  def filter_digits2(<<x, rest::binary>>) when x in ?1..?9, do: <<x>> <> filter_digits2(rest)
  def filter_digits2(<<"one", rest::binary>>), do: "1" <> filter_digits2("e" <> rest)
  def filter_digits2(<<"two", rest::binary>>), do: "2" <> filter_digits2("o" <> rest)
  def filter_digits2(<<"three", rest::binary>>), do: "3" <> filter_digits2("e" <> rest)
  def filter_digits2(<<"four", rest::binary>>), do: "4" <> filter_digits2("r" <> rest)
  def filter_digits2(<<"five", rest::binary>>), do: "5" <> filter_digits2("e" <> rest)
  def filter_digits2(<<"six", rest::binary>>), do: "6" <> filter_digits2("x" <> rest)
  def filter_digits2(<<"seven", rest::binary>>), do: "7" <> filter_digits2("n" <> rest)
  def filter_digits2(<<"eight", rest::binary>>), do: "8" <> filter_digits2("t" <> rest)
  def filter_digits2(<<"nine", rest::binary>>), do: "9" <> filter_digits2("e" <> rest)
  def filter_digits2(<<_, rest::binary>>), do: filter_digits2(rest)

Most Liked

Aetherus

Aetherus

Just tried solving Day 1 puzzles using the low-code platform developed by my company :rofl:

There’s no function to split a string into lines, so I have to heavily rely on regular expressions.

By the way, the whole platform is powered by Elixir and Phoenix :grin:

kip

kip

ex_cldr Core Team

benchee is the go-to for benchmarking in Elixir. You can see my configuration in the bench directory in my advent_of_code repo.

To use it you would do mix run ./bench/bench.exs then sit back and relax :slight_smile:

APB9785

APB9785

Creator of ECSx

My first approach didn’t handle overlaps properly in part 2, so I ended up with a somewhat funky pattern match syntax:

defp process_line(["o", "n", "e" | _] = [_h | t], ...),
    do: process_line(t, ...)

There’s probably a cleaner way to do this, but it works!

Full solution here: https://github.com/APB9785/AoC-2023-elixir/blob/master/lib/day_01.ex

mruoss

mruoss

I approached part 2 from both sides :wink:

defmodule Task2 do
  @digits %{
    "one" => 1,
    "two" => 2,
    "three" => 3,
    "four" => 4,
    "five" => 5,
    "six" => 6,
    "seven" => 7,
    "eight" => 8,
    "nine" => 9
  }

  def solve(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(&convert_line/1)
    |> Enum.sum()
  end

  def convert_line(line) do
    10 * first_digit(line) + last_digit(String.reverse(line))
  end

  for digit <- 1..9 do
    string = Integer.to_string(digit)
    defp first_digit(<<unquote(string), _::binary>>), do: unquote(digit)
    defp last_digit(<<unquote(string), _::binary>>), do: unquote(digit)
  end

  for {string, digit} <- @digits do
    reverse_string = String.reverse(string)
    defp first_digit(<<unquote(string), _::binary>>), do: unquote(digit)
    defp last_digit(<<unquote(reverse_string), _::binary>>), do: unquote(digit)
  end

  defp first_digit(<<_::utf8, rest::binary>>), do: first_digit(rest)
  defp last_digit(<<_::utf8, rest::binary>>), do: last_digit(rest)
end
Askath

Askath

Took me way to long, as I misread the question. But was nice trying out elixir with a more difficult prolbem for the first time! really enjoyed it. Although my solution seems bruteforced :smiley:

defmodule Aoc1 do
  @moduledoc """
  Documentation for `Aoc1`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Aoc1.hello()
      :world

  """
  def first_and_last(string) do
    first = String.first(string)
    last = String.last(string)
    IO.puts("first: #{first}, last: #{last}")

    {first, last}
  end

  def read_file do
    case File.read("input") do
      {:ok, result} ->
        result

      {:error, error} ->
        IO.puts("Error: #{error}")
    end
  end

  def replace_spoken_numbers(list) do
    digits = [
      {"eighthree", 83},
      {"eightwo", 82},
      {"fiveight", 58},
      {"threeight", 38},
      {"sevenine", 79},
      {"oneight", 18},
      {"twone", 21},
      {"one", 1},
      {"two", 2},
      {"three", 3},
      {"four", 4},
      {"five", 5},
      {"six", 6},
      {"seven", 7},
      {"eight", 8},
      {"nine", 9},
      {"zero", 0}
    ]

    Enum.map(list, fn line ->
      Enum.reduce(digits, line, fn {word, digit}, acc ->
        String.replace(acc, word, Integer.to_string(digit))
      end)
    end)
  end

  def parse(file) do
    file |> String.split("\n", trim: true) |> replace_spoken_numbers()
  end

  def hello do
    numbers =
      parse(read_file())
      |> Enum.map(fn line ->
        Regex.replace(~r/[a-z]/, line, "") |> first_and_last()
      end)

    Enum.reduce(numbers, 0, fn {first, last}, acc ->
      num = first <> last
      IO.puts(num)
      acc = acc + String.to_integer(num)
      acc
    end)
    |> IO.inspect()
  end
end

Aoc1.hello()

Where Next?

Popular in Challenges Top

QuinnWilton
Note: This topic is to talk about Day 7 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can joi...
New
bjorng
This topic is about Day 16 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums): https://adve...
New
New
New
Aetherus
Today’s challenge is quite interesting. I ended up using Zipper to solve this problem. Maybe I overengineered quite a bit. The data stru...
New
stevensonmt
Anyone else think the prompt for this challenge is contradictory? The rules for comparing packets include If both values are lists, c...
New
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New
bjorng
This topic is about Day 18 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
connorlay
Note by the Moderators: This topic is for general discussion about the Advent of Code 2018. To prevent people from being spoiled about s...
New
seeplusplus
Hello all, hopefully I post this before someone else does and I don’t dupe. IMO Day 4 was much easier than Day 3 (yay, I can sleep befor...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement