Zigzag lentamente convergente

23

Dado un solo entero impar positivo como entrada, devuelve un zigzag convergente como una lista de cadenas, lista de listas de caracteres o cadena separada por nueva línea, de esta forma:

#
 #
  #
   #
    #
   #
  #
 #
  #
   #
  #

Puede reemplazar #con cualquier carácter coherente que no sea un espacio en blanco. Se permite el espacio en blanco al final de cada línea y se permite una nueva línea al final.

El zig-zag comienza en la columna 1y para cada fila se mueve hacia la derecha una columna, hasta llegar a la columna n(donde nestá la entrada). Luego, se mueve hacia la izquierda 2, luego hacia la derecha n-1, luego hacia la izquierda 3, con los dos límites convergiendo hasta que el zigzag termine en la columna central ( (n+1)/2).

Casos de prueba

El ejemplo anterior es el caso de prueba para 5.

Los siguientes son casos de prueba individuales:

3
#
 #
  #
 #

7
#
 #
  #
   #
    #
     #
      #
     #
    #
   #
  #
 #
  #
   #
    #
     #
    #
   #
  #
   #
    #
   #

1

#
Hiperneutrino
fuente
¿Se permite el espacio en blanco inicial (pero consistente, es decir, no rompe la forma)?
Erik the Outgolfer
@EriktheOutgolfer Voy a decir que no por eso.
HyperNeutrino

Respuestas:

15

C (gcc) , 89 bytes

f(n,a,b){puts("0");for(a=n;--a>n/2;)for(b=n-2*a;b<=2*a-n;)printf(" %*d\n",a-abs(b++),0);}

Pruébalo en línea!

Funciona analizando la secuencia de número de espacios como (para n = 7):

          0
1 2 3 4 5 6 5 4 3 2 1
    2 3 4 5 4 3 2
        3 4 3

Y para n = 3:

  0
1 2 1

Podemos ver que el número del medio ( aen el código) se ejecuta desde [n-1, n / 2). Entonces, la diferencia entre el primer número y el número del medio es:

a  n  b  2a-n
-------------
6  7  5  5
5  7  3  3
4  7  1  1
2  3  1  1

Entonces, si hemos bpasado por [- (2a-n), 2a-n], a-abs(b)nos dará la secuencia deseada. Esto es esencialmente lo que hace el código.

Pomo de la puerta
fuente
14

Carbón , 10 8 bytes

FN«↗ι‖»/

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 2 bytes gracias a @dzaima por señalar que no tengo que usar #s.

Neil
fuente
Finalmente, algo que supera a Jelly
JungHwan Min
3

Jalea , 14 bytes

ṖṖṚ$ÐĿẎ0;⁶ẋp1Y

Pruébalo en línea!

Programa completo

Usos 1.

-1 gracias a Jonathan Allan .
-1 gracias a Jonathan Allan .

Erik el Outgolfer
fuente
’R-> para un byte.
Jonathan Allan
@ JonathanAllan Ooh, por supuesto, gracias. Había tratado de evitarlo en una versión anterior y lo olvidé ...
Erik the Outgolfer
”X-> 1para otro.
Jonathan Allan
@JonathanAllan Heh otro pasar por alto aparentemente ... Traté de evitar los enteros también.
Erik the Outgolfer
3

Haskell , 72 bytes

g[]=[]
g a=a++g(reverse$init a)
r="#":map(' ':)r
("#":).g.tail.(`take`r)

Pruébalo en línea!

Definimos una lista infinita que res la diagonal de #s a partir de la esquina superior izquierda.

Luego definimos una función gque hace la mayor parte del trabajo. gtomará una lista y la invertirá repetidamente y eliminará su primer elemento hasta que la lista esté vacía, luego concatenará el resultado de cada acción.

Nuestra función principal aquí es una función sin puntos. Esta función comienza tomando nelementos de la lista infinita r, luego corta el primer elemento y aplica g. Por último, tenemos que agregar una #vuelta al principio, esto se debe a que las especificaciones de la pregunta son un poco raras, no estoy seguro de por qué la primera diagonal siempre es una más larga de lo que debería ser, pero lo es, así que tenemos que agregue aa #.

Asistente de trigo
fuente
@nimi Terminé haciendo ("#":).g.init.(take r)pero gracias!
Wheat Wizard
2

05AB1E , 6 bytes

LN71SΛ

Pruébalo en línea!

     Λ     use the canvas function with

L          a range list [1 .. input] as lengths for each path 

 N         a "0" as character to be printed 
           (N is the index variable used by loops. If there was no loop yet, its
           default value is 0. By using N, I avoid an extra space between 0 and 71)

  71S      and the directions 7 and 1 (NW and NE), that alternate automatically until
           the range list is finished.
dorio
fuente
No, lo intenté primero, pero dibuja ambas direcciones, antes de continuar con el siguiente elemento de la lista de rango, cuando elimino el S. Entonces el resultado será el doble de largo. Todavía no sabía sobre + y ×. Hacen patrones realmente interesantes cuando los combinas con números
Dorian
Ah, en verdad tienes razón. Mi error. Vi que funcionó sin el S, pero no presté suficiente atención a la salida ..>.> Y el +y ×son básicamente incorporados para [0,4,4,0,2,6,6,2]y [1,5,5,1,3,7,7,3]. Y 8se restablecerá al origen desde donde comenzó. Aquí un poco más de información.
Kevin Cruijssen
1

JavaScript, 127 bytes

Calcula el objetivo ( g) para llegar. Cuando se alcanza este objetivo, da la vuelta al siguiente objetivo. También usa un truco para evitar usar Math.round()agregando 0.5a cada número desigual.

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f(5);

Thomas W
fuente
1

Haskell, 74 bytes

