Mise en forme ordinale d'Alice

9

introduction

Alice est un langage 2D de Martin Ender qui a deux modes d'exécution différents, cardinal et ordinal . Lorsque le pointeur d'instruction passe à travers un miroir (soit /ou \), il passe d'un mode à l'autre.

Dans ce défi, nous nous concentrerons sur le mode ordinal , où les commandes opèrent sur les chaînes et le pointeur d'instructions se déplace en diagonale, rebondissant contre les bords du code.

Des programmes simples fonctionnant uniquement en mode ordinal peuvent être écrits dans un style assez compact, comme dans l'exemple suivant:

/fbd/
@aec\

Ici , le IP démarre en mode cardinal de la première cellule vers l' est, passe par le premier miroir et commence à se déplacer en diagonale et rebondir, l' exécution des commandes a, bet c. Il rencontre alors le miroir nord-est qui fait aller au sud vers l'autre miroir, puis commencer à rebondir vers l'ouest, rencontrant des commandes d, e, fet enfin @, ce qui met fin au programme.

Ce type de structure est assez compact, mais ce n'est pas facile à écrire et à maintenir (l'ajout d'une seule commande peut nous forcer à réorganiser la plupart du code!), Donc j'aimerais que vous m'aidiez à formater.

La tâche

Étant donné une séquence de commandes, où chaque commande est un seul caractère ASCII imprimable, réorganisez-les sur deux lignes afin que la première moitié de la séquence puisse être lue à partir du premier caractère de la deuxième ligne, puis en se déplaçant toujours en diagonale vers la droite, tandis que la seconde moitié peut être lue en prenant les caractères restants de droite à gauche. Ne vous inquiétez pas des miroirs et du symbole de terminaison, je les ajouterai moi-même.

Ainsi, par exemple, étant donné l'entrée, abcdefvous devez sortir

fbd
aec

Dans le cas où l'entrée est de longueur impaire, vous devez ajouter un seul espace (qui est un noop dans Alice) n'importe où, tant que la séquence de commandes rencontrée reste la même. Vous pouvez également choisir de sortir deux lignes de longueur différente d'un caractère, auquel cas la plus courte est considérée comme ayant un seul espace à la fin.

Règles

C'est le , la réponse la plus courte, en octets, gagne!

  • Vous pouvez entrer / sortir via l'une des méthodes d' entrée / sortie par défaut
  • L'entrée se compose d'une seule ligne de caractères ASCII imprimables
  • Une seule nouvelle ligne de fin est autorisée dans la sortie
  • Certaines sorties de votre programme peuvent ne pas avoir un comportement complètement correct lorsqu'elles sont exécutées en tant que programmes Alice (par exemple si l'espace de remplissage est inséré à l'intérieur d'un littéral de chaîne). Vous n'avez pas à vous préoccuper de ces situations
  • Les failles standard sont interdites

Cas de 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)
Leo
la source

Réponses:

1

Gelée , 15 octets

œs2U2¦ṚZUJḤ$¦ZY

Essayez-le en ligne!

Prend l'entrée citée.

Explication:

œ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 le Outgolfer
la source
12

Alice , 28 octets

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

Essayez-le en ligne!

Si la longueur d'entrée est impaire, cela place l'espace de remplissage à la fin du programme linéarisé, qui finit par être le premier caractère de la sortie.

Leo a écrit un formateur ordinal dans Alice il y a quelques jours. Après avoir ajouté la prise en charge des entrées de longueur impaire, puis supprimé certaines choses qui n'étaient pas nécessaires pour ce défi, nous nous sommes retrouvés à 28 octets . Je voulais essayer une approche légèrement différente, qui est cette réponse. Malheureusement, cela a fini par lier 28 octets, mais au moins de cette façon, je peux publier ma propre solution et laisser Leo publier son algorithme d'origine.

Cela utilise l'idée vraiment intelligente de Leo pour diviser une chaîne en deux avec ..Y;m;.!z?~.

Explication

Supposons que l'entrée ait une longueur paire (car nous la remplirons simplement avec un espace si ce n'est pas le cas). Le modèle est un peu plus facile à voir si nous l'utilisons 0123456789comme code. La sortie requise serait:

91735
08264

Ainsi, la première ligne contient toutes les positions impaires de l'entrée et la deuxième ligne toutes les entrées paires. De plus, si nous inversons les positions impaires, alors les lignes elles-mêmes sont toutes les deux la première moitié (éventuellement plus longue) entrelacées avec l'inverse de la seconde moitié.

L'idée de base est donc:

  • Entrée séparée en positions paires et impaires.
  • Remplissez les positions impaires avec un espace si nécessaire.
  • Inversez les positions impaires.
  • Puis deux fois: divisez par deux la chaîne actuelle, inversez la seconde moitié, entrelacez les deux moitiés, imprimez avec un saut de ligne de fin.

Quant au code, cela ressemble beaucoup au type de mise en page que nous produisons dans ce défi, mais il est subtilement différent: lorsque l'IP atteint /la fin du code, il se reflète à l' est , pas au sud. Ensuite, en mode Cardinal, l'IP passera à la première colonne. Le \il revient en mode Ordinal, de sorte que la seconde moitié du code ne va pas de droite à gauche ici, mais de gauche à droite également. Cela est avantageux lorsque vous travaillez avec la pile d'adresses de retour, car elle ne stocke pas d'informations sur la direction de l'adresse IP. Cela nous permet d'économiser quelques octets car l'IP se déplacera dans la même direction (horizontale) sur les deux wet k.

Le code linéarisé est le suivant:

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

Passons en revue:

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
la source
1
Je vais devoir poster un autre défi pour cette nouvelle mise en page que vous avez imaginée! : D Très bien, je pense que je vais commencer à l'utiliser même si je n'utilise pas la pile de retour, il est plus facile de lire les deux moitiés du code de gauche à droite
Leo
4

Gelée , 23 22 octets

-1 octet grâce à Leo (en bas à gauche peut être le rembourrage)

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

Un programme complet imprimant le résultat (le lien monadique renvoie une liste de listes de listes de caractères).

Essayez-le en ligne! ou consultez une suite de tests .

Comment?

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
la source
1

JavaScript (ES6), 104 octets

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>

Fonctionne en émulant le chemin d'exécution et en remplissant les commandes au fur et à mesure.

Neil
la source
Cela semble être une bonne idée, mais je ne connais pas assez le javascript pour comprendre l'algorithme que vous avez utilisé ... Pourriez-vous ajouter quelques explications?
Leo
@Leo Je ne sais pas combien je peux expliquer de plus. Comme vous le savez, les commandes suivent une ligne en zig-zag de gauche à droite et de nouveau à gauche. Le 1&~iréalise le zig-zag vertical, tandis que lei+i>l?l-i:i réalise le miroir à mi-chemin. Une fois que toutes les commandes ont été entrées dans les positions d'exécution souhaitées, la matrice est ensuite collectée ensemble pour produire le résultat souhaité.
Neil