:?
:
#/)
\ #
!"*@
"
Try it online!
This outputs the results in the order C, B, A
separated by linefeeds.
Explanation
As usual, a short Labyrinth primer:
- Labyrinth has two stacks of arbitrary-precision integers, main and aux(iliary), which are initially filled with an (implicit) infinite amount of zeros. We'll only be using main for this answer.
- The source code resembles a maze, where the instruction pointer (IP) follows corridors when it can (even around corners). The code starts at the first valid character in reading order, i.e. in the top left corner in this case. When the IP comes to any form of junction (i.e. several adjacent cells in addition to the one it came from), it will pick a direction based on the top of the main stack. The basic rules are: turn left when negative, keep going ahead when zero, turn right when positive. And when one of these is not possible because there's a wall, then the IP will take the opposite direction. The IP also turns around when hitting dead ends.
Despite the two no-ops ("
) which make the layout seem a bit wasteful, I'm quite happy with this solution, because its control flow is actually quite subtle.
The IP starts in the top left corner on the :
going right. It will immediately hit a dead end on the ?
and turn around, so that the program actually starts with this linear piece of code:
: Duplicate top of main stack. This will duplicate one of the implicit zeros
at the bottom. While this may seem like a no-op it actually increases
the stack depth to 1, because the duplicated zero is *explicit*.
? Read n and push it onto main.
: Duplicate.
: Duplicate.
That means we've now got three copies of n
on the main stack, but its depth is 4
. That's convenient because it means we can the stack depth to retrieve the current multiplier while working through the copies of the input.
The IP now enters a (clockwise) 3x3 loop. Note that #
, which pushes the stack depth, will always push a positive value such that we know the IP will always turn east at this point.
The loop body is this:
# Push the stack depth, i.e. the current multiplier k.
/ Compute n / k (rounding down).
) Increment.
# Push the stack depth again (this is still k).
* Multiply. So we've now computed (n/k+1)*k, which is the number
we're looking for. Note that this number is always positive so
we're guaranteed that the IP turns west to continue the loop.
" No-op.
! Print result. If we've still got copies of n left, the top of the
stack is positive, so the IP turns north and does another round.
Otherwise, see below...
\ Print a linefeed.
Then we enter the next loop iteration.
After the loop was traversed (up to !
) three times, all copies of n
are used up and the zero underneath is revealed. Due to the "
at the bottom (which otherwise seems pretty useless) this position is a junction. That means with a zero on top of the stack, the IP tries to go straight ahead (west), but because there's a wall it actually makes a 180 degree turn and moves back east as if it had hit a dead end.
As a result, the following bit is now executed:
" No-op.
* Multiply two zeros on top of the stack, i.e. also a no-op.
The top of the stack is now still zero, so the IP keeps moving east.
@ Terminate the program.
C B A
) if it's clearly specified in the answer? \$\endgroup\$