Feliz cumpleaños v!


72

¡Gracias a @KritixiLithos por ayudarme con este desafío!


V es un lenguaje de programación que escribí para poder usar y extender vim para desafíos de código de golf. ¡El primer compromiso fue el 3 de marzo de 2016, lo que significa que hoy V cumple un año! Woo-hoo

Durante el primer año de existencia de V, hubo 176 confirmaciones de cuatro colaboradores diferentes, 140 respuestas de 12 usuarios diferentes y demasiados operadores duplicados rotos para contar . Tiene un intérprete en línea , generosamente alojado por @Dennis, que se ha ejecutado casi 8,000 veces desde diciembre .

¡Tengamos un desafío para celebrar el cumpleaños de V! Dado que la mayoría de las funciones en V están diseñadas con la manipulación de cuerdas y en mente, parece natural que cualquier desafío que celebre V se deba al arte ascii. Por lo tanto, su desafío para hoy es tomar una palabra como entrada y remodelar esa palabra en forma de V. Por ejemplo, la entrada "Hola" debería dar la siguiente V:

Hello         olleH
 Hello       olleH
  Hello     olleH
   Hello   olleH
    Hello olleH
     HellolleH
      HellleH
       HeleH
        HeH
         H

Aquí hay algunos detalles sobre cómo debería verse su V. Si la cadena de entrada tiene una longitud de n caracteres, la V debe tener n*2líneas altas. La primera línea debe consistir en:

<input string><(n*2) - 1 spaces><input string reversed>

En cada nueva línea, se agrega un espacio al principio, y los dos lados de la cadena se mueven uno hacia el otro, eliminando los caracteres superpuestos. Hasta la última línea, que es solo el primer carácter de entrada. El espacio en blanco al final de cada línea es aceptable, y también se permite una nueva línea al final.

Puede suponer que la entrada siempre será ASCII imprimible sin ningún espacio en blanco, y puede tomar la entrada y la salida en cualquier método razonable. Aquí hay algunas entradas de muestra más:

Happy:

Happy         yppaH
 Happy       yppaH
  Happy     yppaH
   Happy   yppaH
    Happy yppaH
     HappyppaH
      HapppaH
       HapaH
        HaH
         H

Birthday:

Birthday               yadhtriB
 Birthday             yadhtriB
  Birthday           yadhtriB
   Birthday         yadhtriB
    Birthday       yadhtriB
     Birthday     yadhtriB
      Birthday   yadhtriB
       Birthday yadhtriB
        BirthdayadhtriB
         BirthdadhtriB
          BirthdhtriB
           BirthtriB
            BirtriB
             BiriB
              BiB
               B

V!:

V!   !V
 V! !V
  V!V
   V

~:

~ ~
 ~

Por supuesto, dado que esto es , las lagunas estándar están prohibidas y su objetivo es escribir el programa más corto posible para completar esta tarea. ¡Feliz golf!


Por lo que vale, tengo un punto débil para las respuestas de vim, así que puntos de bonificación imaginarios por usar vim o V, aunque cualquier lenguaje es aceptable. :)


¿Puedo imprimir un solo carácter nulo (0x00) después de cada nueva línea?
Wheat Wizard

@wheatwizard Hmm. Es un poco extraño, pero supongo que está bien siempre que la salida sea visualmente igual.
DJMcMayhem

21
¡El quinto cumpleaños será otra cosa! (En números romanos)
Albert Renshaw

55
Mis mejores deseos para el lenguaje V por el Vee :-)
The Vee

Respuestas:


44

MATL , 21 14 bytes

¡MATL le desea a V un feliz cumpleaños!

tnEXyY+c3MZvZ)

Pruébalo en línea!

Explicación

Considere la entrada

'Hello'

de longitud n=5. El código calcula la convolución 2D de esta cadena con la matriz de identidad de tamaño 2*n,

[1 0 0 0 0 0 0 0 0 0;
 0 1 0 0 0 0 0 0 0 0;
 0 0 1 0 0 0 0 0 0 0;
 0 0 0 1 0 0 0 0 0 0;
 0 0 0 0 1 0 0 0 0 0;
 0 0 0 0 0 1 0 0 0 0;
 0 0 0 0 0 0 1 0 0 0;
 0 0 0 0 0 0 0 1 0 0;
 0 0 0 0 0 0 0 0 1 0;
 0 0 0 0 0 0 0 0 0 1]

El resultado de la convolución, convertida a char y con char 0 mostrado como espacio, es

['Hello         ';
 ' Hello        ';
 '  Hello       ';
 '   Hello      ';
 '    Hello     ';
 '     Hello    ';
 '      Hello   ';
 '       Hello  ';
 '        Hello ';
 '         Hello']

Luego, las columnas [1, 2, ..., 2*n-1, 2*n, 2*n-1, ..., 2, 1]se seleccionan de esta matriz de caracteres, produciendo el resultado deseado:

['Hello         olleH';
 ' Hello       olleH ';
 '  Hello     olleH  ';
 '   Hello   olleH   ';
 '    Hello olleH    ';
 '     HellolleH     ';
 '      HellleH      ';
 '       HeleH       ';
 '        HeH        ';
 '         H         ']

Código comentado

t      % Implicitly input string. Duplicate
nE     % Length, say n. Multiply by 2
Xy     % Identity matrix of that size
Y+     % 2D convolution. This converts chars to ASCII codes
c      % Convert to char
3M     % Push 2*n, again
Zv     % Push symmetric range [1, 2, ..., 2*n, 2*n-1, ..., 1]
Z)     % Apply as column indices. This reflects the first 2*n columns
       % symmetrically, and removes the rest. Implicitly display

Enfoque muy interesante! +1
seshoumara

3
@seshoumara ¡Gracias! Como dice flawr, la convolución es la clave del éxito :-)
Luis Mendo

