Note: If you’re attempting to read this as a Fediverse post, you might find it rather confusing. I recommend using a web browser to read it properly, following this link.
The challenge
On day 1, we have to open a closed door with a rotary dial and a keypad. The dial has 100 positions from 0 to 99. We have a (long) list with instructions like "L42" or "R4", meaning “turn 42 clicks to the left” or “turn 4 clicks to the right”, respectively.
If we start at position 50, we might sometimes land on position 0 after a turn. The number of times we land on 0, is actually the password to enter on the keypad.
The idea
Having the list of instructions, we apparently need to do the following:
Take our current position, read the instruction, calculate at which position we land, and if it is 0, add 1 to our zero counter.
Turning right, means increasing the position by the given number; turning left, decreasing it.
Obviously, if we pass 99, we start at 0 again. Say, our position is 50 and our instruction is R52. The position would be 102. 100 is zero, 101 is 1, 102 is 2.
The mathematical operation corresponding to this, is called the module.
We write n%k as the rest of the division of n/k.
What happens if we start at 50 and our instruction is L52? Obviously, our new position would be -2, which would translate to 98.
What is n%k if n is negative? Often, n%k is understood as -|n|%k, which in our case would mean: -2%100 = -2. We would have to add 100 if position/100 is negative.
The programming language of my choice, Perl (preinstalled on every UN*X and MacOS machine), does this automatically: The operation n%k will always return a positive number. If n is negative, the result of n%k is k – |n|%k. Exactly what we want.
So, this is the code:

It should be rather self explanatory. I’ll just give a few remarks:
The program expects an input file (with the instructions) as command line parameter. The diamond operator <> reads the file given line by line and stores the current line in the magic variable $_ until there is nothing more to read.
The regular expression m/(/D)(/d+)/ is matched against $_. \D stands for non-digit character, whilst \d+ represents a non-empty sequence of digits.
What is enclosed in the first parenthesis is stored in the special variable $1, what is in the second in $2.
eq is the equality operator for strings. == is reserved for numbers.
Perl interprets every non-zero number as a boolean true, 0 as false.
The expression, a or b means the following:
if a is true, continue, if not, do b!
The updated challenge
Actually, we got it wrong in the first part. We were not only supposed to count the times we land on 0, but also every time, the dial passes that number.
The updated idea
Whilst certainly it would have been possible to use some smart arithmetic, I thought: My time is more valuable than my computer’s, so I decided to take it easy: After each click during dialling, check if the number is zero. So this is the code:

One thing worth mentioning here, might be the range operator (a..b) which simply counts from a to b in steps of 1.
And there is the part $zeroes++ unless $position % 100 which might look rather unusual. unless condition is another way of writing if not condition. You can use both keywords.
In Perl, if an if/unless statement is followed by a single instruction, instead of writing
unless($position % 100) {
$zeroes++
}
you may use the above notation, which makes it shorter to write and nicer to read.
An alternative idea
OK. After having finished the second part, it kept annoying me that I solved the second part so ungracefully, so I redid it in a nicer fashion:

I abbreviated the variable names, as you can see, and I also made heavy use of the ternary operator: condition ? this_if_true : that_if_false
In each iteration, we start with a value of $p between 0 and 99.
Instead of reading an explanation, look at these values for $p and $n and try to figure out, how the expression gives the correct result for the increase in $z:
| p | n | z increase |
| 10 | 0 | 1 |
| 10 | 230 | 2 |
| 10 | -30 | 1 |
| 10 | -230 | 3 |
| 0 | -230 | 2 |
Iโd love to discuss my and your solutions with you!
I have created a โleaderboardโ (so far I am the only person in it). Feel free to join it!
Just drop me a personal message to my main Fediverse account or drop me an email (address at the bottom of the page), and I shall send you the join code.

Leave a Reply