アリスの序数書式


9

前書き

Aliceは、Martin Enderによる2次元言語で、2つの異なる実行モード、cardinalordinalがあります。命令ポインタがミラー(または)を通過すると、1つのモードから別のモードに切り替わります。/\

この課題では、コマンドが文字列を操作し、命令ポインターが斜めに移動して、コードの端に対して跳ねる序数モードに焦点を当てます。

通常モードでのみ動作する単純なプログラムは、次の例のように、非常にコンパクトなスタイルで記述できます。

/fbd/
@aec\

ここでIPは、最初のセルが東に行くから枢機卿モードで起動し、第1のミラーを透過し、斜めに移動し、バウンス、コマンドの実行を開始するabc。それは、それは他のミラーに向けて南に行くと、その後、西に向けたバックをバウンスコマンドに遭遇した起動可能北東ミラーに遭遇したdef、そして最後に@、プログラムを終了します。

この種の構造は非常にコンパクトですが、記述と保守が容易ではありません(単一のコマンドを追加すると、ほとんどのコードの順序を変更しなければならなくなる可能性があります)。書式設定を手伝ってください。

タスク

コマンドのシーケンスがあり、各コマンドが単一の印刷可能なASCII文字である場合、シーケンスの前半が2行目の最初の文字から始まり、常に右に向かって斜めに移動できるように、コマンドを2行に並べ替えます。後半は残りの文字を右から左に読みながら読むことができます。ミラーと終了記号については心配しないでください。自分で追加します。

したがって、たとえば、入力abcdefを指定すると、出力する必要があります

fbd
aec

入力が奇数長の場合、遭遇するコマンドのシーケンスが同じままである限り、どこかに単一のスペース(Aliceでは何もしない)を追加する必要があります。また、長さが1文字だけ異なる2つの行を出力するように選択することもできます。その場合、短い方の行の終わりに1つのスペースがあると見なされます。

ルール

これはであり、バイト単位での最短の答えが勝ちます!

  • デフォルトの入出力メソッドのいずれかを介して入出力できます
  • 入力は、1行の印刷可能な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)

回答:


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

オンラインでお試しください!

入力の長さが奇数の場合、これにより、線形化されたプログラムの最後にパディングスペースが配置され、最終的に出力の最初の文字になります。

レオは数日前にアリスで序数フォーマッターを書いた。奇数長の入力のサポートを追加し、この課題に必要のないものを削除した後、28バイトになりました。私は少し違うアプローチを試したかったのですが、これがこの答えです。残念ながら、結局28バイトになってしまいましたが、少なくともこの方法で、独自のソリューションを投稿し、Leoに元のアルゴリズムを投稿させることができます。

これは、で文字列を半分に分割するというLeoの本当に賢いアイデアを使用しています..Y;m;.!z?~

説明

入力が偶数の長さであると仮定しましょう(そうでない場合はスペースで埋めるだけなので)。0123456789コードを使用すると、パターンが少しわかりやすくなります。必要な出力は次のとおりです。

91735
08264

したがって、1行目には入力のすべての奇数位置が含まれ、2行目にはすべての偶数入力が含まれます。さらに、奇数の位置を逆にすると、ライン自体は両方とも前半(おそらくより長い)で後半の逆にインターリーブされます。

したがって、基本的な考え方は次のとおりです。

  • 入力を奇数位置と偶数位置に分離します。
  • 必要に応じて、奇数位置にスペースを埋め込みます。
  • 奇数の位置を逆にします。
  • 次に2回:現在の文字列を半分にし、後半を逆にし、両方の半分をインターリーブし、末尾に改行して印刷します。

コードに関しては、これはこの課題で作成しているレイアウトの種類によく似ていますが、微妙に異なります。/コードの最後でIPがに到達すると、南ではなくに反映されます。次に、カーディナルモードでは、IPは最初の列にラップアラウンドします。そこで\thereはOrdinalモードに入るので、コードの後半はここで右から左に移動するのではなく、左から右に移動します。これは、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バイト(左下がパディングである場合があります)

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途中のミラーを実現しています。すべてのコマンドが目的の実行位置に入力されると、配列が収集され、目的の結果が生成されます。
Neil、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.