38

V , 24, 23 , 20 bytes

3Ù2Ò Íî
Xæ$òâÙHãêxx>

Pruébalo en línea!

Mucho más corto ahora que V tiene un operador 'inverso' .

No es tan impresionante en comparación con los otros idiomas de golf que han respondido, pero tenía que hacerse. Hexdump:

00000000: 33d9 32d2 20cd ee0a 58e6 24f2 e2d9 48e3  3.2. ...X.$...H.
00000010: ea78 783e                                .xx>

Explicación:

3Ù                  " Make three extra copies of this current line
  2Ò                " Replace each character on this line and the next line with spaces
     Íî             " Join all lines together
X                   " Delete one space
 æ$                 " Reverse the word under the cursor

En este punto, el búfer se ve así:

Happy         yppaH

No, construiremos recursivamente el triángulo hacia abajo.

ò                   " Recursively:
 â                  "   Break if there is only one non-whitespace character on this line
  Ù                 "   Make a copy of this line
   H                "   Move to the first line
    ã               "   Move to the center of this line
     ê              "   Move to this column on the last line
      xx            "   Delete two characters
        >           "   Indent this line

Aquí es donde puedo mostrar una de mis características favoritas de V. Muchos comandos requieren una discusión. Por ejemplo, el >comando sangrará un número variable de líneas dependiendo del argumento:

>>    " Indent this line (this command is actually a synonym for '>_')
>j    " Indent this line and the line below
>k    " Indent this line and the line above
6>>   " Indent 6 lines
>}    " Indent to the end of this paragraph
>G    " Indent to the last line
...   " Many many many more

pero la mayoría de los comandos se verán obligados a finalizar con un argumento predeterminado (generalmente la línea actual) si se encuentra al final del programa y no se especifica. Por ejemplo, lo que V realmente ejecuta para nuestro bucle recursivo es:

òâÙHãêxx>>ò

El segundo òse rellena implícitamente. Lo bueno es que los comandos terminados implícitamente aplican varias capas de profundidad, por lo que aunque solo escribimos >, V dará implícitamente _su argumento y sangrará la línea actual.


Estaba trabajando en ello, ¡pero creo que es más apropiado que respondas!
nmjcman101

29

Brainfuck , 152 bytes

Esta es una ocasión tan trascendental que decidí descifrar el viejo intérprete BF y darle un giro a esto.

++++++++++[->+>+++<<]>>++>>+>>>,[[<]<<+>>>[>],]<[<]<<-[->+>>[>]>++++[-<++++++++>]<[<]<<]>[->++<]>[-<+>]<[<[-<+<.>>]<[->+<]>+>->>[.>]<[-]<[.<]<<<<<.>>>>]

Con comentarios

++++++++++
[->+>+++<<] Insert 0 into the first buffer (Which we don't care about) 10 into the second and 30 into the thrd
>>++    Raise the third buffer to 32 making us our space
>   This buffer is reserved for the Insertable spaces counter
>
+>>>    Raise our incrementer This will be used to fill the other half of the string with spaces
,[  Read a byte
    [<]<<   Move to the back of the string buffer which is our incrementer
    +       increment it
    >>>[>]      And move to the next space of the string
    ,       And then read a new byte
]
<[<]<<-     Decrement the incrementer and begin to add spaces
[
    -       Decrement the incrementer
    >+      Raise the incrementer in the padding
    >>[>]   Move to a new part of the string buffer
    >++++[-<++++++++>]< Write a space
    [<]<<   Move all the way back to the string counter
]
BEGIN WRITING!!
>
[->++<]>[-<+>]<Double the incrementer
[
    <[  Move to the space counter
        -<+<.>> Decrement the space counter increment the temporary one to the left of it then print the space we stored to the left of that then return
    ]<[->+<]>+> Move the temporary space counter back
    -   Decrement the incrementer
    >>[.>]  Print every character from left to right
    <[-]    Snip the end off this
    <[.<]   Print every character from right to left
    <   Move back ot the incrementer
    <<<<.>>>> Print a newline aswell
]

Pruébalo en línea!


23

> <> , 221 bytes

Pasé manera demasiado tiempo en esto. Feliz cumpleaños V!

l:2*01           p84*/v
 !@:$-1         /!?:$<
  1.v/ ^       v\~~>a
   vv\}o<     >ao  /
    1\/84/   :}o:$-
     \\!?<: l;!?\v
      p10-1:g10r\
       >  :>?\vv
        v:$-1/~
         </r+*
          </~
           l

Puede probarlo en línea , pero es mucho más divertido obtener este intérprete y ejecutarlo con la --playbandera

python3 fish.py v.fish -s "ppcg" --tick 0.05 --play

que da como resultado la animación a continuación.

Ejemplo

Ejemplo de corrida de peces

(tarda un poco menos de dos minutos)

Explicación

Debido a que la parte interesante de esta respuesta es envolverla en la Vforma, aquí hay una explicación que se ajusta a ella. Utilizamos la siguiente versión numerada para referencia.

1. l:2*01           p84*/v
2.  !@:$-1         /!?:$<
3.   1.v/ ^       v\~~>a
4.    vv\}o<     >ao  /
5.     1\/84/   :}o:$-
6.      \\!?<: l;!?\v
7.       p10-1:g10r\
8.        >  :>?\vv
9.         v:$-1/~
10.         </r+*
11.          </~
12.           l

