La formattazione ordinale di Alice


9

introduzione

Alice è una lingua 2-d di Martin Ender che ha due diverse modalità di esecuzione, cardinale e ordinale . Quando il puntatore dell'istruzione passa attraverso un mirror (uno /o l'altro \), passa da una modalità all'altra.

In questa sfida ci concentreremo sulla modalità ordinale , in cui i comandi operano sulle stringhe e il puntatore dell'istruzione si sposta in diagonale, rimbalzando contro i bordi del codice.

I programmi semplici che funzionano solo in modalità ordinale possono essere scritti in uno stile abbastanza compatto, come nel seguente esempio:

/fbd/
@aec\

Qui l'IP si avvia in modalità cardinale dalla prima cellula verso est, attraversa il primo specchio e inizia a muoversi in diagonale e rimbalzare, l'esecuzione di comandi a, be c. Incontra quindi lo specchio nord-est che lo fa andare a sud verso l'altro specchio e quindi inizia a rimbalzare verso ovest, incontrando i comandi d, ee f, infine @, che termina il programma.

Questo tipo di struttura è piuttosto compatta, ma non è facile da scrivere e mantenere (l'aggiunta di un singolo comando potrebbe costringerci a riordinare la maggior parte del codice!), Quindi mi piacerebbe che mi aiutassi con la formattazione.

L'obiettivo

Data una sequenza di comandi, in cui ogni comando è un singolo carattere ASCII stampabile, riordinali su due righe in modo che la prima metà della sequenza possa essere letta a partire dal primo carattere della seconda riga e quindi spostandosi sempre in diagonale verso destra, mentre la seconda metà può essere letta prendendo i caratteri rimanenti da destra a sinistra. Non preoccuparti dei mirror e del simbolo di terminazione, li aggiungerò io.

Quindi, ad esempio, dato l'input abcdefche dovresti produrre

fbd
aec

Nel caso in cui l'input abbia una lunghezza dispari, dovresti aggiungere un singolo spazio (che è un noop in Alice) ovunque, purché la sequenza di comandi rilevata rimanga la stessa. Puoi anche scegliere di produrre due righe di lunghezza diversa per un carattere, nel qual caso quella più corta ha uno spazio singolo alla fine.

Regole

Questo è , la risposta più breve, in byte, vince!

  • È possibile immettere / emettere tramite uno dei metodi di immissione / emissione predefiniti
  • L'input è costituito da una singola riga di caratteri ASCII stampabili
  • È consentita una sola nuova riga finale nell'output
  • Alcuni output del tuo programma potrebbero non avere un comportamento completamente corretto quando eseguiti come programmi Alice (ad es. Se lo spazio di riempimento è inserito all'interno di una stringa letterale). Non devi preoccuparti di queste situazioni
  • Sono vietate le scappatoie standard

Casi test

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

Risposte:


1

Gelatina , 15 byte

œs2U2¦ṚZUJḤ$¦ZY

Provalo online!

Accetta input tra virgolette.

Spiegazione:

œ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

Alice , 28 byte

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

Provalo online!

Se la lunghezza dell'input è dispari, questo mette lo spazio di riempimento alla fine del programma linearizzato, che finisce per essere il primo carattere dell'output.

Leo ha scritto un formattatore ordinale ad Alice pochi giorni fa. Dopo aver aggiunto il supporto per input di lunghezza dispari e aver rimosso alcuni elementi non necessari per questa sfida, siamo arrivati ​​a 28 byte . Volevo provare un approccio leggermente diverso, che è questa risposta. Sfortunatamente, ha appena finito di legare 28 byte, ma almeno in questo modo posso pubblicare la mia soluzione e lasciare che Leo pubblichi il suo algoritmo originale.

Questo usa l'idea davvero intelligente di Leo di dividere una stringa a metà ..Y;m;.!z?~.

Spiegazione

Supponiamo che l'input abbia una lunghezza pari (perché lo faremo solo con uno spazio se non lo fa). Lo schema è un po 'più facile da vedere se usiamo 0123456789come codice. L'output richiesto sarebbe:

91735
08264

Quindi la prima riga contiene tutte le posizioni dispari dell'input e la seconda riga tutti gli input pari. Inoltre, se invertiamo le posizioni dispari, le linee stesse sono entrambe la prima metà (possibilmente più lunga) interlacciata con l'inverso della seconda metà.

Quindi l'idea di base è:

  • Separare l'input in posizioni pari e dispari.
  • Riempi le posizioni dispari con uno spazio, se necessario.
  • Invertire le posizioni dispari.
  • Quindi due volte: dimezzare la stringa corrente, invertire la seconda metà, interlacciare entrambe le metà, stampare con avanzamento riga finale.

Per quanto riguarda il codice, questo assomiglia molto al tipo di layout che stiamo producendo in questa sfida, ma è leggermente diverso: quando l'IP raggiunge /la fine del codice si riflette a est , non a sud. Quindi, mentre è in modalità Cardinale, l'IP passerà alla prima colonna. Il \re entra in modalità Ordinale, in modo che la seconda metà del codice non vada da destra a sinistra qui, ma anche da sinistra a destra. Questo è utile quando si lavora con lo stack di indirizzi di ritorno, perché non memorizza informazioni sulla direzione dell'IP. Questo ci consente di salvare alcuni byte perché l'IP si sposterà nella stessa direzione (orizzontale) su entrambi we k.

Il codice linearizzato è questo:

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

Andiamo attraverso:

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
Dovrò pubblicare un'altra sfida per questo nuovo layout che ti è venuta in mente! : D Molto carino, penso che inizierò a usarlo anche quando non uso lo stack di ritorno, è più facile leggere entrambe le metà del codice da sinistra a destra
Leo,

4

Gelatina , 23 22 byte

-1 byte grazie a Leo (in basso a sinistra potrebbe essere il riempimento)

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

Un programma completo che stampa il risultato (il collegamento monadico restituisce un elenco di elenchi di elenchi di caratteri).

Provalo online! o vedere una suite di test .

Come?

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

Funziona emulando il percorso di esecuzione e compilando i comandi mentre procede.


Sembra una bella idea, ma non so abbastanza di JavaScript per capire l'algoritmo che hai usato ... Potresti aggiungere qualche spiegazione?
Leone,

@Leo non sono sicuro di quanto più posso spiegare. Come sapete, i comandi seguono una linea a zig-zag da sinistra a destra e di nuovo a sinistra. Il 1&~iraggiunge lo zig-zag verticale, mentre la i+i>l?l-i:iraggiunge lo specchio a metà. Una volta immessi tutti i comandi nelle posizioni di esecuzione desiderate, l'array viene quindi raccolto insieme per produrre il risultato desiderato.
Neil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.