Article
· Dec 31, 2024 6m read

My little Advent of Code 2024 journey

You'll find the original text and all my Advent of Code efforts in different programming languages in https://bitbucket.org/janihur/advent-of-code/src/master/

ObjectScript code discussed here is found in https://bitbucket.org/janihur/advent-of-code/src/master/objectscript

I have been using ObjectScript only on last 1,5 years maybe 30% of my working time but the code at work is very different than in these puzzles. You can find my random code snippets and learning notes from https://github.com/janihur/objectscript-ex

This is the first time using ObjectScript during the contest. Earlier this year I practiced a bit with first 5 puzzles from 2018.

Before the event I made version 2 of my input data load routine. The main motivation is to be able to make the data available directly from the VS Code editor without making data files available for IRIS instance.

The solutions expect a data from object that implements aoc.data.base "iterator" interface. The class can be created from the input data:

python3 data-import-v2.py PUZZLE_INPUT_FILE

This will generate data classes:

  • aoc.example<YEAR><DAY>.cls - will be create only if PUZZLE_INPUT_FILE-example exists
  • aoc.input<YEAR><DAY>.cls

The solution classes have the interface with parameter defining if it should load the example or the actual puzzle data:

ClassMethod Solve(useExampleData As %Boolean = 0)

Some solutions uses companion classes, so be sure to load them too:

  • aoc.Coord
  • aoc.list
  • aoc.stack
  • aoc.StopWatch
  • aoc.str
  • aoc.topo
  • aoc24.Guard

Day 1

The data loading pattern works just fine. The trick is to use regular expressions (especially %Regex.Matcher class) to split the string.

I struggled with sorting as the language seems to have no sorting on any of it's peculiar data types so I implemented the simple and inefficient Bubble sort that luckily works here just fast enough.

However on the process I realised the sorting is builtin feature of the versatile multidimensional array data type:

All siblings are automatically sorted numerically or alphabetically as they are added to the tree.

Because you can freely define your array indices I have effectively started using one-based array types. This very nicely eliminates those off-by-one errors I frequently have with languages with zero-based indexing.

Day 2

Algorithm part of the puzzle was still easy for me and I scored both parts on the first try. However I fell on the same trap than the most and I had to rewrite my part 1 solution to be more general so it could be applied also to part 2.

Here I had to take a next deep dive on the features of multidimensional array, especially on merge and kill commands. This was probably the first time I had to use these functions in the actual code. I'm starting to see the point of multidimensional array thought it is well hidden behind obscure syntax and fragmented documentation.

Oh, and I had to implement string split as the platform doesn't have it but only more primitive string operations:

ClassMethod splitInputLine(
    line As %String,
    Output levels)
{
    kill levels
    for i=1:1:$length(line," ") {
        set levels(i) = $piece(line," ",i)
    }
    set levels("size") = i // feeling clever!
}

Note the clever use of subscripts!

Day 3

So far there has been no need for computer science stuff but logical reasoning has been enough.

No new ObjectScript tricks today but maybe I should put one or two potentially reusable class (i.e. static) methods into a dedicated package in the spirit of over-engineering!

Day 4

I struggled in part 1 to build the diagonals - that was a huge time sink. I also had to study the %Regex.Matcher a bit more to get the matching right.

Part 2 was a breeze compared to part 1 but I made a typo and submitted wrong answer first (first time this year).

Day 5

In the first look to the example data the puzzle looked like a case for topological sort but it turned out the validation of updates in part 1 was not a sorting problem.

But then in part 2 topological sort was indeed needed. I have used topological sort only once before (in another Advent of Code puzzle) in my career and never with ObjectScript. I implemented it in a companion class (aoc.topo) and at the same time I added also two other small helpers with better ergonomics: aoc.list and aoc.str.

I also found a valid use case for goto command too!

Overall all this took some much time that this year day 5 was the point I fell behind.

Day 6

I had no time for the puzzles in three days so now I have permanently fallen behind the daily schedule.

This is the first case where the data have to be processed as 2d array so I had to make a few new preparations. I also created two new classes:

  • aoc.Coord - to help me passing and calculating new coordinates (positions)
  • aoc24.Guard - simulating the guard's movement

Part 1 was straightforward but I struggled a bit in part 2. However it didn't took too much time to figure out the following solution:

  1. reduce the search space to the visited positions only (65% reduction)
  2. set an obstackle in every visited positions (except the guard's initial position)
  3. simulate guard's movement as in part 1
    1. there is a loop if the guard hits the obstacle second time from the same direction
    2. there is no loop if the guard walks out of the area in the same way than in part 1

In my hardware the part 2 took ~90 seconds so clearly this is non-optimal brute force algorithm. One optimization idea (search space reduction) not implemented is to set the guard's initial position next to the new obstacle.

In the beginning I tried to check if there is a certain obstacle patterns that will lead to the loop but as I couldn't figure them out immediately I abandoned the approach.

Day 7

Part 1

I bet there is a mathematical number theory that solves this problem but with my limited mathematical skills I just started to calculate all possible equations and discard the equation when it's value exceeded the expected value. I googled "parsing mathematical expressions" for implementation ideas and ended maybe a bit over-complex solution to use stacks to save the current operation and it's operands. In every iteration of equation numbers I had two new stacks for holding add and multiply operators. If the value exceeded the expected value I discarded the stack, otherwise the stack was kept for next iteration. Essentially the stack is just an elaborate accumulator.

My stack class is aoc.stack. I was also interested to correctly record the execution time so enter aoc.StopWatch. (I really need to pay attention to the de-facto standard naming convention.)

In this puzzle I had a lot of silly mistakes, e.g. at one point I forgot to rename one variable, that took far too long to troubleshoot.

Part 2

The part 2 introduced a new operation and so the search space exploded as it very often does here. Occasionally this might render brute force approaches more or less "useless". For sure it's an indication there have to be a more clever approach. Anyway I didn't have any better ideas than to run through all the valid combinations as in part 1.

During the next weeks I had zero effort on Advent Of Code. Just on the New Year's Eve I decided to out to the internet for the solutions, run into a recursive Python solution in 15 seconds and decided go no further in the lands of computer science nor mathematics. Essentially I just had to add the concatenation operation exactly the same way I already used for addition. Yes, the execution time exploded but was still just 70 seconds (2 secs in part 1) in my hardware.

I scored the star on the first try.

Later I refactored the code so that the both parts use the same solution helper methods.

Discussion (1)1
Log in or sign up to continue

Big THANK YOU @Jani Hurskainen for sharing your story.
I'm impressed by the progress you made on ObjectScript
after only 1,5 years maybe 30% of working time,

AoC examples are definitely different from the target cases ObjectScript was designed for.
Its top target is the underlaying database, string manipulation and less math functionality.

My best wishes for Health and Success  for the New Year
Robert