Diamondize Some Text

20

Dada una cadena de entrada de longitud 2o más larga que consta únicamente de caracteres alfabéticos [A-Z]o [a-z](su elección si son todas mayúsculas o minúsculas), genera una cadena continua de caracteres que forman un patrón de doble diamante.

La cadena de entrada comienza en la línea central y se extiende hacia abajo y hacia la derecha en diagonal hasta llegar al final de la cadena de entrada. Luego, el patrón continúa hacia arriba y hacia la derecha en diagonal hasta que esté tan por encima de la línea central como la longitud de la cadena de entrada menos 1. Continúe hacia abajo y hacia la derecha hacia la línea central, luego hacia abajo y hacia abajo. izquierda, luego hacia arriba y hacia la izquierda (yendo "detrás" del personaje central) y finalmente hacia abajo y hacia la izquierda de regreso al personaje inicial.

Eso es un poco prolijo, y se demuestra mejor con algunos ejemplos:

"YOU"
  U   Y
 Y O U O
Y   O   U
 O Y U Y
  U   O

  ^   ^
 ↙ ↖ ↗ ↘
↘   ↗   >
 ↘ ↗ ↖ ↙
  V   V

Vea cómo YOUcomienza en la línea central y sigue hacia abajo y hacia la derecha, luego hacia arriba y hacia la derecha, etc., hasta que regrese al principio. Observe especialmente cómo la Yparte superior e izquierda está "detrás" Oy, por lo tanto, no se muestra.

Algunos ejemplos adicionales:

"HI"
 I I
H H H
 I I

"TEST"
   E     E
  S T   T S
 T   T T   T
T     S     T
 E   E E   E
  S T   T S
   T     T

"HELLO"
    L       L
   O L     E L
  H   E   H   O
 E     H O     H
H       L       E
 E     L L     L
  L   E   L   L
   L H     E O
    O       H

  • La entrada y salida se pueden dar por cualquier método conveniente .
  • Se garantiza que la entrada tendrá al menos dos letras de largo (es decir, nunca recibirá ""como entrada).
  • Puede imprimirlo en STDOUT o devolverlo como resultado de una función.
  • Un programa completo o una función son aceptables.
  • Cualquier cantidad de espacio en blanco extraño es aceptable, siempre y cuando los caracteres se alineen apropiadamente (por ejemplo, siéntase libre de rellenar como un rectángulo).
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente
No estoy seguro de que realmente importe, pero ¿por qué el segundo pase (arriba a la izquierda) va detrás del primer pase (arriba a la derecha)? Tiene menos sentido intuitivo y también un poco molesto ya sea saltear o volver a dibujar esa letra.
BradC
2
@BradC Estaba jugando con una tira de Möbius en mi escritorio cuando se me ocurrió el desafío, y la tira va un poco "atrás", por eso. No hay otro motivo.
AdmBorkBork
Puede ser una idea incluir un "dibujo" de la ruta utilizando flechas para ayudarnos a visualizarlo.
Shaggy
@Shaggy Agregó un dibujo.
AdmBorkBork
Bonito, este es más desafiante que la primera mirada ...
booshlinux

Respuestas:

10

Carbón , 17 bytes

GH<↗↘>↖↙LθθGH<Lθθ

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

GH

Dibuja a lo largo de un camino.

<↗↘>↖↙

Dibuja en las direcciones ↘↗↗↘↙↖↖↙ ( <y >son shorthands para esos dos pares, pero los otros pares no tienen shorthands).

Lθ

Cada segmento de ruta tiene la misma longitud, incluidos los extremos, de la longitud de la entrada.

θ

Use la entrada como el texto que se escribirá a lo largo de la ruta.

GH<Lθθ

Imprima las dos primeras partes de la ruta nuevamente para que el carácter del medio sea correcto.

Neil
fuente
3
Este desafío parece hecho a medida para el carbón de leña
Jonás
@ Jonás Lamentablemente, el comando de ruta de texto no dibuja el último carácter si la ruta está cerrada, por lo que no puede usar el truco de dibujo inverso aquí. (Aunque si lo hiciera, sería el mismo recuento de bytes de todos modos, ya que rotar la cadena cuesta 6 bytes.)
Neil
9

05AB1E , 12 bytes

gIR7._•Íη•Λ

Pruébalo en línea!

           Λ    use the canvas function
g               with the length of input for each segment
 IR7._          the input reversed and rotated left by 7 characters (we will draw this backwards to have the right center character)
      •Íη•     and the directions 1, 3, 3, 1, 7, 5, 5, 7 as a compressed number. 
dorio
fuente
Quiso decir 1, 3, 3, 1, 7, 5, 5, 7?
Neil
Oh tienes razon Mezclé un poco los números
Dorian
6

JavaScript (ES6),  157155154  bytes

