Format ordinal Alice

9

pengantar

Alice adalah bahasa 2-d oleh Martin Ender yang memiliki dua mode eksekusi yang berbeda, kardinal dan ordinal . Ketika instruksi pointer melewati melalui cermin (baik /atau \), itu beralih dari satu mode ke mode yang lain.

Dalam tantangan ini kita akan fokus pada mode ordinal , di mana perintah beroperasi pada string dan penunjuk instruksi bergerak secara diagonal, memantul ke tepi kode.

Program sederhana yang hanya beroperasi dalam mode ordinal dapat ditulis dalam gaya yang cukup ringkas, seperti dalam contoh berikut:

/fbd/
@aec\

Berikut IP dimulai dalam mode kardinal dari sel pertama akan timur, melewati cermin pertama dan mulai bergerak diagonal dan memantul, mengeksekusi perintah a, bdan c. Ini kemudian bertemu cermin utara-timur yang membuatnya pergi ke selatan ke arah cermin lain dan kemudian mulai memantul kembali ke arah barat, menghadapi perintah d, e, f, dan akhirnya @, yang berakhir program.

Struktur semacam ini cukup kompak, tetapi tidak mudah untuk menulis dan memelihara (menambahkan satu perintah mungkin memaksa kita untuk menyusun ulang sebagian besar kode!), Jadi saya ingin Anda membantu saya dengan pemformatan.

Tugas

Diberikan urutan perintah, di mana setiap perintah adalah karakter ASCII tunggal yang dapat dicetak, menyusun ulang mereka pada dua baris sehingga bagian pertama dari urutan dapat dibaca mulai dari karakter pertama dari baris kedua dan kemudian bergerak selalu secara diagonal ke kanan, sementara bagian kedua dapat dibaca dengan mengambil karakter yang tersisa dari kanan ke kiri. Jangan khawatir tentang cermin dan simbol terminasi, saya akan menambahkannya sendiri.

Jadi, misalnya, diberi input abcdefAnda harus menampilkan

fbd
aec

Jika inputnya panjangnya aneh, Anda harus menambahkan spasi tunggal (yang merupakan noop di Alice) di mana saja, selama urutan perintah yang dijumpai tetap sama. Anda juga dapat memilih untuk menghasilkan dua garis yang berbeda panjangnya oleh satu karakter, dalam hal ini yang lebih pendek dianggap memiliki satu ruang di ujungnya.

Aturan

Ini adalah , jawaban terpendek, dalam byte, menang!

  • Anda dapat input / output melalui salah satu metode input / output default
  • Input terdiri dari satu baris karakter ASCII yang dapat dicetak
  • Baris baru satu trailing diizinkan dalam output
  • Beberapa output dari program Anda mungkin tidak memiliki perilaku yang sepenuhnya benar ketika dijalankan sebagai program Alice (misalnya jika ruang padding dimasukkan ke dalam string literal). Anda tidak perlu khawatir dengan situasi ini
  • Celah standar dilarang

Uji kasus

--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)
Leo
sumber

Jawaban:

1

Jelly , 15 byte

œs2U2¦ṚZUJḤ$¦ZY

Cobalah online!

Mengambil input yang dikutip.

Penjelasan:

œ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
Erik the Outgolfer
sumber
12

Alice , 28 byte

/mY. zm~wZ.k;
\I;'!*?RR.OY@/

Cobalah online!

Jika panjang input ganjil, ini menempatkan ruang padding di akhir program linear, yang akhirnya menjadi karakter pertama dari output.

Leo menulis formatter Ordinal di Alice beberapa hari yang lalu. Setelah menambahkan dukungan untuk input panjang ganjil dan kemudian menghapus beberapa hal yang tidak perlu untuk tantangan ini, kami berakhir pada 28 byte . Saya ingin mencoba pendekatan yang sedikit berbeda, yaitu jawaban ini. Sayangnya, itu akhirnya mengikat 28 byte, tetapi setidaknya dengan cara ini saya dapat memposting solusi saya sendiri dan membiarkan Leo memposting algoritma aslinya.

Ini benar-benar menggunakan ide pintar Leo untuk membagi string menjadi dua ..Y;m;.!z?~.

Penjelasan

Mari kita asumsikan bahwa input memiliki panjang genap (karena kita hanya akan menambahkannya dengan spasi jika tidak). Polanya sedikit lebih mudah untuk melihat apakah kita menggunakan 0123456789sebagai kode. Output yang dibutuhkan adalah:

91735
08264

Jadi baris pertama berisi semua posisi ganjil dari input dan baris kedua semua input genap. Lebih jauh, jika kita membalikkan posisi ganjil, maka garis-garis itu sendiri adalah paruh pertama (mungkin lebih lama) disatukan dengan kebalikan dari babak kedua.

Jadi ide dasarnya adalah:

  • Pisahkan input menjadi posisi ganjil dan genap.
  • Pad posisi aneh dengan spasi jika perlu.
  • Membalik posisi aneh.
  • Kemudian dua kali: membagi dua string saat ini, membalikkan bagian kedua, menyisipkan kedua bagian, mencetak dengan garis makan line.

Adapun kode, ini sangat mirip dengan jenis tata letak yang kami hasilkan dalam tantangan ini, tetapi agak berbeda: ketika IP menyentuh /pada akhir kode itu akan tercermin timur , bukan selatan. Kemudian, saat dalam mode Kardinal, IP akan membungkus ke kolom pertama. The \ada kembali memasuki modus Ordinal, sehingga paruh kedua kode tidak pergi dari kanan ke kiri di sini, tapi dari kiri ke kanan juga. Ini bermanfaat ketika bekerja dengan tumpukan alamat pengirim, karena tidak menyimpan informasi tentang arah IP. Ini memungkinkan kita menyimpan beberapa byte karena IP akan bergerak ke arah (horisontal) yang sama pada keduanya wdan k.

Kode linear adalah ini:

IY' *mRw..Y;m;.!z?~RZOk@

Mari kita lalui:

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.
Martin Ender
sumber
1
Saya harus memposting tantangan lain untuk tata letak baru yang Anda buat! : D Sangat bagus, saya pikir saya akan mulai menggunakannya bahkan ketika saya tidak menggunakan tumpukan kembali, lebih mudah untuk membaca kedua bagian kode dari kiri ke kanan
Leo
4

Jelly , 23 22 byte

-1 byte berkat Leo (kiri bawah mungkin padding)

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

Program lengkap mencetak hasilnya (tautan monadik mengembalikan daftar daftar karakter).

Cobalah online! atau lihat test suite .

Bagaimana?

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)
Jonathan Allan
sumber
1

JavaScript (ES6), 104 byte

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>

Bekerja dengan meniru jalur eksekusi dan mengisi perintah saat berjalan.

Neil
sumber
Sepertinya ide yang bagus, tapi saya tidak cukup tahu tentang javascript untuk memahami algoritma yang Anda gunakan ... Bisakah Anda menambahkan beberapa penjelasan?
Leo
@ Leo Saya tidak yakin berapa banyak lagi yang bisa saya jelaskan. Seperti yang Anda tahu, perintah mengikuti garis zig-zag dari kiri ke kanan dan kembali ke kiri lagi. The 1&~imencapai zig-zag vertikal, sedangkan i+i>l?l-i:imencapai cermin di tengah jalan. Setelah semua perintah dimasukkan ke posisi eksekusi yang diinginkan, array kemudian dikumpulkan bersama untuk menghasilkan hasil yang diinginkan.
Neil