A veces, las flechas (→ ↓ ←) se utilizan para indicar la dirección en la que se alcanza un fragmento.

  1. Inicialización

       1.→l:2*01           p84*/v
       2.  !@:$-1   X     /!?:$<
       3.   1.            \~~>a
    

    La primera línea empujará 2n a [0,1], dejará n en la pila y agregará un espacio. Luego, subimos y giramos hacia la segunda línea a la derecha, donde comenzaremos a ir a la izquierda. Hay un bucle para agregar n + 1 espacios. Esto funciona de la siguiente manera.

                    Initial:                 "ppcg4 "
    !@:$-1 /!?:$<
               $     Swap.                   "ppcg 4"
              :      Duplicate.              "ppcg 44"
             ?       If more spaces to add:
        -1            Subtract 1.            "ppcg 3"
       $              Swap.                  "ppcg3 "
      :               Duplicate.             "ppcg3  "
     @                Rotate top 3.          "ppcg 3 "
    !                 Jump over stored value
                             and wrap around.
                    Else:
            /         Go to next part.
    

    Una vez finalizado esto, rebota hacia la línea 3. Allí se eliminan los dos elementos superiores de la pila (0 y un espacio) ( ~~) y saltamos a la Xubicación en [10,1] ( a1.), continuando hacia la derecha. Nos encontramos en la /línea 7 y comenzamos el ciclo principal del programa.

  2. Bucle principal ( 2n veces lo hacen)

     6.              ;!?\
     7.       p10-1:g10r\   ←
    

    Esta es la condición del bucle. Al principio, la pila se invierte para imprimir. Luego obtenemos el contador de [1,0] ( 01g) y almacenamos una versión decrementada ( :1-01p). Al dar vueltas y saltos hacia arriba y hacia la derecha, encontramos el condicional para terminar el programa. Si no terminamos, saltamos al primer ciclo de impresión.

    • Primer bucle de impresión (mitad izquierda)

      5.    1\   /   :}o:$-
      6.     \\!?<: l         ←
      

      Comenzamos con la longitud en la parte superior de la pila y ejecutamos el siguiente código siempre que el elemento superior no sea 0.

      1-$:o}
      
      1-        Subtract 1.    "ppcg3"
        $       Swap.          "ppc3g"
         :      Duplicate.     "ppc3gg"
          o     Output.        "ppc3g"
           }    Rotate right.  "gppc3"
      

      Esto imprimirá la pila sin descartarla. Si el ciclo termina, saltamos a la derecha en la línea 5, preparándonos para el próximo ciclo de impresión.

    • Preparación de la mitad derecha

      5.  →    /84/   
      6.       \     
      7.            :    
      8.            >
      9.         v:$-1/~
      10.         </r+*
      11.          </~
      12.           l
      

      Esta fue una de las partes más difíciles de colocar. A continuación se muestra una versión despojada de todas las direcciones para indicar lo que sucede.

                   Initial stack:   "    gcpp0"
      84*+r~
      84*          Push 32 == " ".  "    gcpp0 "
         +         Add 32 and 0.    "    gcpp "
          r        Reverse.         " gcpp    "
           ~       Remove top.      " gcpp   "
      

      Luego empujamos la longitud de lo que se va a imprimir y comenzamos el segundo ciclo de impresión (con un duplicado inicial que no forma parte del ciclo).

    • Segundo bucle de impresión (mitad derecha)

      3.     / ^ 
      4.     \}o<
      5.    
      6.           ↓   
      7.           
      8.       >  :>?\vv
      9.        v:$-1/~ 
      

      El código que se ejecuta es completamente el mismo que en el primer bucle de impresión, y o}se coloca un poco más lejos porque había ubicaciones disponibles. Al finalizar, nos quedan algunas cosas por hacer antes de que podamos verificar el bucle principal invariante nuevamente. Después ~de que se ejecuta la línea 9, nos ajustamos verticalmente, terminando en el siguiente fragmento de código.

                      ↓
      2.          X     / 
      3.  1.v/             >a
      4.              >ao  /
      

      Primero aoimprimirá una nueva línea. Luego rebotamos y llegamos exactamente al mismo lugar después de la inicialización, es decir, saltando al X.


probablemente debería hacer que la versión de golf sea la versión principal
Destructible Lemon

1
@DestructibleWatermelon, la publicación trata más sobre la versión V, ya que fue mucho más difícil moldear todo en una forma específica con solo un número limitado de bytes disponibles. Por lo tanto, la explicación seguirá para la versión V, en lugar de la versión simple. Podría hacer uno realmente golfizado más tarde.
PidgeyUsedGust

Esto es oro solo oro
Christopher

Aprecio que esta respuesta esté en un idioma cuyo nombre consiste exclusivamente en 'V' rotadas.
Sellyme

19

Brain-Flak , 486 + 1 = 489 bytes

¡Feliz cumpleaños V de Brain-Flak!

También un agradecimiento a 0 ' que proporcionó parte del código utilizado en esta respuesta

+1 debido a la -cbandera que se requiere para la entrada y salida de ASCII

((([]<{({}<>)<>}<>([]){({}[()]<(([][()])<{({}[()]<({}<>)<>>)}{}><>)<>({}<<>{({}[()]<({}<>)<>>)}{}><>)(({})<>)<>>)}{}([][][()]){({}[()]<((((()()()()){}){}){})>)}{}<>{({}<>)<>}<>>){}[()])<{((({})<((({}){}())){({}[()]<(({}<(({})<>)<>>)<(({}<({}<>)<>>[()])<<>({}<<>{({}[()]<({}<>)<>>)}{}>)<>>){({}[()]<({}<>)<>>)}{}<>>)>)}{}{}((()()()()()){})(<()>)<>>)<{({}[()]<({}<>)<>>)}{}{}{}{({}<>)<>}<>>[()])}{}>()())([][()]){{}(({}[()])<{({}[()]<((((()()()()){}){}){})>)}{}{({}<>)<>}{}>)([][()])}{}<>

Pruébalo en línea!

Esta es sin duda la cosa más difícil que he hecho en Brain-Flak.

