Zigzag a convergenza lenta


23

Dato un singolo intero dispari positivo come input, restituisce uno zigzag convergente come un elenco di stringhe, un elenco di elenchi di caratteri o una stringa separata da una nuova riga, in questa forma:

#
 #
  #
   #
    #
   #
  #
 #
  #
   #
  #

È possibile sostituire #con qualsiasi carattere coerente non bianco. È consentito uno spazio bianco finale su ogni riga e è consentita una nuova riga finale.

Lo zig-zag inizia dalla colonna 1e per ogni riga si sposta a destra di una colonna, fino a raggiungere la colonna n(dove si ntrova l'input). Quindi, si sposta a sinistra 2, quindi a destra n-1, quindi a sinistra 3, con i due limiti convergenti fino a quando lo zigzag termina nella colonna centrale ( (n+1)/2).

Casi test

L'esempio sopra è il caso di prova per 5.

Di seguito sono riportati singoli casi di test:

3
#
 #
  #
 #

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

1

#

È consentito lo spazio bianco principale (ma coerente, cioè non infrangibile)?
Erik the Outgolfer,

@EriktheOutgolfer Ho intenzione di dire di no per quello.
HyperNeutrino,

Risposte:


15

C (gcc) , 89 byte

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);}

Provalo online!

Funziona analizzando la sequenza del numero di spazi come (per n = 7):

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

E per n = 3:

  0
1 2 1

Possiamo vedere che il numero medio ( anel codice) parte da [n-1, n / 2). Quindi, la differenza tra il primo numero e il numero medio è:

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

Quindi, se stiamo battraversando [- (2a-n), 2a-n], a-abs(b)ci darà la sequenza desiderata. Questo è essenzialmente ciò che fa il codice.


14

Carbone , 10 8 byte

FN«↗ι‖»/

Provalo online! Il collegamento è alla versione dettagliata del codice. Modifica: salvato 2 byte grazie a @dzaima per aver sottolineato che non devo usare #s.


Finalmente qualcosa che batte Jelly
JungHwan Min il


3

Gelatina , 14 byte

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

Provalo online!

Programma completo.

Usi 1.

-1 grazie a Jonathan Allan .
-1 grazie a Jonathan Allan .


’R-> per un byte.
Jonathan Allan,

@JonathanAllan Ooh ovviamente grazie. Avevo cercato di evitarlo in una versione precedente e l'ho dimenticato ...
Erik the Outgolfer

”X-> 1per un altro.
Jonathan Allan,

@JonathanAllan Heh un altro aspetto apparentemente ... Ho cercato di evitare anche i numeri interi.
Erik the Outgolfer,

3

Haskell , 72 byte

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

Provalo online!

Definiamo un elenco infinito ressendo la diagonale di #s a partire dall'angolo in alto a sinistra.

Definiamo quindi una funzione gche fa il peso del lavoro. gprenderà un elenco e lo invertirà ripetutamente e rimuoverà il suo primo elemento fino a quando l'elenco non sarà vuoto, quindi concatenerà il risultato di ogni azione.

La nostra funzione principale qui è una funzione senza punti. Questa funzione inizia prendendo gli nelementi dall'elenco infinito r, quindi taglia il primo elemento e si applica g. Ultimo dobbiamo aggiungere un #ritorno all'inizio, questo perché le specifiche della domanda sono un po 'strane, non sono sicuro del motivo per cui la prima diagonale è sempre una più lunga di quanto dovrebbe essere, ma lo è, quindi dobbiamo aggiungi aa #.


@nimi ho finito per fare ("#":).g.init.(take r)ma grazie!
Wheat Wizard,



2

05AB1E , 6 byte

LN71SΛ

Provalo online!

     Λ     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.

No, l'ho provato prima, ma disegna entrambe le direzioni, prima di continuare con l'elemento successivo dell'elenco di intervalli, quando rimuovo S. Quindi l'output diventerà il doppio del tempo. Non sapevo ancora di + e ×. Creano modelli davvero interessanti quando li combini con i numeri
Dorian,

