Rouler le tapis

15

Cette question est inspirée de la question de Kevin Cruijssen .

Maintenant que le tapis est posé, nous voulons le rouler. Votre tâche consiste à écrire un programme qui prend une chaîne et renvoie une spirale faite à partir de cette chaîne (représentant un tapis roulé vu de côté).

La procédure pour une étape de roulement du tapis est la suivante. Il y a un exemple pour illustrer ce que je veux dire. Notez que l'exemple commence par un tapis partiellement roulé pour une meilleure compréhension:

ac
rpet
  • séparer la "tête" de la "queue" du tapis: la tête est ce qui a été roulé jusqu'à présent, la queue est ce qui reste à rouler.
Head: ac   Tail:
      rp          et
  • Tournez la tête de 90 ° dans le sens des aiguilles d'une montre.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • si la largeur de la nouvelle tête (ici 2) est inférieure ou égale à la longueur de la queue (ici 2)
    • puis placez-le sur la queue
    • sinon, le tapis (comme au début de l'étape) était enroulé
New carpet: ra
            pc
            et

Répétez la procédure autant de fois que nécessaire.


Deux exemples illustrant toutes les étapes du roulement du tapis:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Quelques précisions:

  • Vous n'avez pas besoin de montrer toutes les étapes intermédiaires, seulement le tapis roulé (par exemple, si vous trouvez un moyen non itératif de calculer le résultat, c'est parfait). De plus, vous n'avez pas besoin d'imprimer d'espace blanc de premier plan, dans les exemples ci-dessus, je ne les montre que pour aligner les éléments.
  • L'entrée est une chaîne, une liste / un tableau de caractères
  • La sortie est imprimée sur stdout ou dans un fichier.
  • L'entrée est agréable: la longueur est d'au moins 1 caractère et au plus une constante suffisamment petite pour ne pas causer de problèmes, mais vous ne pouvez pas utiliser cette constante dans votre programme; le contenu de la chaîne n'est que de beaux caractères ([a-zA-Z0-9]), encodés à votre guise.
  • C'est le , donc la réponse la plus courte en octets l'emporte. Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues non-golfeur de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • Ajoutez également une explication à votre réponse si vous pensez qu'elle est nécessaire.
Bromind
la source
3
Étroitement liés
Giuseppe
2
Aussi celui-ci: codegolf.stackexchange.com/questions/125966/… , mais aucun n'inclut le contrôle de résiliation.
Bromind
3
Cas de test suggéré: ProgrammingPuzzlesAndCodeGolf- la longueur finale de la queue supérieure à 1 m'a déclenché.
Sok
1
Je pense que vous avez échangé les mots "tête" et "queue" ici: "si la largeur de la nouvelle tête [...] est supérieure ou égale à la longueur de la queue [...]".
Erik the Outgolfer
1
Voté en raison de règles d'entrée / sortie trop restrictives; J'ai supprimé ma réponse Python 2 car on ne peut pas l'utiliser à l' printintérieur d'un lambda.
Chas Brown

Réponses:

7

Fusain , 15 octets

FS«F¬℅§KV⁰⟲⁶→Pι

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

FS«

Faites une boucle sur le tapis.

F¬℅§KV⁰

Vérifiez s'il y a quelque chose au-dessus du curseur.

⟲⁶

Sinon, roulez le tapis.

→Pι

Déplacer vers la droite et sortir le caractère actuel.

Exemple: pour l'entrée 0123456789, les actions suivantes se produisent:

0

0 est imprimé.

01

Le curseur se déplace vers la droite et 1s'imprime.

0
1

Puisqu'il n'y a rien au-dessus de 1, la toile est tournée.

0
12

Le curseur se déplace vers la droite et 2est imprimé.

10
2

Puisqu'il n'y a rien au-dessus de 2, la toile est tournée.

10
23

Le curseur se déplace vers la droite et 3est imprimé.

10
234

Le curseur se déplace vers la droite et 4est imprimé.

21
30
4

Puisqu'il n'y a rien au-dessus de 4, la toile est tournée.

21
30
45

Le curseur se déplace vers la droite et 5est imprimé.

21
30
456

Le curseur se déplace vers la droite et 6est imprimé.

432
501
6

Puisqu'il n'y a rien au-dessus de 6, la toile est tournée.

432
501
67

Le curseur se déplace vers la droite et 7est imprimé.

432
501
678

Le curseur se déplace vers la droite et 8est imprimé.

432
501
6789

Le curseur se déplace vers la droite et 9est imprimé.

Neil
la source
C'est génial. Donc, fondamentalement, Charcoal a un opérateur de "rouleau" intégré ?
Jonah
1
@ Jonah Eh bien, ça ne roulera pas pour moi au fur et à mesure, mais en affichant la chaîne caractère par caractère, je peux rouler au fur et à mesure, oui.
Neil
3

