Rodar la alfombra

15

Esta pregunta está inspirada en la pregunta de Kevin Cruijssen .

Ahora que la alfombra está tendida, queremos enrollarla. Su tarea es escribir un programa que tome una cadena y devuelva una espiral hecha de esta cadena (que representa una alfombra enrollada vista desde el lado).

El procedimiento para un paso de rodar la alfombra es el siguiente. Hay un ejemplo para ilustrar lo que quiero decir. Observe que el ejemplo comienza con una alfombra parcialmente enrollada para una mejor comprensión:

ac
rpet
  • separe la "cabeza" de la "cola" de la alfombra: la cabeza es lo que se ha enrollado hasta ahora, la cola es lo que queda por enrollar.
Head: ac   Tail:
      rp          et
  • Gire la cabeza 90 °, en sentido horario.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • si el ancho de la nueva cabeza (aquí 2) es menor o igual que la longitud de la cola (aquí 2)
    • luego, póngalo encima de la cola
    • de lo contrario, la alfombra (como estaba al comienzo del paso) estaba enrollada
New carpet: ra
            pc
            et

Repita el procedimiento tantas veces como sea necesario.


Dos ejemplos que muestran todos los pasos de la alfombra rodando:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Algunas precisiones:

  • No necesita mostrar todos los pasos intermedios, solo la alfombra enrollada (por ejemplo, si encuentra una manera no iterativa de calcular el resultado, es perfecto). Además, no necesita imprimir ningún espacio en blanco inicial, en los ejemplos anteriores, solo les muestro para alinear cosas.
  • La entrada es una cadena, una lista / matriz de caracteres
  • La salida se imprime en stdout o en un archivo.
  • La entrada es buena: la longitud es de al menos 1 carácter, y como máximo una constante lo suficientemente pequeña como para que no cause problemas, pero no puede usar esa constante en su programa; el contenido de la cadena son solo caracteres agradables ([a-zA-Z0-9]), que codifica según su preferencia.
  • Este es el , por lo que la respuesta más corta en bytes gana. No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolf. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, agregue una explicación para su respuesta si cree que es necesaria.
Bromind
fuente
3
Muy relacionado
Giuseppe
2
También este: codegolf.stackexchange.com/questions/125966/… , pero ninguno incluye la verificación de terminación.
Bromind
3
Caso de prueba sugerido: ProgrammingPuzzlesAndCodeGolf- la longitud final de la cola mayor que 1 me hizo tropezar.
Sok
1
Creo que ha intercambiado las palabras "cabeza" y "cola" aquí: "si el ancho de la nueva cabeza [...] es mayor o igual que la longitud de la cola [...]".
Erik the Outgolfer
1
Votado en contra debido a reglas de entrada / salida demasiado restrictivas; Eliminé mi respuesta de Python 2 ya que no se puede usar printdentro de a lambda.
Chas Brown el

Respuestas:

7

Carbón de leña , 15 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

FS«

Pase sobre la alfombra.

F¬℅§KV⁰

Comprueba si hay algo encima del cursor.

⟲⁶

Si no, entonces ruede la alfombra.

→Pι

Mover a la derecha y generar el carácter actual.

Ejemplo: para la entrada 0123456789, se producen las siguientes acciones:

0

0 está impreso.

01

El cursor se mueve hacia la derecha y 1se imprime.

0
1

Como no hay nada encima 1, el lienzo se gira.

0
12

El cursor se mueve hacia la derecha y 2se imprime.

10
2

Como no hay nada encima 2, el lienzo se gira.

10
23

El cursor se mueve hacia la derecha y 3se imprime.

10
234

El cursor se mueve hacia la derecha y 4se imprime.

21
30
4

Como no hay nada encima 4, el lienzo se gira.

21
30
45

El cursor se mueve hacia la derecha y 5se imprime.

21
30
456

El cursor se mueve hacia la derecha y 6se imprime.

432
501
6

Como no hay nada encima 6, el lienzo se gira.

432
501
67

El cursor se mueve hacia la derecha y 7se imprime.

432
501
678

El cursor se mueve hacia la derecha y 8se imprime.

432
501
6789

El cursor se mueve hacia la derecha y 9se imprime.

Neil
fuente
Eso es genial. Entonces, ¿básicamente el carbón tiene un operador incorporado de "rollo" ?
Jonás
1
@ Jonás Bueno, no se moverá para mí a medida que avanza, pero al generar la cadena carácter por carácter, puedo hacerlo a medida que avanzo, sí.
Neil
3

Pyth, 37 bytes

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

Pruébelo en línea aquí , o verifique todos los casos de prueba a la vez aquí .

.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
fuente
3

Casco , 24 bytes

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

Pruébalo en línea!

Explicación

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

J , 69 bytes

-3 bytes gracias a FrownyFrog

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

Pruébalo en línea!

explicación

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

El algoritmo es sencillo a pesar de ser un poco detallado para J.

Estrategia general: reduzca la entrada a una tabla cuadrada, con una pieza sobrante (posiblemente vacía).

