Carré-spirale la chaîne!

12

Étant donné une chaîne, commencez par la mettre au carré comme suit:

Tout d'abord, écrivez la chaîne.

abcde

Ensuite, écrivez la chaîne tournée à gauche.

abcde
bcdea

Continuez ainsi jusqu'à ce que vous ayez écrit des lignes len (chaîne) .

abcde
bcdea
cdeab
deabc
eabcd

Maintenant, lisez la chaîne comme ceci:

----+
+--+|
|+>||
|+-+|
+---+

Qui donne:

abcdeabcdcbaedcbcdeabaede

Imprimez cette chaîne.

Cas de test

abcdef -> abcdefabcdedcbafedcbcdefabcbafedefaf
cena! -> cena!cenanec!anena!cec!a!
ppcg -> ppcgppcppgcpcgpg
abc -> abcabacbc
ab -> abab
a -> a
 -> 

Veuillez commenter si un scénario de test est incorrect.

N'oubliez pas qu'il s'agit de , donc le code avec le plus petit nombre d'octets l'emporte.

Oliver Ni
la source
2
cena!est faux. Il devrait correspondre à votre exemple, abcdecar les deux sont de 5 lettres:cena!cenanec!anena!cec!a!
Linus
@Linus Merci, je l'ai corrigé.
Oliver Ni

Réponses:

7

JavaScript (ES7), 83 80 78 77 octets

s=>s.repeat(l=s.length).replace(/./g,_=>s[(c-=--i**.5-l&1||-1)%l],c=-1,i=l*l)

Programme conforme à ES3 en prime:

for(s=prompt(r=""),c=-1,l=s.length,i=l*l;i;)r+=s[(c-=l-Math.sqrt(i--)&1||-1)%l];alert(r)

Explication

Cela profite du fait que la sortie, par exemple pour une chaîne de longueur 5, peut être représentée comme:

abcdeabcd cbaedcb cdeab aed e
012345678 7654321 23456 543 4

où chaque chiffre représente un index dans la chaîne (à partir de 0), modulez la longueur de la chaîne. En d'autres termes, si n est la longueur de la chaîne, nous incrémentons l'index 2n - 1 fois, puis le décrémentons 2 (n - 1) - 1 fois, puis l'incrémentons 2 (n - 2) - 1 fois, etc. Cela peut être simplifié par l'algorithme suivant:

  • Commencez l'index i à -1 .
  • Pour chaque entier x dans la plage [n 2 ..1] :
    • Si floor (sqrt (x)) est de la même parité (paire / impaire) que n , incrémentez i .
    • Sinon, décrémenter i .
    • Ajoutez le caractère à l'index i mod n à la sortie.

Cela fonctionne parce que floor (sqrt (x)) change de parité après 2n - 1 itérations, puis 2 (n - 1) - 1 itérations, etc.

ETHproductions
la source
Ridicule. Bon travail!
MayorMonty
1

Pyth , 15 octets

