2024 Day 3: Mull It Over

Maybe I didn’t need to write a whole lexer here, but I did, and I had fun. Reading compiler books over the last year has really made every problem look like a compiler problem.

advent/2024/src/day3_2.adb at c50aa046df3ffebd26cf525fd53d6ebb8d89bc25 · JeremyGrosser/advent · GitHub

1 Like

I did the exact opposite and simply used GNAT.Regpat :smile:

2 Likes

I also ended up writing a lexer because I was expecting part 2 to add a constraint like “expressions are actually nested.”

puzzles/AdventOfCode2024/src/day03.adb at 28e953807e27b67d9a5dca2f1901d9d0ed09cdb8 · jcmoyer/puzzles · GitHub

2 Likes

Completed part one using a sort of automaton like thing, jeez, it seemed like a lot of work! There’s a lot I need to learn to make my life easier, like lexers or Regpat!

Completed part 2, wasn’t so bad. Much better solutions by others… :sweat_smile::

And my approach for part one turns out to be very bad for part two :laughing:

Fiddled around with Ada for far too long on this one, gave up and just wrote it in Ruby. :tired_face:

def solve(str) = str
  .scan(/mul\((\d{1,3}),(\d{1,3})\)/)
  .sum { |a, b| a.to_i * b.to_i }

input = File.read("day03.txt")
puts solve input
puts solve input.gsub(/don't\(\)(.*?do\(\)|.*$)/m, "")

Respect to those who finished it in Ada.

1 Like

I didn’t know about Gnat Regpat (nor about 'Reduce, which was nice for Day 1). Every day a new trick.

So, I also did it with a state machine. I’ve done those quite a few times, so I can sort of write them in my head. Since there were no large overlapping prefixes, it was quite straight-forward (aoc2024/aoc202403b/src/parse_mul.adb at 966ee3ba6711a26e15131c2fca18cf8720f6ff2c · theovosse/aoc2024 · GitHub). When doing the second problem, I almost gave up, because it becomes quite repetitive. Anyway, that’s also when I discovered I had a potential bug in the state machine of the first solution. Still there, BTW, but it doesn’t affect the solution unless there’s something like “mumul(10,10)” in the input.

Great minds think alike, I solved it almost the exact same way.

1 Like

[fredpraca][3][Ada]RegPat solution

This one was easy when you figured out how to make RegPat working

I kind of approached it in a way I know is not scalable, but was easier for me to implement for the exercise. I just used Ada.Strings.Fixed.Index and searched for "do()", "don't()", and "mul(" (followed by some simple parsing for the rest of mul), save their starting locations, sorted the results based on the index I found them at, then ran through the logic with the sorted array (enabling for do, disabling for don’t, multiplying for mul when enabled).

EDIT: Though I kinda guessed at what part 2 required based on a few of the solutions linked here. I don’t have an AoC account setup to see it myself.

I still have part 2 to do, but already solved part one in a way that makes me extremely proud and most people probably think it is quite peculiar but… I used GNAT.Spitbol.Patterns and boy, I hate parsing, but once I made it work, my my, it is great!

The code can be summarized to:


   A_VStr, B_Vstr : VString;
   Digs : constant Pattern := Span("0123456789");
   Multiplicator_Pattern : constant Pattern := "mul(" & Digs ** A_VStr & ',' & Digs ** B_VStr & ')'; -- Please, read the documentation about GNAT.Spitbol.Patterns as found in g-spipat.ads

      while Match (Input_Line, Multiplicator_Pattern, "") loop
         pragma Debug(Put_Line("Matched Values: A = " & A_VStr & " B = " & B_VStr));
         A := Integer'Value(To_String(A_VStr));
         B := Integer'Value(To_String(B_VStr));
         Accumulator := Accumulator + A * B;
      end loop;
3 Likes

SPITBOL is vastly unknown/underutilized/underrated.

Welp… AoC is telling me that my second solution is wrong… But I visually inspected the first two input lines and the code worked at cleaning the don't()..do() pairs… So I do not know why AoC is telling me that my result is wrong… So I give up :confused:

If someone wants to take a look at why my code is wrong, feel free. I think my Spitbol solution is the cooler one though :stuck_out_tongue:

Best regards,
Fer

The do() and don't() logic applies to the input as a whole, not for each line separately. So if one line ends with

don't() xxx

and the next line starts with

yyy do() zzz

then yyy needs to be ignored as well. Seems like you would get this case wrong. (I made the same mistake at first…)

P.S. I agree, the Spitbol pattern solution looks pretty cool. :smile:

3 Likes

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

An append on the input (to create a single string) fixed this…

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Its done now. Thanks ^^

1 Like