Pyth, 37 octets

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt

Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQtQ   Implicit: Q=eval(input())
                                         Trailing Q inferred
                                 ]hQ     First character of Q, wrapped in an array
                                    tQ   All but the first character of Q
                                ,        2-element array of the two previous results
                                           This yields array with rolled carpet (as array of strings) followed by the tail
       .W                                While condition function is truthy, execute inner function, with initial value of the above:
         gleHJlhH                          Condition function, input H
             JlhH                            Number of layers in the current rolled carpet, store in J
          leH                                Lenth of the tail
         g   J                               Is the above greater than or equal to J?
                 ,+_MChZ<eZJ>eZJ           Inner function, input Z
                   _MChZ                     Rotate the current rolled carpet (transpose, then reverse each row)
                  +     <eZJ                 Append the first J characters of the tail as a new row
                 ,                           Pair the above with...
                            >eZJ             ... all but the first J characters of the tail - this is the new tail
.U+j;bZ                                  Join the carpet roll on newlines and append the tail, implicit print
Sok
la source
3

Husk , 24 octets

►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N

Essayez-le en ligne!

Explication

Implicit input, say s="carpets"

CṘ2N  Break s into chunks:
   N   Natural numbers: [1,2,3,4,..
 Ṙ2    Repeat each twice: [1,1,2,2,3,3,4,4,..
C      Break s into chunks of these lengths: ["c","a","rp","et","s"]
       The last chunk is shorter if we run out of characters.

§z:oΘḣĠ+  Attempt to merge suffix of chunks:
      Ġ    Cumulative reduce chunk list from right
       +   by concatenation: ["carpets","arpets","rpets","ets","s"]
   oΘḣ     Prefixes of chunk list (empty and nonempty): [[],["c"],..,["c","a","rp","et","s"]]
§z         Zip these by
  :        appending: [["carpets"],["c","arpets"],..,["c","a","rp","et","s"]]
           These are all versions of the chunk list where some suffix has been merged.

mFȯ:T↔ø  Roll each list:
m         Map
 F        reduce from left
      ø   starting from empty character matrix
  ȯ:T↔    by this function:
    T↔     Reverse and transpose (rotating by 90 degrees)
  ȯ:       then append next chunk as new row.
         Result: [["carpets"],["c","arpets"],..,["epr","tca","s"]]

►S=ÖL  Select the matrix rolled by the correct amount:
►       Find element that maximizes
 S=     being equal to
   ÖL   sort by length.
        This selects a matrix whose rows have non-decreasing lengths.
        Ties are broken by choosing the rightmost one.
       Result: ["ra","pc","ets"]

Implicitly print each row separated by newlines.
Zgarb
la source
2

J , 69 octets

-3 octets grâce à FrownyFrog

[:(}:@[,{:@[,])&>/[:((|:@|.@[,#@[$]);#@[}.])&>/^:(<:&#&>/)^:_,.@{.;}.

Essayez-le en ligne!

explication

[: (}:@[ , {:@[ , ])&>/ [: ((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/^:(<:&#&>/)^:_ }. ;~ 1 1 $ {.

L'algorithme est simple en dépit d'être un peu bavard pour J.

Stratégie globale: Réduisez l'entrée à une table carrée, avec une pièce restante (éventuellement vide).

Au fur et à mesure que nous réduisons, nous utiliserons une liste de cases à 2 éléments. Notre "résultat jusqu'à présent" sera la première case, et les "articles restant à traiter" seront la 2ème case. La première case sera initialisée en tête de l'entrée (mais convertie en tableau):

1 1 $ {.

et "les éléments restant à traiter" seront la queue de l'entrée:

}. ;~

Maintenant nous avons:

┌─┬─────┐
│c│arpet│
└─┴─────┘

où le «c» est en fait une table 1x1.

Nous réduisons cela à l'aide d'une boucle J Do ... While:

^:(...)^:_

Où la partie entre parenthèses est la condition "continuer":

<:&#&>/

qui dit "continuez pendant que la longueur de la boîte de droite est supérieure ou égale à la longueur de la boîte de gauche (c'est-à-dire la longueur du côté de la matrice carrée)

Que signifie "continuer"? Cela est défini dans le verbe à gauche du premier ^:, qui nous indique comment prendre le résultat actuel et produire l'itération suivante. Ce verbe est:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/

Décomposons-le:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  verb in parens               )&>/ NB. put the verb in parens
                                     NB. between the two items
                                     NB. of our list, and unbox
                                     NB. them into left / right
                                     NB. args ([ / ]) for the verb
 (|:@|.@[ , #@[ {. ]) ; #@[ }. ]     NB. breaking down verb in 
                                     NB. parens...
                      ; ....         NB. new "remaining items":
                            }. ]     NB. remove from remaining
                        #@[          NB. the size of a side of
                                     NB. the result matrix
                ....  ;              NB. new "result":
  |:@|.@[                            NB. rotate existing result
          ,                          NB. and put it on top of
            #@[ {. ]                 NB. the items we removed
                                     NB. from remaining items

Autrement dit, ce n'est qu'un algorithme décrit dans l'OP traduit littéralement en J.

Enfin, nous traitons des (éventuellement 0) objets restants, la queue de notre rouleau de tapis:

(}:@[ , {:@[ , ])&>/

Cela dit "prenez tout sauf le dernier orme du résultat":

}:@[ 

et l'ajouter aux ,derniers éléments du résultat {:@[avec les éléments restants ajoutés à ce dernier élément, ]

Jonas
la source
Ah, J ... les lettres sont pour les noobs
RK.
,.peut faire ce qui 1 1$]fait et $peut être utilisé comme {..
FrownyFrog
@FrownyFrog ty. Je suis arrivé à 70 octets avec votre première suggestion, mais je ne savais pas si je comprenais $ can be used as {.- pouvez-vous clarifier?
Jonah
1
La dernière ligne de l'explication, vous utilisez {. pour tronquer, celui-ci peut être un $ pour autant que je comprends.
FrownyFrog
Vous pouvez également remplacer le droit [: par un @
FrownyFrog
1

R , 146 132 octets

function(s){m=F[F]
while({m=rbind(t(m)[,F:0],s[1:F])
s=s[-1:-F]
length(s)>sum(F<-dim(m))})0
write(m[F:1,],1,F[1],,"")
cat(s,sep="")}

Essayez-le en ligne!

Met en œuvre la procédure de laminage de tapis. Prend la saisie sous forme de liste de caractères et imprime sur la sortie standard.

Sauvegardé 14 octets en trouvant un moyen d'utiliser une do-whileboucle et en l'initialisant à l'aide de F.

function(s){
m=F[F]					# logical(0); create an empty array (this gets automatically promoted to character(0) later
while(					# do-while loop
      {m=rbind(t(m)[,F:0],s[1:F])	# rotate m counterclockwise and add the first F characters of s to the bottom
       s=s[-1:-F]			# remove those characters
       length(s)>sum(F<-dim(m))})0	# while the number of characters remaining is greater than the sum of m's dimensions
write(m[F:1,],1,F[1],,"")		# write the rolled portion write writes down the columns, we reverse each column
cat(s,sep="")				# and write the remaining characters
}
Giuseppe
la source
1

Gelée , 30 octets

Semble trop long ...

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ

Essayez-le en ligne!

Comment?

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ - Main Link: list of characters
Ḣ                              - pop and yield head
 W                             - wrap in a list
  ,                            - pair with (the remaining list after Ḣ)
                         ¿     - while...
                        $      - ...condition: last two links as a monad:
                     Ẉ         -   length of each
                       Ƒ       -   is invariant under:
                      Ṣ        -     sort
                    /          - ...do: reduce by:
   ð               ð           -   the enclosed dyadic chain -- i.e. f(head, tail):
    Z                          -     transpose
     U                         -     reverse each (giving a rotated head)
              ɗ                -     last three links as a dyad:
          ¥                    -       last two links as a dyad:
       L                       -         length (i.e. number of rows in current roll)
         @                     -         with swapped arguments:
        s                      -           split (the tail) into chunks of that length
           ©                   -       (copy to register for later)
            Ḣ                  -       pop and yield head (Note register "copy" is altered too)
             W                 -       wrap in a list
      ;                        -     concatenate (the rotated head with the first chunk of the tail)
                  ¤            -     nilad followed by link(s) as a nilad:
                ®              -       recall from register (other chunks of tail, or an empty list)
                 Ẏ             -       tighten (the chunks to a flat list)
               ,               -     pair (the concatenate result with the tightened chunks)
                             Ɗ - last three links as a monad:
                          Ḣ    -   pop and yield head
                           Y   -   join with newline characters
                            ;  -   concatenate (the remaining tail)
                               - when running as a full program implicitly prints
Jonathan Allan
la source
1

05AB1E , 41 octets

g©L¦€DD2šηO®>‹Ï©IŽ8OS®g4α._.ΛðÜI®O®g->.$«

Beaucoup trop long, mais je voulais utiliser le Canvas .. Ce qui était probablement un mauvais choix maintenant que je l'ai fini et il s'est avéré être aussi long ..

Essayez-le en ligne . (Pas de suite de tests, car il semble y avoir un problème étrange avec la fonction intégrée ..)

Explication:

Permettez-moi de commencer par donner une explication générale du canevas et de ce que je voulais que mon code accomplisse. Des informations plus détaillées peuvent être trouvées dans cette astuce pertinente 05AB1E , mais pour ce défi, je voulais avoir ce qui suit:

La fonction intégrée de Canvas prend trois paramètres:

  • une[2,2,3,3,4,4,5,5,...]
  • b
  • c[2,0,6,4][,,,]ncarpet[0,6,4,2]0123456789ABCDEFGHI[6,4,2,0]

Quant au code:

g                # Get the length of the (implicit) input-string
 ©               # Store it in the register (without popping)
  L              # Create a list in the range [1,length]
   ¦             # Remove the first item to make the range [2,length]
    D           # Duplicate each to get the list [2,2,3,3,4,4,5,5,...]
      D2š        # Create a copy and prepend a 2: [2,2,2,3,3,4,4,5,5,...]
         η       # Get the prefixes: [[2],[2,2],[2,2,2],[2,2,2,3],...]
          O      # Sum each prefix: [2,4,6,9,12,16,20,...]
           ®     # Push the length from the register again
            >‹   # Check for each summed prefix if it's <= length
              Ï  # And only leave the truthy values
               © # And store this in the register (without popping)
                 # (This is our `a` for the Canvas builtin)
I                # Push the input-string
                 # (This is our `b` for the Canvas builtin)
Ž8O              # Push compressed integer 2064
   S             # Converted to a list of digits: [2,0,6,4]
    ®g           # Push the list from the register, and get its length
      4α         # Get the absolute difference with 4
        ._       # And rotate the [2,0,6,4] that many times towards the left
                 # (This is our `c` for the Canvas builtin)
               # Now use the Canvas builtin, without printing it yet
  ðÜ             # Remove any trailing spaces (since the Canvas implicitly makes a rectangle)
     ®O          # Push the sum of the list from the register
       ®g-       # Subtract the length of the list from the register
          >      # And add 1
    I      .$    # Remove that many leading characters from the input-string
             «   # And append it at the end of the roll created by the Canvas
                 # (after which the result is output implicitly)

Voir cette astuce de mes 05AB1E (section Comment compresser les grands entiers? ) Pour comprendre pourquoi Ž8Oest 2064.

Kevin Cruijssen
la source
0

Python 3 , 112 octets

r=lambda t,h=[[]]:len(h)>len(t)and h[:-1]+[h[-1]+list(t)]or r(t[len(h):],list(zip(*h[::-1]))+[list(t)[:len(h)]])

Dans ce cas, la sortie est la valeur de la fonction.

Essayez-le en ligne!

Si vous préférez, voici une autre solution (plus longue, 129 octets ) qui imprime directement l'entrée laminée:

r=lambda t,h=['']:len(h)>len(t)and set(map(print,h[:-1]+[h[-1]+t]))or r(t[len(h):],list(map(''.join,zip(*h[::-1])))+[t[:len(h)]])

Essayez-le en ligne!

PieCot
la source
1
besoin de l'imprimer
ASCII uniquement le
@ ASCII uniquement: citant l'auteur de la question: "Si le retour au lieu de l'impression montre une grande amélioration ou une bonne astuce, postez une réponse (et expliquez que vous revenez, pas l'impression)" . Je pense donc que ça va.
PieCot
0

MATLAB / Octave , 154 octets

Pas le plus court, mais jouer au golf à MATLAB / Octave est toujours amusant :)

function h=r(t,h);n=fliplr(h');s=size(n,2);q=numel(t);if s<=q h=r(t(max(s,1)+1:end),[n; t(1:max(s,1))]);elseif q>0 h(:,end+q)=' ';h(end,end-q+1:end)=t;end

Essayez-le en ligne!

PieCot
la source
1
malheureusement, op dit que vous devez imprimer
ASCII uniquement le
@ ASCII uniquement comme expliqué ici ( it.mathworks.com/matlabcentral/answers/… ), stdout dans le monde Matlab se réfère à la fenêtre de commande. Étant donné que le résultat de l'évaluation de chaque commande est automatiquement imprimé dans la fenêtre de commande, je pense que cette réponse pourrait être considérée comme conforme aux exigences de la question.
PieCot
pourrait vouloir clarifier cela alors
ASCII uniquement
@ ASCII uniquement, je ne comprends pas vraiment ce que tu veux dire. C'est une fonction, vous l'appelez, le résultat sera automatiquement imprimé sur la fenêtre de commande (ie stdout). Quel est le problème avec ça? Même la réponse R fonctionne comme ça ...
PieCot
1
En ce moment vous disp, je dirais que vous devriez enlever le displaisser les gens qui ne connaissent pas R qu'il fait écrire à STDOUT par défaut
ASCII seulement