Brain-Flak es notoriamente terrible para duplicar y revertir cadenas y este desafío consiste en nada más que duplicar y revertir cadenas.

Logré obtener este fragmento casi funcional en menos de una hora de trabajo duro, pero agregar en los últimos espacios resultó ser una de las cosas más difíciles que he hecho en Brain-Flak.

Explicación

La idea básica es que primero crearemos la parte superior de la V y cada iteración eliminará dos caracteres del medio y agregará un espacio al comienzo.

En la práctica esto se vuelve bastante difícil.

Existen algoritmos existentes para copiar y revertir, así que utilicé uno de esos para crear una copia reversa del código en la pila. Una vez que lo he hecho, pongo 2n-1espacios en la parte superior de la pila original y muevo la pila de nuevo sobre la pila para crear un emparedado.

Prueba 1

Ahora tenemos nuestra fila superior. Ahora queremos eliminar dos caracteres desde el principio y agregar un espacio al frente. Esto resulta ser la parte más difícil. La razón de esto es que necesitamos almacenar esencialmente dos valores, uno para la profundidad del fragmento actual y otro para la profundidad al centro de la V donde tiene que ocurrir la eliminación.

Esto es duro.

Debido a toda la duplicación y reversión que está ocurriendo, ambas pilas están en uso todo el tiempo. Realmente no hay ningún lugar en estas pilas para poner algo. Incluso con todo el Third Stack Magic en el mundo, no puede obtener el tipo de acceso que necesita para resolver este problema.

? Entonces, como lo arreglamos? En resumen, no lo hacemos realmente; ignoramos los espacios por el momento y los aplicamos más tarde, agregaremos ceros al código para marcar dónde están destinados los espacios, pero aparte de eso, realmente no haremos nada.

Entonces, en cada iteración, hacemos una copia de la última iteración y la colocamos en la pila. Usamos la profundidad que almacenamos para dividir esto por la mitad, de modo que tengamos la mitad izquierda de la V en la pila derecha y la mitad derecha de la V en la pila izquierda. Eliminamos dos elementos y los remendamos. Agregamos una nueva línea como medida y comenzamos la siguiente iteración. Cada vez que la profundidad hasta el centro de la V disminuye en uno y cuando llega a cero, detenemos el bucle.

Ahora tenemos la mayor parte de la V construida. Sin embargo, nos faltan espacios adecuados y nuestra V está actualmente un poco (léase: completamente) al revés.

Prueba 2

Entonces lo volteamos. Para voltearlo sobre la otra pila, tenemos que mover cada elemento uno por uno. A medida que movemos elementos, verificamos los ceros. Si nos encontramos con uno, tenemos que volver a colocar los espacios donde pertenecen. Tiramos el cero y agregamos un montón de espacios. ¿Cómo sabemos cuántos? Hacemos un seguimiento; voltear una pila a diferencia de duplicar o invertir una es una tarea muy poco intensiva, por lo que en realidad tenemos la memoria para almacenar y acceder a un contador adicional para realizar un seguimiento de cuántos espacios agregar. Cada vez que agregamos algunos espacios, disminuimos el contador en uno. El contador debe llegar a cero en la última línea nueva (la parte superior de la V) y, por lo tanto, estamos listos para imprimir.

Por último, limpiamos algunas cosas que quedan y terminamos el programa para la salida implícita.

Prueba 3


¡Impresionante que hayas logrado que funcione! ¿Crees que podrías guardar bytes dejándolo invertido y agregando la -rbandera?
DJMcMayhem

@DJMcMayhem No lo creo. El proceso de reversión y la inserción de espacios ocurren al mismo tiempo, por lo que si agrego la -rbandera, necesitaría revertirla en otro momento. Se está haciendo tarde donde estoy, pero creo que trabajaré en tratar de jugar golf sustancialmente mañana. Si puedo solucionar el problema de espacios, definitivamente usaré la -rbandera.
Wheat Wizard

16

Jalea , 15 12 bytes

⁶ṁ⁸;;\Uz⁶ŒBY

Pruébalo en línea!

Cómo funciona

⁶ṁ⁸;;\Uz⁶ŒBY  Main link. Argument: s (string)

⁶ṁ            Mold ' ' like s, creating a string of len(s) spaces.
  ⁸;          Prepend s to the spaces.
    ;\        Cumulative concatenation, generating all prefixes.
      U       Upend; reverse each prefix.
       z⁶     Zip/transpose, filling empty spots with spaces.
         ŒB   Bounce; map each string t to t[:-1]+t[::-1].
           Y  Join, separating by linefeeds.

Tiene 12 caracteres, pero ¿hay alguna codificación en la que salgan solo 12 bytes?
kasperd

1
Sí, Jelly usa su propia página de códigos personalizada .
Dennis


16

JavaScript (ES6), 108 106 98 94 bytes

f=
s=>s.repeat((j=l=s.length*4)*2).replace(/./g,_=>--j?s[j+j<l?j-i:l-i-j]||` `:(j=l,++i,`
`),i=1)
<input oninput=o.textContent=f(this.value)><pre id=o>


¿Serías capaz de hacer una publicación explicando esto? Estoy un poco confundido por el reemplazo y las expresiones regulares.
Jacob Persi

@JacobPersi Son un arenque rojo. Todo lo que necesito es un área de salida de tamaño n*2por n*4(incluidas las nuevas líneas al final de cada línea). Luego calculo el carácter que debería aparecer en cada celda.
Neil

¡Agradable! Puede eliminar un byte quitando la nueva línea entre f=y s=>.
yummypasta

@yummypasta El f=es solo una parte del fragmento, no la respuesta. Como tal, no está incluido en el recuento de bytes.
Neil

11

Retina , 51 47 bytes

¡Feliz cumpleaños de un compañero de lenguaje de procesamiento de cadenas!