Ah, hai davvero ragione. Colpa mia. Ho visto che ha funzionato senza S, ma non ho prestato sufficiente attenzione all'output ..>.> E +e ×sono fondamentalmente integrati per [0,4,4,0,2,6,6,2]e [1,5,5,1,3,7,7,3]. E 8ripristinerà l'origine da cui sei partito. Ecco qualche informazione in più.
Kevin Cruijssen,



1

JavaScript, 127 byte

Calcola l'obiettivo ( g) da raggiungere. Quando viene raggiunto questo obiettivo, tornare al prossimo obiettivo. Utilizza anche un trucco per evitare l'uso Math.round()aggiungendo 0.5a ogni numero irregolare.

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


1

Haskell, 74 byte

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

Provalo online!

Come funziona:

    [(' '<$[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

Ogni chiamata ricorsiva faggiunge alla diagonale successiva.



1

Buccia , 19 byte

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

Provalo online!

Spiegazione

Questo sembra un po 'goffo.

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.


1

Retina , 71 byte

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

Provalo online! Spiegazione: Le prime tre fasi convertono l'input nella forma in :> :cui il numero di caratteri tra la :s è il numero di input. Le ultime due fasi rimbalzano quindi >(o <, quando si sposta verso sinistra) tra le :s. Il quarto stadio avvolge il rimbalzo, stampando ogni volta le parti richieste della stringa. Il ;comando interrompe la stampa della stringa dopo il ciclo.


1

05AB1E , 16 byte

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

Provalo online!

Spiegazione

Î<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

1

K (Kona), 27 byte

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

Produce la sequenza numerica sottostante invertendo e rilasciando ripetutamente la testa di un vettore fino a quando è vuota.


3
Benvenuto in PPCG.SE! Solo per questo sai, puoi inserire il tuo codice in un interprete online chiamato TIO (Provalo online) e collegarti ad esso in modo che le persone possano provare il tuo codice. tio.run/#k-kona ti fornirà anche un post PPCG formattato da inviare qui.
Notts90,

0

PHP, 65 byte

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

Esegui come pipe -nFo testalo online .

spiegazione:

prima iterazione: $nè NULL, quindi --$nnon ha alcun effetto e valuta in NULL
-> imposta $ne $din argomento pre-decrementato
1. incremento $xper pari $d, decremento per dispari $d
2. stampa X, una nuova riga e $xspazi

ulteriori iterazioni: decremento $n; quando colpisce 0, reimposta $n(e $d) su argomento pre-decrementato

finale: stampane uno in più X.


0

Japt , 31 byte

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

Soluzione ricorsiva che restituisce una matrice di linee.

Provalo online!usando il -Rflag per unire l'output con le nuove righe.


0

Python 2, 159 145 141 136 byte

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

Ci sono già state delle belle versioni di Python a questo problema, ma ho pensato di pubblicare ancora il mio terribile one-liner. (Senza punto e virgola però!)

Modifica: 14 byte in giù, usando la somma anziché la comprensione della doppia lista

Modifica: appena notato in Python 2 puoi usare input invece di raw_input. Ho sempre usato quest'ultimo.


0

Mathematica, 142 102 byte (indipendente)

Questa soluzione ha un sapore mathy:

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

Questo in pratica calcola in quale segmento ci troviamo (invertendo la funzione numerica triangolare) e quindi spostandoci a sinistra oa destra aggiungendo una potenza di -1.

Puoi testarlo sulla sandbox del codice Wolfram incollando il codice come UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&@6//MatrixForme premendo Maiusc + Invio o Invio tastierino numerico o facendo clic su Ingranaggio -> "Valuta cella".


Questo sembra avere la stessa lunghezza della mia porta errata originale della soluzione Python 2 di Erik (questa porta fornisce l'output per un input superiore):

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.