/mY. zm~wZ.k;
\I;'!*?RR.OY@/
在线尝试!
如果输入长度为奇数,则将填充空间放在线性化程序的末尾,最后成为输出的第一个字符。
Leo几天前在Alice中写了Ordinal格式化程序。添加对奇数长度输入的支持,然后删除了一些对于此挑战而言不必要的内容之后,我们最终获得了28个字节。我想尝试一种稍微不同的方法,这就是答案。不幸的是,它最终只占用了28个字节,但是至少以此方式,我可以发布自己的解决方案,并让Leo发布其原始算法。
这确实使用了Leo的聪明想法,用来将字符串分成两半..Y;m;.!z?~
。
说明
让我们假设输入的长度是偶数(因为如果没有,我们将用空格填充它)。如果我们将其0123456789
用作代码,则更容易看到该模式。所需的输出将是:
91735
08264
因此,第一行包含输入的所有奇数位置,第二行包含所有偶数输入。此外,如果我们反转奇数位置,则线条本身都是前半部分(可能更长)与后半部分的相反部分交织在一起的。
因此,基本思想是:
- 将输入分隔为奇数和偶数位置。
- 如有必要,请在奇数位置填充空格。
- 反转奇数位置。
- 然后两次:将当前字符串减半,将后半部分反转,将两半交错,并在末尾换行。
至于代码,这看起来很像我们在这次挑战中所产生的布局,但是却有细微的不同:当IP /
到达代码的末尾时,它会向东而不是向南反射。然后,在基数模式下,IP将环绕到第一列。在\
那里重新进入有序状态,使代码下半年不从右到离开这里,但是从左至右为好。在使用返回地址堆栈时,这是有益的,因为它不存储有关IP方向的信息。这使我们节省了一些字节,因为IP会在w
和两者上沿相同(水平)方向移动k
。
线性化的代码是这样的:
IY' *mRw..Y;m;.!z?~RZOk@
让我们来看一下:
I Read one line of input.
Y Unzip. Separates the string into even and odd positions.
' * Append a space to the odd half.
m Truncate: discards characters from the longer of the two
strings until they're the same length. So if the input
length was even, appending a space will make the odd half
longer and this discards the space again. Otherwise, the
space just padded the odd half to the same length as the
even half and this does nothing.
R Reverse the odd half.
w Push the current IP address to the return address stack.
The purpose of this is to run the following section
exactly twice.
This first part splits the current line in half, based
on an idea of Leo's:
.. Make two copies of the current half.
Y Unzip one of the copies. The actual strings are irrelevant
but the important part is that the first string's length
will be exactly half the original string's length (rounded up).
; Discard the potentially shorter half.
m Truncate on the original string and its even half. This shortens
the original string to the first half of its characters.
; Discard the even half, because we only needed its length.
.! Store a copy of the first half on the tape.
z Drop. Use the first half to discard it from the original string.
This gives us the the second (potentially shorter half).
? Retrieve the first half from the tape.
~ Swap it so that the second half is on top.
The string has now been split in half.
R Reverse the second half.
Z Zip. Interleave the two halves.
O Print the result with a trailing linefeed.
k Pop an address from the return address stack and jump back there.
The second time we reach this, the return address stack is empty,
and this does nothing.
@ Terminate the program.