El recuento de bytes asume la codificación ISO 8859-1.

$
$.`$* 
$
¶$`
O$^r`.\G

;{*`.¶

(\S.*).¶.
 $1¶

Pruébalo en línea!

Explicación

$
$.`$* 

Esto agrega nespacios (donde nestá la longitud de la cadena), haciendo coincidir el final de la cadena, recuperando la longitud de la cadena $.`y repitiendo un espacio que muchas veces con $*.

$
¶$`

Duplicamos toda la cadena (separada por un salto de línea), haciendo coincidir el final de la cadena nuevamente e insertando la cadena en sí $`.

O$^r`.\G

Esto invierte la segunda línea haciendo coincidir de derecha a izquierda ( r), luego haciendo coincidir un carácter a la vez ( .) pero asegurándose de que estén todos adyacentes ( \G). De esta manera, los partidos no pueden pasar el salto de línea. Esto luego se utiliza en una etapa de clasificación. Al usar el modo ordenar por ( $) pero reemplazar cada coincidencia con una cadena vacía, no se realiza una clasificación real. Pero debido a la ^opción, los partidos se invierten al final, invirtiendo toda la segunda línea.

;{*`.¶

Esta etapa es para la salida y también afecta al resto del programa. {envuelve las etapas restantes en un bucle que se repite hasta que esas etapas no cambien la cadena (lo que sucederá porque la última etapa ya no coincidirá). La ;salida deshabilita al final del programa. Las *vueltas esta etapa en un funcionamiento en seco lo que significa que la etapa se procesa y el resultado se imprime, pero después la cadena anterior se restaura.

El escenario en sí mismo simplemente elimina un salto de línea y el carácter anterior. Lo que nos da una línea de la salida deseada (comenzando con la primera línea).

(\S.*).¶.
 $1¶

Finalmente, esta etapa convierte cada línea en la siguiente. Esto se hace insertando un espacio delante del primer carácter no espacial, eliminando el último carácter en la primera línea, así como el primer carácter en la segunda línea. Este proceso se detiene una vez que solo queda un carácter sin espacio en la primera línea, que corresponde a la última línea de la salida.


Me encantaría una explicación de cómo funciona esto. Sé que la sintaxis de sed es menos compacta, pero mi borrador es dos veces más largo. Invertir la cadena y juntar la primera línea de salida es la mayor parte.
seshoumara

@seshoumara Claro, ahí lo tienes.
Martin Ender

Gracias. Ahora sé que un script sed de doble longitud no es malo :)) debido a s///caracteres adicionales que se suman, a una inversión de cadena más larga y otras operaciones que carecen de las sutilezas de Retina. Buena lectura. +1
seshoumara

9

05AB1E , 12 bytes

Dgð×J.p€ûR.c

Pruébalo en línea!

Explicación

D             # duplicate input
 g            # length of copy
  ð×J         # append that many spaces to input
     .p       # get a list of all prefixes
       €û     # turn each into a palindrome
         R    # reverse the list
          .c  # pad each line until centered

O para el mismo número de bytes desde la otra dirección.

Âsgú.sí€ûR.c

Explicación

             # push a reversed copy of input
 s            # swap the input to the top of the stack
  g           # get its length
   ú          # prepend that many spaces
    .s        # get a list of all suffixes
      í       # reverse each
       €û     # turn each into a palindrome
         R    # reverse the list
          .c  # pad each line until centered

2
Si sangra los comentarios de forma incremental, incluso la fuente parece una V :)
aross

9

Japt, 22 20 16 14 + 2 bytes

¡Japt desea a V muchos años más exitosos de golf!

²¬£²îU²ç iYU)ê

Requiere la -Rbandera. ¡Pruébelo en línea!

Explicación

Esto hace uso de las funciones çy îque agregué hace unos días:

²¬£²îU²ç iYU)ê    Implicit: U = input string
²                 Double the input string.
 ¬                Split into chars.
  £               Map each char X and index Y by this function:
     U²             Take the input doubled.
       ç            Fill this with spaces.
         iYU        Insert the input at index Y.
    î       )       Mask: repeat that string until it reaches the length of
   ²                the input doubled.
                    This grabs the first U.length * 2 chars of the string.
             ê      Bounce the result ("abc" -> "abcba").
                  Implicit: output result of last expression, joined by newlines (-R flag)

La técnica de Dennis es un byte más larga:

U+Uç)å+ mw y mê

5

GNU sed , 110100 + 1 (bandera r) = 101 bytes

Editar: 9 bytes más cortos gracias a Riley

Como otro lenguaje de manipulación de cadenas, sed le desea a V lo mejor.

h;G
:;s:\n.: \n:;t
h;:r;s:(.)(\n.*):\2\1:;tr
H;x
s:\n\n ::
:V
h;s:\n::p;g
s:^: :;s:.\n.:\n:
/\n$/!tV

Pruébalo en línea!

Explicación: suponiendo que la entrada es el último caso de prueba ('V!'). Mostraré el espacio del patrón en cada paso para mayor claridad, reemplazando los espacios con 'S'.

h;G                       # duplicate input to 2nd line: V!\nV!
:;s:\n.: \n:;t            # shift each char from 2nd line to 1st, as space: V!SS\n
h;:r;s:(.)(\n.*):\2\1:;tr # save pattern space, then loop to reverse it: \nSS!V
H;x                       # append reversed pattern to the one saved V!SS\n\n\nSS!V
s:\n\n ::                 # convert to format, use \n as side delimiter: V!SS\nS!V
:V                        # start loop 'V', that generates the remaining output
h;s:\n::p;g               # temporarily remove the side delimiter and print pattern
s:^: :;s:.\n.:\n:         # prepend space, delete char around both sides: SV!S\n!V
/\n$/!tV                  # repeat, till no char is left on the right side
                          # implicit printing of pattern left (last output line)