A medida que reduzcamos, utilizaremos una lista de cuadros de 2 elementos. Nuestro "resultado hasta ahora" será la primera casilla, y los "elementos restantes para procesar" serán la segunda casilla. El primer cuadro se inicializará en el encabezado de la entrada (pero se convertirá en una tabla):

1 1 $ {.

y "los elementos que quedan por procesar" serán la cola de la entrada:

}. ;~

Ahora tenemos:

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

donde la 'c' es en realidad una tabla 1x1.

Lo reducimos usando un bucle J Do ... While:

^:(...)^:_

Donde la parte entre paréntesis es la condición de "seguir adelante":

<:&#&>/

que dice "continúe mientras la longitud del cuadro derecho es mayor o igual que la longitud del cuadro izquierdo (es decir, la longitud lateral de la matriz cuadrada)

¿Qué significa "seguir adelante"? Eso se define en el verbo a la izquierda del primero ^:, que nos dice cómo tomar el resultado actual y producir la siguiente iteración. Ese verbo es:

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

Vamos a desglosarlo:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  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

Es decir, esto es solo un algoritmo descrito en el OP traducido literalmente a J.

Finalmente nos ocupamos de los (posiblemente 0) elementos sobrantes, la cola de nuestro rollo de alfombra:

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

Esto dice "toma todo menos el último olmo del resultado":

}:@[ 

y añádelo a ,los últimos elementos del resultado {:@[con los elementos restantes agregados a ese último elemento, ]

Jonás
fuente
Ah, J ... las letras son para novatos
RK.
,.puede hacer lo que 1 1$]hace y $puede usarse como {..
FrownyFrog
@FrownyFrog ty. Lo llevé a 70 bytes con su primera sugerencia, pero no estaba seguro de haberlo entendido $ can be used as {., ¿puede aclararlo?
Jonás
1
La última línea de la explicación, usa {. para truncar, ese puede ser un $ por lo que yo entiendo.
FrownyFrog
También puede reemplazar el derecho [: con un @
FrownyFrog
1

R , 146 132 bytes

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="")}

Pruébalo en línea!

Implementa el procedimiento de laminado de alfombras. Toma la entrada como una lista de caracteres e imprime en stdout.

Guardado 14 bytes por encontrar una manera de utilizar un do-whilebucle e inicializar utilizando 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
fuente
1

Jalea , 30 bytes

Parece demasiado largo ...

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

Pruébalo en línea!

¿Cómo?

Ḣ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
fuente
1

05AB1E , 41 bytes

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

Demasiado tiempo, pero quería usar el Canvas ... lo cual probablemente fue una mala elección ahora que lo terminé y resultó ser tan largo ...

Pruébalo en línea . (No hay una suite de prueba, porque parece haber un problema extraño con el incorporado ...)

Explicación:

Permítanme comenzar dando una explicación general del Canvas y lo que quería que lograra mi código. Se puede encontrar información más detallada en este consejo relevante de 05AB1E , pero para este desafío quería hacer lo siguiente:

El lienzo incorporado toma tres parámetros:

  • un[2,2,3,3,4,4,5,5,...]
  • si
  • C[2,0 0,6 6,4 4][,,,]nortecarpet[0 0,6 6,4 4,2]0123456789ABCDEFGHI[6 6,4 4,2,0 0] en lugar).

En cuanto al código:

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)

Ver este consejo 05AB1E mío (sección Cómo comprimir grandes números enteros? ) Para entender por qué Ž8Oes 2064.

Kevin Cruijssen
fuente
0

Python 3 , 112 bytes

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

En este caso, la salida es el valor de la función.

Pruébalo en línea!

Si lo prefiere, aquí hay otra solución (más larga, 129 bytes ) que imprime directamente la entrada enrollada:

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

Pruébalo en línea!

PieCot
fuente
1
necesita imprimirlo
solo ASCII
@ Solo ASCII: Citando al autor de la pregunta: "Si regresar en lugar de imprimir muestra una gran mejora o un buen truco, publique una respuesta (y explique que está regresando, no imprimiendo)" . Entonces creo que está bien.
PieCot
0

MATLAB / Octave , 154 bytes

No es el más corto, pero jugar al golf en MATLAB / Octave siempre es divertido :)

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

Pruébalo en línea!

PieCot
fuente
1
lamentablemente, op dice que tiene que imprimir
solo ASCII
@ Solo ASCII como se explica aquí ( it.mathworks.com/matlabcentral/answers/… ), stdout en el mundo de Matlab se refiere a la ventana de comandos. Dado que el resultado de la evaluación de cada comando se imprime automáticamente en la ventana de comandos, creo que esta respuesta podría considerarse coherente con los requisitos de la pregunta.
PieCot
podría querer aclarar eso entonces
solo ASCII
@ Solo ASCII No entiendo a qué te refieres, de verdad. Es una función, la llamas, el resultado se imprimirá automáticamente en la ventana de comandos (es decir, stdout). ¿Qué tiene de malo esto? Incluso la respuesta R funciona así ...
PieCot
1
Ahora mismo disp, yo diría que debe retirar el dispdejar que la gente que no saben R que hace escribir en STDOUT por defecto
ASCII de sólo