code-shoily

code-shoily

Here’s my day 3 code

https://github.com/code-shoily/advent_of_code/blob/master/lib/2024/day_03.ex

This was quite easy. I was afraid Part 2 would be “un-regex-able” and was preparing for hand crafting automata but looks like it wasn’t the case. Also, nice to have that Toboggan reference. I love cross-overs.

Showing Posts 1 to 10

egze

egze

Part 1:

defmodule Part1 do
  def scan(input) do
    Regex.scan(~r/mul\((\d{1,3}),(\d{1,3})\)/, input, capture: :all_but_first)
    |> Enum.reduce(0, fn [a, b], acc ->
      acc + String.to_integer(a) * String.to_integer(b)
    end)
  end
end

Part 2:

defmodule Part2 do
  def scan(input, enabled \\ :enabled, acc \\ 0)

  def scan(input, :enabled, acc) do
    case Regex.split(~r/don't\(\)/, input, parts: 2) do
      [valid, rest] -> scan(rest, :disabled, acc + Part1.scan(valid))
      [valid] -> acc + Part1.scan(valid)
    end
  end

  def scan(input, :disabled, acc) do
    case Regex.split(~r/do\(\)/, input, parts: 2) do
      [_invalid, rest] -> scan(rest, :enabled, acc)
      [_invalid] -> acc
    end
  end
end
mwilsoncoding

mwilsoncoding

Here are my solutions for today. (if another thread for this pops up, I’ll try to delete it. My version of this thread is still pending approval :laughing: )

Part 1:

defmodule Day3.Part1 do
  def solve() do
    File.stream!("03/input.txt")
    |> Enum.reduce(
      0,
      fn line, acc ->
        acc +
          (~r/mul\((\d{1,3}),(\d{1,3})\)/
           |> Regex.scan(line |> String.trim(), capture: :all_but_first)
           |> Enum.reduce(
             0,
             fn [a, b], acc -> acc + String.to_integer(a) * String.to_integer(b) end
           ))
      end
    )
    |> IO.puts()
  end
end

Day3.Part1.solve()

Part 2:

defmodule Day3.Part2 do
  defp sum_part(part) do
    ~r/mul\((\d{1,3}),(\d{1,3})\)/
    |> Regex.scan(part, capture: :all_but_first)
    |> Enum.reduce(
      0,
      fn [a, b], acc -> acc + String.to_integer(a) * String.to_integer(b) end
    )
  end

  def solve() do
    File.stream!("03/input.txt")
    |> Enum.reduce(
      {0, true},
      fn line, {acc, start_enabled?} ->
        {acc +
           (line
            |> String.trim()
            |> String.split("do")
            |> (fn parts ->
                  if start_enabled? do
                    parts
                  else
                    parts
                    |> Enum.drop(1)
                  end
                end).()
            |> Enum.filter(&(not String.starts_with?(&1, "n't()")))
            |> Enum.map(&sum_part/1)
            |> Enum.sum()),
         ~r/do\(\)/
         |> Regex.scan(line, capture: :all, return: :index)
         |> List.last()
         |> List.last()
         |> elem(0) >
           ~r/don't\(\)/
           |> Regex.scan(line, capture: :all, return: :index)
           |> List.last()
           |> List.last()
           |> elem(0)}
      end
    )
    |> elem(0)
    |> IO.puts()
  end
end

Day3.Part2.solve()
sevenseacat

sevenseacat

Author of Ash Framework

I haven’t used regex in a while - made a few dumb mistakes before getting it right, lol.

https://github.com/sevenseacat/advent_of_code/blob/main/lib/y2024/day03.ex

Aetherus

Aetherus

Thanks for your regex. It’s the first time I saw (?>pattern) in a regex.

Here’s my solution:

Part 1

~r/
  (?<=mul\()  # prefixed by "mul("  (positive lookbehind, not captured)
  (\d{1,3})   # max-3-digit number  (captured)
  ,           # matches a comma     (not captured)
  (\d{1,3})   # max-3-digit number  (captured)
  (?=\))      # suffixed by ")"     (positive lookahead, not captured)
/x
|> Regex.scan(puzzle_input, capture: :all_but_first)
|> List.flatten()
|> Enum.map(&String.to_integer/1)
|> Enum.chunk_every(2)
|> Enum.map(fn [a, b] -> a * b end)
|> Enum.sum()

Part 2

~r/
  (do\(\))     # matches "do()" (captured)
  |            # or
  (don't\(\))  # matches "don't()" (captured)
  |            # or
  (?<=mul\()(\d{1,3}),(\d{1,3})(?=\))  # matches the same pattern as in Part 1, captures only the numbers
/x
|> Regex.scan(puzzle_input, capture: :all_but_first)
|> Enum.map(fn
  ["do()"] -> :on
  ["", "don't()"] -> :off
  ["", "", a, b] -> {String.to_integer(a), String.to_integer(b)}
end)
|> Enum.reduce({0, :on}, fn
  :on, {sum, _} -> {sum, :on}
  :off, {sum, _} -> {sum, :off}
  {a, b}, {sum, :on} -> {sum + a * b, :on}
  _, acc -> acc
end)
|> elem(0)
Flo0807

Flo0807

Hey!

This is my solution for Day 03.

Part 1

Regex.scan(~r/mul\((\d+),(\d+)\)/, puzzle_input, capture: :all_but_first)
|> Enum.map(fn [a, b] ->
  String.to_integer(a) * String.to_integer(b)
end)
|> Enum.sum()

Part 2

Regex.scan(~r/mul\((-?\d+),(-?\d+)\)|do(?:n't)?\(\)/, puzzle_input)
|> Enum.reduce({0, :enabled}, fn
  ["don't()"], {count, _status} ->
    {count, :disabled}

  ["do()"], {count, _status} ->
    {count, :enabled}

  [_text, a, b], {count, :enabled} ->
    result = String.to_integer(a) * String.to_integer(b)

    {result + count, :enabled}

  [_text, _a, _b], {count, :disabled} ->
    {count, :disabled}
end)
|> elem(0)
code-shoily

code-shoily OP

I just realized I could just have one function with regex as an additional parameter. (In case of first, adding true on both cases unlocks the whole list for processing)

code-shoily

code-shoily OP

I love it. Saves me a lot of “emptiness” lol.

bjorng

bjorng

Erlang Core Team

I went for a solution using regexes and regretted it almost immediately. It took me a while to realize that Regex.run/3 with the :global option will not return multiple solutions (as :re.run/3 would), but that I needed to use Regex.scan/3. Fortunately, having invested a lot of time solving part 1 with a regex, it turned out it was possible to solve also part 2 with a regex.

https://github.com/bjorng/advent-of-code/blob/main/2024/day03/lib/day03.ex

Having tried regexes, I decided to implement a solution in Erlang using the binary syntax to do the parsing:

https://github.com/bjorng/advent-of-code/blob/main/2024/day03/day03.escript

UPDATE: After looking at the other solutions, I realized that I only looked for do and don't instead of do() and don't(). That happened to produce the correct result (at least for my input), but I’ve now updated my programs to match the parens too.

code-shoily

code-shoily OP

This is the way.

Where Next? Top

Trending in Challenges Top

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews