Advent of Code 2023 — Sharing our experiences

Criteo R&D
Criteo Tech Blog
Published in
11 min readFeb 1, 2024

Authors: Étienne Sanson, Matthieu Rondeau, Ines A., Ilyas Toumlit & Anisse Astier.

In Criteo, we are passionate experts, but there is always more to learn. That passion motivates us to participate actively in code challenges such as Advent of Code. Also, this year, we decided to support the initiative by becoming a sponsor. That definitely boosted our participation and the involvement of our Criteos.

Join us along for this last 2023 edition journey.

What is Advent of Code?

As Eric Wastl, the creator of AoC, explains on its website:

Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like. People use them for interview prep, company training, university coursework, practice problems, a speed contest, or to challenge each other.

You don’t need a computer science background to participate — just a little programming knowledge and some problem-solving skills will get you pretty far. Nor do you need a fancy computer; every problem has a solution that completes in at most 15 seconds on ten-year-old hardware.

2023 was the 9th edition, and a bunch of our Criteos were involved day after day. Specifically, we had over 70 people who solved at least one of the challenges (53 in 2022). Our private leaderboard perfectly reflects motivation and engagement. We ended up with the following results:

Criteo’s R&D private leaderboard

There was a Slack channel where people shared their thoughts (and spoilers) daily. It’s incredible how an initiative like AoC can create that atmosphere. Everyone was quite active and loved discussing the daily problems. That channel was on fire all the time 🔥 with over 150 people on it.

Fun fact: Do you want to know which programming languages were used?

Programming languages used by Criteos

Experiences from our Criteos

Let’s now share some personal experiences from people inside R&D. We asked them questions about their participation in the AoC.

Étienne’s experience

What’s been the challenge that you liked the most and why?

Day 10, Pipe Maze. Part 2 was about counting the number of cells inside a region of a map. I naturally thought about solving it with a flood fill algorithm, but some specifics of the puzzle made it not so straightforward to apply it. I was happy to come up with a trick consisting of expanding the map so that a standard flood fill could be applied. Although it may seem obvious afterward, I was surprised to see that others came up with the exact same idea.
I also liked that I realized afterward that there were multiple methods to solve this, some of which were much simpler and more elegant than the one I came up with. One is based on ray-tracing, which I was disappointed not to have considered.
Another one, which I used in a later puzzle, was based on formulas to compute the area of a polygon on a grid. This one may have been quite simple to implement.

What’s been the most difficult day and why?

There were many difficult puzzles on which I struggled.
While not the most difficult one in the absolute, Day 5 difficulty stood out as coming early in the month.
But maybe the one I found the most difficult was Day 21.
I struggled a lot, first, to understand how to solve the problem (for Part 2), which was dependent on the specificities of the input. It took me a long time to figure out, partly because these specificities weren’t present in the test input.
Then, I struggled to actually code the solution, which required me to be very methodic and rigorous, and I (almost) failed at it.
I spent a few hours on it, with almost one full final hour to read and re-read my code, searching for a bug I couldn’t find, knowing that the output I got wasn’t right. Finally, as a very last attempt before giving up, I just swapped two values in the computation of the output, and I got it right. The frustration of not understanding why I had to do that was outweighed by the relief of getting the right answer!

What language did you use? Did you learn something new?

I used C#.
It was really enriching to see how others, at Criteo and more broadly, solved the challenges.
I learned some tricks to make my code more concise, and I learned a few algorithms along the way that I didn’t know, like how to find the minimum cut of a graph (Karger’s algorithm), or how to compute a polygon’s area based on its vertices coordinates (Shoelace formula, Pick’s theorem).

Why did you participate? How would you encourage people to participate in the following editions?

I have no longer been coding in my day-to-day activities for many years, so when I heard about the Advent Of Code, I thought it would be a good challenge to see if I wasn’t too rusty. In addition, I like puzzles.
I would encourage people to participate in the next editions as it’s a fun challenge, but I would warn them that it can be very time-consuming if they want to get all 50 stars. Happily, it’s only one month a year!

Anecdote time! For one of the puzzles, I lost an entire hour checking, again and again, my code because I couldn’t find why my answer wasn’t the right one, only realizing after much effort that I had changed the input earlier at some point for testing and forgot to change it back to its original value.

Photo by Florian Olivo on Unsplash

Matthieu’s highlights

What’s been the challenge that you liked the most and why?

I think the one I liked the most was Day 11 because I quickly found a solution that would work for the second part as well, and it made me very proud.

What’s been the most difficult day and why?

I struggled with many ​of them 😄

But if I needed to take only one, I guess it would be Day 17; since I did not know “Breadth-first search” (BFS) at first, I went for such bad solutions. It was a bad Sunday morning, and I should thank my wife for putting up with me and my anger!

What language did you use? Did you learn something new?

Ruby.
I learned a lot, like each year, I guess. The most obvious one would be the usage of a solver (z3 in my case) for Day 23.

Why did you participate? How would you encourage people to participate in the following editions?

I have participated since the beginning of the Advent of Code. This friend of mine showed it to me the first time, and I still participate with him and ex-colleges I met over the years. I really enjoy the problems, but I enjoy comparing solutions with my friends the most.
I guess if I were to encourage people to participate, I would say first, it’s a good opportunity to try new languages or use one you don’t use at work (for me, not using ruby at Criteo makes me a bit sad). Also it a good opportunity to strenghten your skills. And it’s fun :D

Photo by Desola Lanre-Ologun on Unsplash

