SkillAgentSearch skills...

AoC2023

2023 Advent of Code in Ada

Install / Use

/learn @johnperry-math/AoC2023
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Advent of Code 2023 in Ada and :new: Rust! :crab: and even some :new: Modula-2!

<img src="ada_logo.svg" width="200">

Because 5 years of pain and suffering aren't enough. :grin: This year features an attempt to implement the same algorithm in both Ada and Rust. For fun, I throw in some Modula-2 from time to time... well, at least ~~once~~ ~~twice~~ thrice (Days 1, 3, and 10).

Mathematics and Computer Science

The following advanced concepts of mathematics and computer science showed up either in the puzzles or in my solutions to them:

  1. Modularity -- OK, maybe this isn't "advanced", but after completing the puzzles:
    • In Ada, I went back and created a Common package that contains code that I kept re-using; in particular, Location_Record and Map_Array and Read_Input for two-dimensional maps. I'm rather pleased with the result. Unfortunately, gnatdoc isn't the greatest system for documenting it.
  2. Programming by contracts (not as much as I'd have liked)
  3. Subtypes and ranges (Ada and Modula-2 only; Rust doesn't offer this feature)
  4. Functional-style programming (mostly Rust, but Ada has some offerings; e.g., 'Reduce)
  5. Interval arithmetic (mostly set operations)
  6. Mathematical modeling
  7. Quadratic formula
  8. Integer sequences that reduce to arithmetic sequences (there's a term for this, but I can't recall it offhand; see the Day 9 puzzle)
  9. Search algorithms
  10. Dynamic programming
  11. Detecting patterns of numerical sequences
  12. Euclid's algorithm for greatest common divisors and using them to compute least common multiples
  13. Pick's Theorem and the Shoelace Formula
  14. Gröbner bases (yes, really)
  15. Monte Carlo methods
  16. Karger's Theorem

Ranking of problems by difficulty

This is inherently subjective, and I may even misremember how difficult I found a problem, so if you disagree, at least check out the justification I give in the relevant day's Experience section.

:star_struck: Quick 'n easy puzzles

C'mon, you can do these.

  • :rocket: Day 1: Trebuchet?!
  • :package: Day 2: Cube Conundrum
  • :gear: Day 3: Gear Ratios
  • :ticket: Day 4: Scratchcards
  • :stopwatch: Day 6: Wait For It
  • :camel: Day 7: Camel Cards
  • :palm_tree: Day 9: Mirage Maintenance
  • :stars: Day 11: Cosmic Expansion
  • 🔎 Day 15: Lens Library

:thinking: Puzzles needing more than a little thought

  • :seedling: Day 5: If You Give A Seed A Fertilizer
  • :desert: Day 8: Haunted Wasteland
  • :mirror: Day 13: Point of Incidence
  • 📡 Day 14: Parabolic Reflector Dish
  • :mirror: Day 16: The Floor Will Be Lava
  • :shopping_cart: Day 17: Clumsy Crucible
  • :stuffed_flatbread: Day 19: Aplenty
  • :radio_button: Day 20: Pulse Propagation
  • :bricks: Day 22: Sand Slabs

:fearful: Problems requiring a lot of thought, or trickier ideas

A reputable mathematics or computer science program will teach you how to solve these problems, but you've probably used it often enough to forget the technique. Or, it's not something they teach in school, but a little imagination will get you to the solution.

  • :loop: Day 10: Pipe Maze
  • :hotsprings: Day 12: Hot Springs
  • :walking: Day 21: Step Counter
  • :evergreen_tree: Day 23: A Long Walk

:scream: Great puzzles that are jes' plain ornery

If you know the trick, the solution is easy. But knowing the trick is unusual, and while I was able to come up with a solution, implementing it was tricky and frustrating.

  • :volcano: Day 18: Lavaduct Lagoon
  • :snowflake: Day 25: Snowverload

:sob: What was the puzzle master thinking?!?

This question left a lot of the pros baffled, and not a few of them miffed! Most solutions I saw relied on asking a theorem prover to solve it. (Or Mathematica... but I repeat myself.)

  • ⛈️ Day 24: Never Tell Me The Odds

Day 1: Trebuchet?!

<span style="font-size: 8ex;">:rocket:</font>

The elves have decided you need to fix the lack of snow. Their solution is to catapult you into the sky via a trebuchet.

This has the most entertaining paragraph I recall in Advent of Code:

You try to ask why they can't just use a weather machine ("not powerful enough") and where they're even sending you ("the sky") and why your map looks mostly blank ("you sure ask a lot of questions") and hang on did you just say the sky ("of course, where do you think snow comes from") when you realize that the Elves are already loading you into a trebuchet ("please hold still, we need to strap you in").

The problem depends on calibration values, which are the first and last "digits" to appear in a string.

  1. Sum the calibration values, where "digit" means 1..9.
  2. Sum the calibration values, where "digit" now includes the spellings (one, two, ...)

Unusual tools

  • Ada: contracts on the Digit function (sure would be nice if Ada had a To_Digit function the way Rust does)
  • Modula-2: just using Modula-2 these days was unusual enough
  • Rust: Aho-Corasick

Experience

Ada and Rust

This is the first time I use Aho-Corasick in Rust, and as with many things Rust, there was quite the learning curve.

Since I'm using Aho-Corasick in Rust, the algorithms aren't quite the same. The Ada uses a sequence of if-then statements and converts each character or string to a digit.

Speed-wise, the two are more or less the same. The Rust is a little faster, but (a) I'm running it in release mode, while I'm running Ada at whatever gnat's default optimization level is, and (b) Ada is checking the contracts for the Digit function.

Modula-2

This is my first non-trivial Modula-2 program in about 3 decades. While it was fun to work with it in principle, I encountered several issues that Ada and/or Rust would have prevented. Of course, it's possible that Modula-2 offers a convenient way to do this, and I just don't know about it.

  1. Standard Library?

    The default library for gm2 is based on PIM, Niklaus Wirth's "Programming in Modula-2" specification. The ISO standard is different in some areas, such as string comparison: PIM, like C's string comparison, returns an integer, while ISO defines and returns a proper type. Fortunately, gnu Modula-2 offers the option to compile against the ISO libraries.

  2. Uninitialized variables?

    I spent way too long debugging an error where I was returning an uninitialized variable. Rust requires you to initialize all variables, and while Ada doesn't (!!!) it does allow you to specify initial values.

  3. Inconvenient initialization?

    Both Ada and Rust allow you to initialize a variable when you declare it. Not so with Modula-2; you must wait until the body (BEGIN)... which means you may forget to initialize it.

  4. String Comparisons? Substrings?

    Ada and Rust allow easy string comparison and substrings. Modula-2 does not, or at least I couldn't find a way. _[update: [Confirmed on gm2 mailing list](https://li

Related Skills

View on GitHub
GitHub Stars36
CategoryDevelopment
Updated2mo ago
Forks1

Languages

Ada

Security Score

90/100

Audited on Jan 27, 2026

No findings