@Riley Respuesta actualizada, gracias!
seshoumara

4

Python, 110 bytes

Pruébalo en línea!

Estoy seguro de que esto no es óptimo, pero al menos es bastante pitónico:

def f(s):n=len(s)*2-1;return''.join(i*' '+s[:n+1-i]+(n-2*i)*' '+s[n-i-1::-1]+'\n'for i in range(n))+n*' '+s[0]

4

Jolf, 31 bytes

¡Jolf a regañadientes le desea a V un feliz cumpleaños!

RΜwzΒώlid+γ_pq_ l+*␅Hi0ΒΒ␅ L_γ1S

Pruébalo aquí! debe ser 0x05.

Explicación

RΜzΒώlid+γ_pq_ l+*␅Hi0ΒΒ␅ L_γ1S  i = input
     li                                  i.length
    ώ                                2 * 
   Β                             Β =
  z                              range(1, Β + 1)
 Μ     d                         map with: (S = index, from 0)
                +                 add:
                 *␅H               S spaces
                    i              and the input
               l                  slice (^) from
                     0Β            0 to Β
           pq_         Β␅         pad (^) with spaces to the right
         γ_                       γ = reverse (^)
        +                 L_γ1    γ + behead(γ)
R                             S  join with newlines

4

Carbón , 29 bytes

¡Feliz cumpleaños V, de tu compañero lenguaje de arte ASCII decepcionantemente largo para este desafío!

SσF…·¹Lσ«Fι§σκMι←↖»Fσ«Pσ↖»‖O→

Pruébalo en línea!

Explicación

Nuestra estrategia: imprimir la mitad izquierda de la V, comenzando desde abajo y moviéndose hacia la esquina superior izquierda; entonces reflexionarlo.

Sσ                                    Input σ as string
                                       The bottom len(σ) half-rows:
   F…·¹Lσ«           »               For ι in inclusive range from 1 to length(σ):
            Fι                          For κ in range(ι):
               §σκ                         Print character of σ at index κ
                  Mι←                   Move cursor ι spaces leftward
                      ↖                  Move cursor one space up and left
                                       The top len(σ) half-rows:
                        Fσ«    »      For each character ι in σ:
                            Pσ          Print σ without moving the cursor
                               ↖         Move cursor one space up and left
                                 ‖O→  Reflect the whole thing rightward, with overlap

(Si solo el carbón de leña tuviera un corte de cadena ... por desgracia, parece que aún no se ha implementado).


Aunque el carbón de leña no tenía un corte de cadena, sí lo tenía CycleChop, que se puede usar para extraer el encabezado de la cadena, ahorrando así 4 bytes. Sin embargo, hay un mejor enfoque que ahorra 9 bytes. Algunos ahorros más que creo que también funcionaron en ese momento: el valor Reflectpredeterminado es un reflejo a la derecha, guardando un byte adicional, y una de las variables está predefinida a la primera entrada, ahorrando dos bytes.
Neil

4

Pip , 32 25 bytes

a.:sX#aL#a{OaDQaPRVaaPUs}

Toma la cadena de entrada como un argumento de línea de comandos. Pruébalo en línea!

Explicación

                           a is 1st cmdline arg, s is space (implicit)
     #a                    Len(a)
   sX                      Space, string-multiplied by the above
a.:                        Concatenate that to the end of a
       L#a{             }  Loop len(a) times (but NB, a is now twice as long as it was):
           Oa                Output a (no trailing newline)
             DQa             Dequeue one character from the end of a
                PRVa         Print reverse(a) (with trailing newline)
                    aPUs     Push one space to the front of a

4

R con paquete stringi, 225 Bytes

library(stringi)
f=function(){
s=scan(,'',1,sep="\n")
m=2*nchar(s)
l=stri_pad(sapply(1:m-1,function(x)substr(paste(paste(rep(" ",x),collapse=""),s),1,m)),m,"right")
r=substr(stri_reverse(l),2,m)
message(paste0(l,r,"\n"))}
f()

Si ejecuta R en código interactivo, después de pegar mi respuesta simplemente ingrese cualquier cosa. Necesitará instalar el paquete stringi R (espero que no esté en contra de las reglas).

Explicación:

La idea básica es agregar espacios al lado izquierdo, luego cortarlo a la longitud correcta. Después de eso, péguelo con su versión invertida como el lado derecho. Aquí hay una versión más larga y legible de la función:

library(stringi)
make_V <- function(){                  # declaring the function
  string <- scan(, '', n=1, sep="\n")  # reading input
  max_length <- 2*nchar(string)        # number of chars in each half row

  # creating the left side of the V

  left <- stri_pad(                    
            sapply(1:max_length-1,     # for each row
                   function(x){     
                    substr(            
                      paste0(
                        paste0(rep(" ", x),
                               collapse=""), string), # add spaces to left side
                           1,
                           max_length) # cut the unneeded end
                    }),
            width=max_length,
            side="right")              # add spaces to the right side

  # creating the right side of the V

  right <- substr(stri_reverse(left), 2, max_length)

  # print it without any symbols before the strings 
  message(paste0(left, right, "\n"))
}

# run the function
make_V()

Bienvenido al sitio! :)
DJMcMayhem

4

Ruby, 92 89 85 bytes

s=gets.chomp
s<<" "*n=s.size*2
n.times{s=s[0..(n-1)]
puts s+s.reverse[1..-1]
s=" "+s}

Mi proceso fue eliminar el primer carácter de la mitad derecha de cada línea después de invertir la primera mitad. Me gusta esto:

Hello     |    olleH
 Hello    |   olleH 
  Hello   |  olleH  
   Hello  | olleH   
    Hello |olleH    
     Hello|lleH     
      Hell|leH      
       Hel|eH       
        He|H        
         H|         

