爱丽丝的序数格式


9

介绍

爱丽丝(Alice)马丁·恩德Martin Ender)的一种二维语言,具有两种不同的执行模式:基数序数。当指令指针通过一面镜子(/\)时,它会从一种模式切换到另一种模式。

在此挑战中,我们将重点关注顺序模式,在命令模式下,命令对字符串进行操作,并且指令指针沿对角线移动,并在代码边缘跳动。

可以以非常紧凑的样式编写仅以序数模式运行的简单程序,如以下示例所示:

/fbd/
@aec\

在这里,IP在基数模式启动从所述第一小区去东,通过第一反射镜,并开始对角移动和跳动,执行命令abc。然后,它遇到了东北镜这使得南下向其他镜像,然后开始反弹向西走回来,遇到命令def,最后@,终止程序。

这种结构非常紧凑,但是编写和维护起来并不容易(添加单个命令可能会迫使我们对大多数代码进行重新排序!),因此,我希望您能帮助我进行格式化。

任务

给定一个命令序列,其中每个命令是一个可打印的ASCII字符,请在两行上对其重新排序,以便可以从第二行的第一个字符开始读取该序列的前半部分,然后始终向右斜移,而后半部分则可以从右到左读取其余字符。不用担心镜子和终止符号,我会自己添加它们。

因此,例如,给定输入,abcdef您应该输出

fbd
aec

如果输入的长度是奇数,则只要遇到的命令顺序保持不变,就应该在任何地方添加一个空格(在Alice中为noop)。您也可以选择输出两行长度相差一个字符的字符,在这种情况下,较短的行被认为在末尾有一个空格。

规则

这是 ,最短答案(以字节为单位)获胜!

  • 您可以通过任何默认的输入/输出方法来输入/输出
  • 输入由一行可打印的ASCII字符组成
  • 输出中允许使用一条尾随换行符
  • 当作为Alice程序运行时,程序的某些输出可能没有完全正确的行为(例如,如果在字符串文字中插入了填充空间)。您不必担心这些情况
  • 禁止出现标准漏洞

测试用例

--Input
abcdef
--Output
fbd
aec

--Input
123
--Output
 2
13
OR
31
 2
OR
3
12
OR
32
1

--Input
O
--Output
O

OR

O

--Input
"Hello, World!"o
--Output
oH!lloo 
""edlr,W

--Input
i.szR.szno
--Output
o.zz.
inssR

--Input
"  ^^} .~[}.~~[}{~~{}[^^^^.""!}"r.h~;a*y'~i.*So
--Output
o *^i}'.*[;.h~r}}~"{.[^
"S .^~ y~a}~~.["{!~"}^^^
(Odd length, your solution may be different)

Answers:


1

果冻,15字节

œs2U2¦ṚZUJḤ$¦ZY

在线尝试!

接受引用输入。

说明:

œs2U2¦ṚZUJḤ$¦ZY Main link, monadic
œs2             Split into 2 chunks of similar lengths, last might be shorter
   U2¦          Reverse the 2nd chunk
      Ṛ         Swap the chunks
       Z        Transpose into chunks of length 2
        UJḤ$¦   Reverse the chunks at even indices (1-indexed)
             Z  Transpose into 2 chunks again
              Y Join by a newline

12

爱丽丝,28字节

/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.

1
对于您想出的这种新布局,我将不得不发布另一个挑战!:D非常好,即使我不使用返回堆栈,我也将开始使用它,从左到右阅读两半代码更容易
Leo

4

果冻23 22 字节

-1个字节,感谢Leo(左下角可能是填充)

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y

完整的程序将打印结果(单子链接返回一个字符列表列表)。

在线尝试!或查看测试套件

怎么样?

LḂ⁶ẋ;µṚ,µm2œs2U0¦ż/µ€Y - Main link: list of characters
L                      - length
 Ḃ                     - modulo 2
  ⁶                    - literal space character
   ẋ                   - repeat
    ;@                 - concatenate (swap @rguments) (appends a space if the input's length is odd)
      µ                - monadic chain separation, call that s
       Ṛ               - reverse s
        ,              - pair with s
         µ         µ€  - for €ach:
          m2           -   modulo 2 slice (take every other character)
            œs2        -   split into two "equal" chunks (first half longer if odd)
               U0¦     -   upend index 0 (reverse the second chunk)
                   /   -   reduce by:
                  ż    -     zip
                     Y - join with newlines (well just the one in this case)
                       - implicit print (mushes the sublists together)

1

JavaScript(ES6),104个字节

f=
s=>s.replace(/./g,(c,i)=>a[1&~i][i+i>l?l-i:i]=c,a=[[` `],[]],l=s.length-1|1)&&a.map(a=>a.join``).join`
`
<input oninput=o.textContent=f(this.value)><pre id=o>

通过模拟执行路径并按需填写命令来工作。


似乎是个不错的主意,但我对javascript的了解还不足以理解您使用的算法...您能添加一些解释吗?
狮子座

@Leo我不确定我还能解释多少。如您所知,这些命令从左到右跟随曲折线,并再次向左返回。在1&~i实现了垂直锯齿形,而i+i>l?l-i:i达到半反射镜。一旦将所有命令输入到所需的执行位置,然后将数组收集在一起以产生所需的结果。
尼尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.