Labyrinth, 28 25 24 23 22 bytes
" >
?!?:|}\{@
@\?"":)!
This was mad fun! :) That is by far the most densely compressed Labyrinth program I've written so far. I had so many versions at 20 and 21 bytes which almost worked that I'm still doubting this is optimal...
This takes input as a list of positive integers (with an arbitrary delimiter), and prints the result to STDOUT as linefeed-delimited integers.
The hunt for 20/21 bytes: I've checked all programs of the form
" XX
?!?X}\{@
@\?XX)!
where X
is any reasonable character by brute force, but didn't find any valid solutions. Of course that doesn't mean that a shorter solution doesn't exist, but it's not possible to force 20-byte programs without a decent amount of assumptions on its structure.
Explanation
(The explanation is slightly outdated, but I'm still not convinced the solution is optimal, so I'll wait with updating this.)
So, normally Labyrinth programs are supposed to look like mazes. While the instruction pointer is in a corridor, it will follow that corridor. When the IP hits any kind of junction, the direction is determined based on the top value of Labyrinth's main stack (Labyrinth has two stacks, with an infinite amount of zeroes at the bottom). That normally means that any non-trivial loop will be quite expensive, because if you have non-wall cells all over the place everything is a junction, and in most cases the top of the stack won't have the right value for the IP to take the path you would like it to take. So what you do is you enlarge the loops such that they have a whole in the centre with only one well-defined entry and exit point each.
But this time I was really lucky and everything fit so well together, that I could squash it all into one big clump. :)
Control flow starts at the _
going South. The _
pushes a zero onto the main stack. That may seem like a no-op, but this increases the (non-implicit) stack depth to 1
which we'll need later.
?
reads an integer from STDIN. If there are no more integers to be read, this pushes zero. In that case, the IP keeps moving South and @
terminates the program right away (because the input list is empty). Otherwise, the IP turns East.
We're now entering a very tight loop with two exit points:
!?;
\?
;
!
prints the integer back to STDOUT, leaving only a zero on the stack. The IP keeps moving East, and ?
reads the next integer. If that is non-zero, we take a right and move South. ?
reads another one (the next even index). Again, if that is non-zero, we take a right and move West.
Then \
prints a linefeed without changing the stack, so we take another right, moving North. !
prints that next even-index integer. Since now there is at least one (positive) odd-index integer on the stack, we keep turning right and the loop repeats.
Once either of those ?
hits the end of the list, they push a zero and move straight onto the corresponding ;
, which discards that zero.
In the case that there was only a single element in the list, we're done (because we've printed that right away), so the IP would keep moving East all the way to the @
, again terminating the program (printing a trailing linefeed on the way).
Otherwise, we need to print the odd-index integers as well. In that case the two paths (from the two exit points of the first loop) merge on the middle "
, turning East in either case.
_
pushes a zero to avoid taking a left into the @
, and ;
discards that zero. Now we enter a new loop:
"}
""
The IP enters this on the bottom-left cell, moving North, going around the loop in a clockwise sense. The }
shifts the top of the main stack over to the auxiliary stack. While there is still an element on the stack, the IP keeps doing its thing. Once everything has been shifted to the auxiliary stack (and reversed in the process), the IP keeps moving East instead, entering the last loop:
\{@
#!
\
prints a linefeed again, {
moves an item from the auxiliary stack back to main. If that was still an item of the list, it will be positive, and the IP turns South, where the item is printed with !
. Then #
pushes the stack depth (and now this is where the initial _
is important, because this #
ensures a positive stack depth), so that the IP still turns right, through the \
and {
again.
After we've printed everything, {
pulls a zero from the bottom of the auxiliary stack, the IP continues East, and @
terminates the program.