f[x]=[x]
f s=s++tail(f$reverse$tail s)
g n=f[(' '<$[2..x])++"#"|x<-[1..n]]

Pruébalo en línea!

Cómo funciona:

    [(' '<$[2..x])++"#"|x<-[1..n]]     -- build the first diagonal, e.g. for n=3:
                                         -- ["#", " #", "  #"]
  f                                      -- call f, which is

f s = s ++                               -- the input list, followed by
           tail                          -- all but the first element of
                f                        -- a recursive call with
                  reverse                -- the reverse of
                          tail s         -- all but the first element of the input 
                                         -- list
f[x]=[x]                                 -- base case: stop if the input list a
                                         -- singleton list

Cada llamada recursiva fanexa la siguiente diagonal.

nimi
fuente
1

Casco , 19 bytes

mo`:'#R' ∫`Ṙ¢e1_1tṫ

Pruébalo en línea!

Explicación

Esto se siente un poco torpe.

mo`:'#R' ∫`Ṙ¢e1_1tṫ  Input is n (e.g. 5)
                  ṫ  Range from input to 1: [5,4,3,2,1]
                 t   Drop first element: [4,3,2,1]
             e1_1    The list [1,-1]
            ¢        repeated infinitely: [1,-1,1,-1,..
          `Ṙ         Clone with respect to the list above: [1,1,1,1,-1,-1,-1,1,1,-1]
         ∫           Cumulative sum: [0,1,2,3,4,3,2,1,2,3,2]
mo                   For each element k (e.g. 3) do this:
      R'             Repeat space k times: "   "
  `:'#               Append '#': "   #"
                     Print implicitly separated by linefeeds.
Zgarb
fuente
1

Retina , 71 bytes

.+
$* 
^
:>
 $
:
;{*T`:<>`_#
( ) >(:)|( )<
$1<$2$3
(:)( )<|>( )
$2$1$3>

Pruébalo en línea! Explicación: Las primeras tres etapas convierten la entrada en el formulario :> :donde el número de caracteres entre los :s es el número de entrada. Las últimas dos etapas luego rebotan >(o <, al moverse hacia la izquierda) entre :s. La cuarta etapa repite el rebote e imprime las partes requeridas de la cadena cada vez. El ;detiene la cadena de ser impresa después del bucle.

Neil
fuente
1

05AB1E , 16 bytes

Î<L¤F¦})˜Ôð×X«»

Pruébalo en línea!

Explicación

Î<L               # push 0 and range [1 ... input-1]
   ¤              # get the last element of the list
    F             # that many times do
     Â            # bifurcate
      ¦           # remove the head
       })˜        # end loop and wrap in flattened list
          Ô       # remove consecutive duplicates
           ð×     # repeat space a number of times corresponding to each number in the list
             X«   # append 1 to each
               »  # join on newline
Emigna
fuente
1

K (Kona), 27 bytes

`0:{|x$"#"}'1,,/{1_|x}\-2-!

Produce la secuencia numérica subyacente al invertir y soltar repetidamente la cabeza de un vector hasta que esté vacío.

Julian Squires
fuente
3
Bienvenido a PPCG.SE! Para que lo sepas, puedes poner tu código en un intérprete en línea llamado TIO (Pruébalo en línea) y vincularlo para que las personas puedan probar tu código. tio.run/#k-kona incluso le proporcionará una publicación PPCG formateada para que envíe aquí.
Notts90
0

PHP, 65 bytes

<?while(--$n||$n=$d=--$argn)echo str_pad("X
",2+$x-=$d&1?:-1);?>X

Ejecutar como tubería con -nFo probarlo en línea .

explicación:

primera iteración: $nes decir NULL, --$nno tiene efecto y se evalúa en NULL
-> establecer $ny $den el argumento pre-decrementado
1. incremento $xpara par $d, decremento para impar $d
2. impresión X, nueva línea y $xespacios

iteraciones adicionales: decremento $n; cuando golpea 0, restablece $n(y $d) al argumento pre-decrementado

final: imprime uno más X.

Titus
fuente
0

Japt , 31 bytes

Ç+V ç +QÃê ¯-2 c´U?ß´UVÄ :Vç +Q

Solución recursiva que devuelve una matriz de líneas.

Pruébalo en línea! usando la -Rbandera para unir la salida con nuevas líneas.

Justin Mariner
fuente
0

Python 2, 159 145 141 136 bytes

print"".join([" "*p+"#\n"for p in(lambda l:[sum(l[:i])for i in range(len(l))])(sum([i*[1-i%2*2]for i in range(input())[::-1]],[])+[1])])

Ya ha habido versiones bastante agradables de Python para este problema, pero pensé que aún publicaría mi horrible one-liner. (¡Sin punto y coma sin embargo!)

Editar: 14 bytes hacia abajo, usando suma en lugar de doble comprensión de lista

Editar: Acabo de notar que en Python 2 puede usar input en lugar de raw_input. Siempre he usado este último.

SydB
fuente
0

Mathematica, 142102 bytes (independiente)

Esta solución tiene un sabor a mathy:

UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&

Básicamente, esto calcula en qué segmento estamos (invirtiendo la función de número triangular) y luego moviéndonos hacia la izquierda o hacia la derecha agregando una potencia de -1.

Puede probarlo en Wolfram Code Sandbox pegando código como UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&@6//MatrixFormy presionando Shift + Enter o Numpad Enter o haciendo clic en Gear -> "Evaluar celda".


Esto tiene la misma longitud que mi puerto incorrecto original de la solución Python 2 de Erik (este puerto proporciona la salida para una entrada más alta):

(Print[X];l=Range@#;Do[Do[Print[StringRepeat[" ",l[[j]]]<>"X"],{j,Length@l}];l=l[[-2;;1;;-1]],{i,#}])&

Marcas.
fuente