.Wp.(H0_CZ.<LQU

Un programme qui prend l'entrée d'un "quoted string"et imprime le résultat.

Essayez-le en ligne! ou vérifiez tous les cas de test (modifiés pour plusieurs entrées).

Comment ça fonctionne

.Wp.(H0_CZ.<LQU  Program. Input: Q
            L U  Map over [0, 1, 2, 3, ..., Q-1] (implicit input):
          .< Q     Q left-shifted by that many characters
                 Call this X
.W               While
   .(H0          popping the first element of X (mutates X in-place)
  p              and printing it with no trailing newline is truthy:
         Z           X = 
        C            X transposed
       _             reversed
TheBikingViking
la source
1

Python 2.7 (dans CMD.EXE), 91 octets

Cela nécessite un terminal avec un backspace fonctionnel ( \b), et ne fonctionnera pas sur repl.it ou ideone.com . Une instruction print se terminant par une virgule sépare la sortie supplémentaire par un espace au lieu d'une nouvelle ligne ou d'un retour. Le retour arrière nous permet d'écraser l'espace de séparation.

s=input();r=s[::-1];n=len(s)-1;i=0
while i<=n:print'\b'+s[i:]+s[:n-i]+r[i+2:]+r[:n-i],;i+=2

Python 2.7, 96 octets

Essayez-le sur ideone.com ou repl.it (merci à Oliver). L'entrée doit être une chaîne python, par exemple 'cena!'.

s=input();r=s[::-1];n=len(s)-1;i=0;S=''
while i<=n:S+=s[i:]+s[:n-i]+r[i+2:]+r[:n-i];i+=2
print S

Les quatre tranches annexées par la boucle ( s[i:], s[:n-i], r[i+2:], r[:n-i]) sont prises à partir des quatre bords de la spirale. Par exemple, avec 01234le carré est:

01234
12340
23401
34012
40123

Nous prenons donc 01234, 0123, 210, 4321. La variable iest l'indice de la valeur en haut à gauche à chaque étape du processus. Dans la spirale finale, plusieurs des tranches peuvent être vides.

Linus
la source
Il est sans doute pas la seule sauver, mais en changeant de Python 3, se débarrasser de la S='', print Set S+=, et tout emballage avant i+=2dans une print()déclaration avec sep='', vous pouvez enregistrer 2 octets.
Kade
@Shebang, je ne suis pas tout de suite. N'hésitez pas à ajouter vous-même une réponse python 3.
Linus
Vous pouvez changer i<=npourn>i
Oliver Ni
Il enregistre un octet.
Oliver Ni
@Oliver, merci ... mais cela ne fonctionne pas pour"a string of odd length."
Linus
1

Gelée , 11 10 octets

ẋ2µṖȮṖUµÐL

TryItOnline! ou tous les tests

Comment?

Le carré non spiralé est une série de tirages "bord supérieur plus bord droit" et "bord inférieur plus bord gauche", chacun étant l'inverse du tirage précédent sans la première et la dernière lettre, et le premier est l'entrée plus l'entrée sans la dernière lettre (par exemple, l'entrée "abcde"a une sortie de "abcdeabcd" + "cbaedcb" + "cdeab" + "aed" + "e").

ẋ2µṖȮṖUµÐL - Main link: s                            e.g. abcde
ẋ2         - repeat s twice                          e.g. abcdeabcde
  µ    µ   - monadic chain separation
        ÐL - repeat until results are no longer unique:
   Ṗ       -     remove the last character                abcdeabcd / cbaedcb / cdeab / aed / e   / ""
    Ȯ      -     print z (with no linefeed) and return z
     Ṗ     -     remove the last character                abcdeabc  / cbaedc  / cdea  / ae  / ""  / ""
      U    -     reverse                                  cbaedcba  / cdeabc  / aedc  / ea  / ""  / "" <- no longer unique.
Jonathan Allan
la source
1

05AB1E, 12 octets

2×[DõQ#¨D?¨R

Essayez-le en ligne!

Explication:

 2×[DõQ#¨D?¨R
               # Implicit input
 2×            # Repeat twice
   [           # Begin infinite loop
┏>  DõQ#       # If empty string, break
┃       ¨      # Remove last character
┃        D     # Duplicate
┃         ?    # Print with no newline and pop
┃          ¨   # Remove last character
┃           R  # Reverse
┗━━━━━━━━━━━━┛ # Implicit end infinite loop
Oliver Ni
la source
0

C, 95 94 octets

i,j,k,l;f(char*s){for(k=-1,l=i=strlen(s);i--;)for(j=i*2;~j--;putchar(s[(k+=(l-i)%2*2-1)%l]));}

Inspiré par la réponse @ETHproductions.

cleblanc
la source
0

Perl, 99 octets

$_=<>;
chop;
@a=split//;
print(@a[$%,(@f=1-($b=@a-$%)..$b-3),$b-1?$b-2:(),reverse@f]),$%+=2 until$%>@a

Les espaces blancs ne font pas partie du programme et sont fournis pour la lisibilité.

Code pas extrêmement efficace. Je devrais pouvoir raccourcir les trois premières lignes d'une manière ou d'une autre, mais tout ce que j'ai essayé de faire a échoué. Cet opérateur ternaire doit également être corrigé d'une manière ou d'une autre, mais le faire de cette façon a permis de raccourcir mon code de 10 octets, car je pouvais tellement découper.

Le code fonctionne en compilant une liste de palindromes, séparés par des nombres pairs, qui représentent les valeurs de position de la chaîne à extraire.

Gabriel Benamy
la source
Vous pouvez utiliser -F ce qui remplacera les lignes 1 et 3. Donnez l'entrée avec echo -npour supprimer le chop. (cela devrait vous faire environ 81 octets)
Dada
0

En fait , 21 13 octets

Cet algorithme est largement basé sur la réponse Jelly de Jonathan Allan . Il existe deux méthodes pour imprimer le résultat en une seule chaîne. L'approche utilisée ici duplique une étape intermédiaire, puis l'ajoute à un total cumulé dans le registre 1 (une chaîne vide par défaut); ;╕dans la fonction, puis à la fin. L'autre approche consiste à dupliquer une étape intermédiaire, à laisser ces étapes en double sur la pile et à les additionner en une seule chaîne à la fin; ;dans la fonction, puis à la fin.

Suggestions de golf bienvenues. Essayez-le en ligne!

2*`dX;╕dXR`Y╛

Ungolfing

         Implicit input s.
2*       Push a string that repeats s two times.
`...`Y   Call the following function until there is no change from the last call
  dX       Discard the last element. Call this new string m.
  ;╕       Duplicate m and add it to the running total in register 1.
  dXR      Discard the last element again and reverse the string.
╛        Push the unspiralled string from register 1 to the stack.
         Implicit return.
Sherlock9
la source
0

Python 3, 59 octets

x=input()*2
while x:x=x[:-1];print(x,end='');x=x[:-1][::-1]

repl.it

Un port direct de ma réponse Jelly ; seulement un programme complet prenant une entrée (plutôt qu'une fonction).
Il print(x,end='')s'agit d'une instruction d'impression qui n'imprimera pas la nouvelle ligne par défaut.

Jonathan Allan
la source
-1

Python 3, 93 octets

s=input();r,n,i=s[::-1],len(s)-1,0
while n-i:print(s[i:]+s[:n-i]+r[i+2:]+r[:n-i],end='');i+=2

Essayez-le en ligne!

Oliver Ni
la source
Plutôt que print(...,end=''), faitesprint(end=s[i:]+s[:n-i]+r[i+2:]+r[:n-i]
FlipTack
1
Quoi qu'il en soit, cette solution ne fonctionne pas abcde, il en manque un eà la fin.
FlipTack
Essayez i<=nplutôt que n-ipour votre condition.
Linus