Devuelve una matriz de caracteres.

s=>(y=n=s.length,y+=i=X=Y=-1,m=[...Array(y+n)].map(_=>r=Array(4*n-3).fill` `),g=x=>x?g(x-=r[m[y][++i==6*n-6||+x]=s[i%n],y-=m[y-Y]?Y:Y=-Y,x-X]?X:X=-X):m)``

Pruébalo en línea!

¿Cómo?

nortew×h

  • w=4 4norte-3
  • h=2norte-1

(0 0,norte-1)

El índice basado en 0 del carácter central que se debe omitir en la forma de diamante es:

pag=6 6norte-6 6

norte=4 4

ingrese la descripción de la imagen aquí

Comentado

s => (                           // s = input string
  y = n = s.length,              // n = length of s
  y += i = X = Y = -1,           // y = n - 1; i = X = Y = -1
  m =                            // create a matrix m[]:
    [...Array(y + n)].map(_ =>   //   - of height 2n-1
      r = Array(4 * n - 3)       //   - of width 4n-3 (save one of these rows in r[])
          .fill` `               //   - initially filled with spaces
    ),                           //
    g = x =>                     // g is a recursive function taking x
      x ?                        //   if x is truthy:
        g(                       //     do a recursive call:
          x -= r[                //       update x:
            m[y][                //         update m[y][x]:
              ++i == 6 * n - 6   //           unless this is the 2nd pass through the
              || +x              //           center cell, set it to the next character
            ] = s[i % n],        //           in s (otherwise we write to m[y][true]
                                 //           instead, which has no effect)
            y -=                 //         update y:
              m[y - Y] ? Y       //           bounce vertically if m[y - Y] is undefined
                       : Y = -Y, //
            x - X                //         bounce horizontally
          ] ? X                  //         if r[x - X] is undefined
            : X = -X             //
        )                        //     end of recursive call
      :                          //   else:
        m                        //     stop recursion and return m[]
)``                              // initial call to g with x = [''] (zero-ish but truthy)
Arnauld
fuente
Tengo una solución de 136 bytes inspirada en su solución, aunque creo que a estas alturas podría ser lo suficientemente diferente como para calificar como una respuesta separada.
Neil
@Neil Probablemente deberías publicarlo como una nueva respuesta.
Arnauld
3

JavaScript (ES6), 136 bytes

f=
(s,l=s.length-1,z=l*4,a=[...Array(l-~l)].map(_=>Array(z+1).fill` `),g=x=>x--?g(x,a[a[y=(x+l)%z]?y:z-y][x>z?z+z-x:x]=s[x%-~l]):a)=>g(z+z)
<input oninput=o.textContent=f(this.value).map(c=&gt;c.join``).join`\n`><pre id=o>

Devuelve una matriz bidimensional. Funciona dibujando la cadena en la matriz que calcula directamente las coordenadas de destino trabajando hacia atrás desde el final para que la celda central se sobrescriba automáticamente. Explicación:

(s

Cadena de entrada

,l=s.length-1

Distancia entre "rebotes", también la mitad del índice de la última fila y uno menos que la longitud.

,z=l*4

Índice de la última columna, también la mitad de la longitud del texto a dibujar.

,a=[...Array(l-~l)].map(_=>Array(z+1).fill` `)

Matriz de espacios.

,g=x=>x--

Cuenta atrás desde la última celda hasta la primera.

  ?g(x

Llamada recursiva para procesar las celdas restantes.

    ,a[a[y=(x+l)%z]?y:z-y]

Calcule la fila de esta celda.

      [x>z?z+z-x:x]=s[x%-~l])

Calcule la columna de esta celda y el carácter que pertenece allí.

  :a

Termine devolviendo la matriz.

)=>g(z+z)

Comience al final del texto.

Neil
fuente
Esa es buena, +1
Ver Nick dice Reinstate a Monica el
1

C (sonido metálico) , 201 196 188 bytes

x,y,i,v,m,n;f(s,z){char*a=s,o[i=(y=z*2-1)*(x=y+y)];for(v=x*2-2;i;n=m=1)o[--i]=i%x?32:10;for(i=x*--z;v--;i+=x*m+n)o[i]==32?o[i]=*a:0,a=*++a?a:s,n=i%x>x-3?-1:n,m=i/x?i/x<y-1?m:-1:1;puts(o);}

Pruébalo en línea!

-13 sugerencias @ceilingcat

AZTECCO
fuente
0

Python 2 , 137 bytes

s=input();n=len(s);m=2*n-2
for r in range(m+1):print''.join([s[[x,-8-x][(x<=m)==(m>2*r)]%n],' '][r!=(x+1-n)%m!=m-r]for x in range(4*n-3))

Pruébalo en línea!

Un programa completo que toma una cadena como entrada e imprime la versión diamantada.

Chas Brown
fuente