Ines’ takeaways

What’s been the challenge that you liked the most and why?

I enjoyed Day 19. AOC often has problems whose Part 1 you can easily brute-force, followed by a Part 2 that forces you to rethink your approach & come up with a smarter solution. Day 19’s Part 2 reveal was a lot of fun — working my way through the sample problem with pen & paper, coming up with the idea to work with a queue of processed ranges & then implementing it.

What’s been the most difficult day and why?

Probably Day 24. Part 2 was very math-intensive & I was also not in the mood for a hard puzzle on Christmas Eve. After banging my head against the wall for a while, I gave up & took a look at some of the solutions on Reddit.

What language did you use? Did you learn something new?

I used Python! I’m also hoping to re-do some of these puzzles in Java or C# once I have the time, as a way to practice using those languages.

Why did you participate? How would you encourage people to participate in the following editions?

AoC is a fun way to learn or get better at a language & will present you with many interesting puzzles. The first fifteen or so puzzles are usually pretty beginner-friendly, so I’d recommend starting with those & not worrying too much about times/ranking (though a bit of friendly competition never hurts!)

Anisse’s remarks

What’s been the challenge that you liked the most and why?

I would say Day 16, “The Floor Will be Lava”. For a very simple reason: the day before, I decided to skip the problem launch time (6 AM in Paris), so I woke up a bit later but with enough sleep to solve the problem with no hiccups.

It used grid problems tricks I had learned in other Advent of Code problems (iterate over offsets, check boundaries, use an integer for direction, and add-modulo for rotations), so I solved it relatively straightforwardly with a recursive solution.

What’s been the most difficult day and why?

Day 24, “Never Tell Me The Odds”, mostly because of Part 2: it required a lot of math, and I couldn’t converge to a solution in a few hours. After trying a brute-force approach that worked with the example (but not the input), I decided to use a generic math solver (z3) instead.

Then it was Day 21, “Step Counter”, on which Part 2 took me over ten tries. I quickly understood that shortcuts could be taken based on the input and problem constraints, but even then, it took quite a while. I had to write custom tests since the examples weren’t really useful for my input-tailored solution.

What language did you use? Did you learn something new?

This year again, I used Rust. Yes, I learned quite a few new things.

One of the challenges I put to myself this year was to solve the puzzle parts in a single pass, where possible. However, I still wanted the parsing to be separate from the algorithmic resolution. For that, I used Rust Iterators: the parsing function returns an Iterator, and it is consumed just-in-time during resolution. This approach worked well for 11 of the 25 puzzles, showing that this approach was viable in some cases, but not always: it depends on the problem at hand. But I learned enough to be able to identify the type of problems where this can be done.

Another trick I learned was to use tuples a bit more: in Rust, they are comparable, hashable, and have default values because tuples of twelve or fewer elements implement the appropriate PartialEq, Eq, Hash, or Default traits (and others). Writing shorter code, sorting a list of tuples, or initializing them with Default::default() is quite helpful.

I wrote about other things I learned in Rust on my blog 👇

Why did you participate? How would you encourage people to participate in the following editions?

I participate mainly to learn.

To fully enjoy Advent of Code, it is important that participation comes from within. In my opinion, the best approach is to begin with the first few days and gauge what you find feasible and whether solving quick puzzles brings you joy. Establish your own objectives and focus on competing with yourself above all else.

I would recommend people either try to consolidate what they know about a given language or use it to learn a new programming language.

Photo by Christopher Gower on Unsplash

Ilyas’ notes

What’s been the challenge that you liked the most and why?

One challenge that stands out from the Advent of Code is Day 21, “Step Counter”. It’s a path-finding problem with bounded steps, where we need to help the Elves maximize the garden plots they can reach on the puzzle input. What I enjoyed most about this challenge was how it started off seemingly simple but quickly escalated in complexity.
I found this challenge to be incredibly rewarding. It pushed me to learn new concepts and improve my coding skills. Plus, the sense of accomplishment I felt after solving it.

What’s been the most difficult day and why?

Pretty much related to the previous one, Day 23, “A Long Walk,” was the one that took the most time to solve for me this year. The problem required both a deep understanding of the rules and an efficient implementation to solve within a reasonable time frame. It was not just about writing code but also about optimizing it.
It also required a good understanding of graph theory and pathfinding algorithms. Implementing an efficient solution requires careful consideration of data structures and algorithm design. It was a real test of my problem-solving and programming abilities.
This challenge pushed me to think more deeply about the data structures I was using and how I could leverage their properties to improve my solution’s performance.

What language did you use? Did you learn something new?

I used Java 21. Advent of Code is an occasion for me to explore this new Java version and remind myself about basic algorithms and data structures.

Why did you participate? How would you encourage people to participate in the following editions?

Advent of Code is a nice opportunity to improve my programming skills, remind myself about basic algorithms concepts, and challenge myself in a fun and engaging way.
It was also great to share the challenge with Criteos, we were many to participate, discuss different approaches and learn from others, it’s a great way to connect.

Ok, ok, stop talking… show me the code! 💻

Sure thing! Check out the solutions that our Criteos uploaded to GitHub for this last 2023 Advent of Code: Matthieu & Anisse.

Also, check hyper-neutrino — Overview YT videos with the solutions:

Did you like the article? Would you like to be part of this incredible team? This article is an excellent example of our culture and values. Check our website to learn more about us and our positions.

--

--

Criteo R&D
Criteo Tech Blog

The R&D team building the Commerce Media Platform for the Open Internet.