No estoy acostumbrado a jugar al golf, así que avíseme si hay algo que pueda hacer para acortarlo.


Bienvenido al sitio, esta es una buena respuesta! Desafortunadamente, realmente no sé mucho sobre Ruby, así que no puedo ofrecer ningún consejo. Sin embargo, es posible que pueda encontrar algo en esta página .
DJMcMayhem

¡Gracias! Hay muchas cosas interesantes en esa página, pero parece que ya estoy haciendo muchas de ellas. Sin embargo, me di cuenta de que podía guardar algunos bytes mediante efectos secundarios y el orden de las operaciones.
user3334690

1
Supongo que [Ruby] es solo Ruby, el lenguaje de programación de programas más o menos conocido.
Rɪᴋᴇʀ

Puede guardar 8 bytes haciendo de esto una lambda .
Jordania

4

Lote, 186 185 bytes

@set e=@set 
%e%/ps=
%e%t=%s%
%e%r=
:l
%e%s=%s% 
%e%r= %r%%t:~-1%
%e%t=%t:~,-1%
@if not "%t%"=="" goto l
:g
%e%r=%r:~1%
@echo %s%%r%
%e%s= %s:~,-1%
@if not "%r%"=="" goto g

Las líneas 1 y 6 tienen un espacio final. Editar: Guardado 1 byte gracias a @ ConorO'Brien.


1
Aquí hay una forma complicada de guardar un byte . (cree un alias para @set y elimine @echo off, insertando @según sea necesario.
Conor O'Brien

@ ConorO'Brien Gracias, nunca habría adivinado que 8 sets me habrían ahorrado suficientes bytes para que valiera la pena.
Neil

3

Haskell , 76 bytes

ves la función principal, tomar un Stringargumento y dar un Stringresultado.

v i=unlines.r$i++(' '<$i)
r""=[]
r s|t<-init s=(s++reverse t):map(' ':)(r t)

Pruébalo en línea!

Notas:

  • i es el argumento / entrada inicial.
  • ses inicialmente icon length iespacios anexados.
  • v illama r s, luego une las líneas de resultados.
  • rDevuelve una lista de Stringlíneas.
  • tes scon el último caracter cortado.
  • La recursión r tproduce las líneas excepto la primera, menos el espacio inicial en cada línea.

2
+1 para nombrar la función principal v. : D
DJMcMayhem

1
@DJMcMayhem: no nombrar la función principal es un byte más largo: unlines.r.((++)<*>(' '<$)).
nimi

1
@nimi Supongo que le gustó qué nombre elegí. Técnicamente, un vínculo lambda ... Cuando escribí la respuesta, no sabía que podía usar declaraciones de nivel superior para algunas funciones, pero no nombrar la función principal. Aunque vi a alguien más hacerlo, me resulta algo inquietante. En estos días funciona al menos en GHCi.
Ørjan Johansen

3

Jalea , 13 bytes

⁶ṁ;@µḣJUz⁶ŒBY

Pruébalo en línea!

¿Cómo?

⁶ṁ;@µḣJUz⁶ŒBY - Main link: string s
⁶             - space character
 ṁ            - mould like s: len(s) spaces
  ;@          - concatenate s with that
    µ         - monadic chain separation (call that t)
      J       - range(length(t))
     ḣ        - head (vectorises): list of prefixes from length to all
       U      - upend: reverse each of them
        z     - transpose with filler:
         ⁶    -     space: now a list of the left parts plus centre
          ŒB  - bounce each: reflect each one with only one copy of the rightmost character
            Y - join with line feeds
              - implicit print

Mentes iguales piensan muy bien. : P
Dennis

¡Oh, no pensé en una concatenación acumulativa! El carbón tiene una dirección V, tal vez algo de investigación por ahí ...
Jonathan Allan

3

Ruby, 85 83 bytes

editar: eliminó el exceso de espacio en blanco

s=ARGV[0];s+=' '*s.length;s.length.times{|i|puts s+s[i..-2].reverse;s=' '+s[0..-2]}

De hecho, me resultó bastante difícil jugar golf en Ruby. Después de agregar espacios en blanco, se expande a un fragmento de código bastante legible:

s = ARGV[0]
s+=' ' * s.length

s.length.times do |i|
  puts s + s[i..-2].reverse
  s = ' ' + s[0..-2]
end

1
Probablemente podría ahorrar un poco estableciendo s.length a una variable como lo hice yo Además, ¿creo que deberías considerar hacer el tamaño en lugar de la longitud?
user3334690

Haciendo lo que @ user3334690 sugirió y moviendo la declaración .times, 79 bytes:s=ARGV[0];(s+=' '*s.size).size.times{|i|puts s+s[i..-2].reverse;s=' '+s[0..-2]}
Conor O'Brien

Puede guardar cinco bytes haciendo de esto una lambda .
Jordania

3

MATLAB (R2016b), 223 183 bytes

r=input('');l=nnz(r)*2;for i=1:l;m=l+1-2*i;c={' '};s=cell(1,i-1);s(:)=c;x=cell(1,m);x(:)=c;e=r;y=flip(r);if(m<1);e=r(1:2*end-i+1);y=r(l/2+end-i:-1:1);end;disp(cell2mat([s e x y]));end

Código Golf por primera vez. ¡Las propinas son bienvenidas!

Salida del programa:

MATLAB Code Golf

Editar:

Guardado 40 bytes gracias a Luis Mendo.


2
¡Bienvenido a PPCG, y buena primera respuesta! Desafortunadamente, no sé nada sobre MATLAB, así que no puedo ayudarlo a jugar golf, pero tal vez encuentre útiles algunos de los consejos :-)
ETHproductions

1
La entrada de una cadena que incluye sus comillas adjuntas está permitida de manera predeterminada. Para que pueda eliminar 's'de input. Además, no veo por qué lo estás usando evalc(disp(...)), pero creo que puedes usarlo de cell2mat esta manera
Luis Mendo el

1
Además, flipes más corto que end:-1:1, mira aquí
Luis Mendo

3

PHP, 95 92 85 80 78 77 bytes

Nota: utiliza la codificación IBM-850

for($s.=strtr($s^$s=$argn,~ ,~▀);~$s[$i++];)echo$s,strrev($s=" $s"^$s^$s),~§;
          # Note that this ^ char is decimal 255 (negating it yields "\0")

Corre así:

echo "Hello" | php -nR 'for($s.=strtr($s^$s=$argn,"\0",~▀);~$s[$i++];)echo$s,strrev($s=" $s"^$s^$s),~§;'
> Hello         olleH 
>  Hello       olleH  
>   Hello     olleH   
>    Hello   olleH    
>     Hello olleH     
>      HellolleH      
>       HellleH       
>        HeleH        
>         HeH         
>          H          

Explicación

for(
  $s.=strtr(             # Set string to the input, padded with spaces.
    $s^$s=$argn,         # Input negated with itself, leads to string with
                         # only null bytes with the same length.
    ~ ,                  # Replace null bytes...
    ~▀                   # ... with spaces.
  );
  ~$s[$i++];             # Iterate over the string by chars, works because 
                         # there are just as many lines as the padded
                         # string has chars.
)
  echo                   # Output!
    $s,                  # The string.
    strrev(              # The reverse of the string.
      $s=" $s"^$s^$s     # After each iteration, prefix string with a
    ),                   # space, and trim the last character.
    ~§;                  # Newline.

Ajustes

  • Ahorré 3 bytes al deshacerme del carácter del pad (el str_padespacio predeterminado es el que necesitamos)
  • Guardado 7 bytes utilizando operaciones binarias en la cadena para truncarlo en lugar de substr
  • Ahorró 5 bytes girando la cadena al imprimir el reverso. Evita la necesidad de imprimir un retroceso, pero da como resultado un espacio final en cada línea.
  • Se guardaron 2 bytes rellenando una cadena usando un método más complicado pero más corto.
  • Se guardó un byte debido al hecho de que no es necesario tener en cuenta el ~"0"caso (ASCII 207), ya que se puede suponer que todas las entradas son ascii imprimibles (Thx @Titus)

echo$s,strrev($s=" $s"^$s^$s),~§;ahorra 5 bytes.
Titus

@Titus, gracias. Por lo general evito las espacios en blanco, pero OP dicho que es aceptable
aross

~$s[$i++]es suficiente (la entrada es ASCII imprimible, y también lo es $s)
Tito el

@Titus, gracias, buena captura.
Tiendo

2

Javascript (ES6), 169 157 bytes

(-10 bytes gracias a Conor O'Brien)

V=(j,i=0,p="")=>i<(f=j.length)*2?V(j,-~i,p+" ".repeat(i)+j.slice(0,f-i*(i>f))+" ".repeat(i<f?(f-i)*2-1:0)+[...j.slice(0,f+~i*(i>=f))].reverse().join``+`
`):p

Una solución recursiva. Soy nuevo en JavaScript, ¡así que sé gentil! Cualquier consejo de golf es muy apreciado. :)

Y, por supuesto, un muy feliz cumpleaños para ti V!

Fragmento de prueba


1
¡Esto es bastante bueno! Por lo general, s.split("")se puede cambiar a [...s], y a.join("")puede ser a.joinseguido por un par de backticks. Puede guardar 3 bytes adicionales reemplazando [r='repeat']y [r]con simple ol 'repeat, lo mismo con slice.
Conor O'Brien

@ ConorO'Brien Gracias por los consejos! Son muy apreciados :)
R. Kap

2

CJam , 26 bytes

Feliz cumpleaños de tu viejo amigo CJam!

q_,2*:L,\f{LS*+m>L<_W%(;N}

Pruébalo en línea!

Explicación

q                           Push the input
 _,2*:L                     Push 2 times the length of the input, store it in L
       ,                    Take the range from 0 to L-1
        \                   Swap top stack elements
         f{                 Map over the range, using the input as an extra parameter
           LS*+               Append L spaces to the input
               m>             Rotate the resulting string right i positions (where i is the
                               current number being mapped)
                 L<           Take the first L characters of the string
                   _W%        Duplicate it and reverse it
                      (;      Remove the first character from the copy
                        N     Add a newline
                         }  (end of block)
                            (implicit output)

2

PowerShell, 126 bytes 124 bytes

$l=($s="$args")|% Le*;$r=-join$s[-1..-$l];0..($l*2-1)|%{' '*$_+($s+' '*$l).substring(0,$l*2-$_)+(' '*$l+$r).substring($_+1)}

Llámelo con un solo parámetro, como .\V.ps1 Hello.

Editar: 2 bytes guardados con propina de AdmBorkBork


1
A Pruébelo en línea! enlace, en caso de que esté interesado.
Dennis

Oh, no sabía sobre esa pequeña herramienta, ¡gracias!
Tor

¡Hola! Un par de pequeños campos de golf en la parte delantera. Tome la entrada como una cadena y use la encapsulación para pasar la variable. Guarda dos bytes. $l=($s="$args")|% Le*;
AdmBorkBork

Wow, no sabía sobre esos 2 campos de golf, ¡gracias!
Tor


2

JavaScript (ES6), 94 bytes

f=(s,y=0,x=0,l=s.length*2-1)=>(s[(x>l?l*2-x:x)-y]||' ')+(x<l*2?f(s,y,x+1):y<l?`
`+f(s,y+1):'')

Casos de prueba


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.