Disegna una serie di catene montuose


16

Ispirato alla piastrellatura del domino di Fibonacci , questo problema riguarda la generazione di arte ASCII che rappresenta un'altra famosa sequenza combinatoria.

Un diagramma di n-step mountain è un disegno di una catena montuosa, usando esattamente i caratteri n '/' e n '\', in modo tale che i personaggi disegnino una curva continua che non scende mai al di sotto della sua "altitudine" iniziale. Per esempio,

   /\/\
/\/    \

e

   /\
/\/  \/\

sono entrambi diagrammi di montagne in 4 fasi, ma

/\  /\/\
  \/

non è.

Ingresso

Il programma dovrebbe accettare un numero intero n da stdin o come parametro per una funzione.

Produzione

Stampa tutti i diagrammi di n -step mountain su stdout. I diagrammi possono essere in qualsiasi ordine, ma devono essere separati da una sorta di spazio bianco. Puoi decidere se diversi diagrammi verranno emessi in orizzontale, in verticale, ecc.

Come nel problema della piastrellatura domino, è possibile utilizzare qualsiasi spazio bianco desiderato. Ciò include nuove righe extra prima o dopo l'output stampato.

Esempio

Alcuni esempi di output validi per n = 3:

Uscita valida A:

                                        /\
         /\             /\             /  \    /\/\
/\/\/\  /  \/\       /\/  \           /    \  /    \

Uscita valida B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

Uscita valida C:

  /\
 /  \       /\
/    \   /\/  \
                  /\/\
 /\              /    \
/  \/\   /\/\/\

Questo è il codice golf; vince il programma più breve (in byte).


Quando dici "Puoi decidere se diversi diagrammi verranno stampati in orizzontale, in verticale, ecc.", Le catene montuose possono essere lateralmente?
xnor,

Le catene montuose stesse non dovrebbero essere lateralmente. I cieli vuoti tra le vette aggiungono alla sfida, credo.
Matt Noonan,

Alcuni intervalli possono apparire più di una volta?
orgoglioso haskeller il

@MattNoonan Hai ragione, stampare le catene montuose in orizzontale era decisamente complicato.
xnor,

@ proud-haskeller Dovrebbe essere una volta ciascuno.
Matt Noonan,

Risposte:


10

Python 2: 151 caratteri

N=2*input()
for i in range(2**N):
 L=[];c=1;exec"b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\/'[b];i=i/2*(c>0);"*N
 for x in(c==1)*zip(*L):print"".join(x)

#Output for n=3:




  /\  
 /  \ 
/    \




 /\/\ 
/    \




   /\ 
/\/  \




 /\   
/  \/\





/\/\/\

Wow, questo è un casino.

La prima idea è quella di utilizzare i numeri 0 to 2**N-1per codificare tutte le sequenze di movimenti in Nalto e in basso nei loro bit. Leggiamo questi bit uno per uno ripetendoli %2e /2, ripetuti in un execciclo.

Memorizziamo lateralmente la catena montuosa in esecuzione in un elenco trasposto di stringhe L. Ogni volta, generiamo un nuovo una riga di spazi sostituisce uno spazio nella nuova riga con /o in \base al fatto che si sia verificato un movimento verso l'alto o verso il basso.

L'indice di quello spazio sono gli cspazi dalla fine, dove si ctrova l'altezza corrente. Farlo dal davanti renderebbe le montagne sottosopra. Lo spostiamo ulteriormente bper allineare i movimenti verso l'alto e verso il basso, ottenendo [b-c]. A partire cda 1 anziché 0 corregge un errore off-by-one.

Per eliminare i casi in cui cscende al di sotto del valore iniziale 1, quando ciò accade, impostiamo isu 0, il che fa sì che tutte le ulteriori mosse siano verso il basso, rendendo cpiù negativo. Quindi, quando controlliamo se è cterminato a 1, controlliamo anche se cmai ci è caduto sotto. Abbiamo solo printla catena montuosa se lo cè 1.

Per stampare, facciamo zip(*L)trasporre l'intervallo da verticale a orizzontale e stampare ogni stringa unita. Molti problemi in questa risposta sono arrivati ​​da Python che considera le stringhe come immutabili, quindi abbiamo lavorato con loro come elenchi di caratteri e li abbiamo uniti solo a stringhe per la stampa.

Grazie a @flornquake per aiuto e miglioramenti.


Dovrai utilizzare ' 'invece che " "se desideri eseguire il loop in uso exec. :) A proposito, non è necessario sfuggire alla barra rovesciata.
terremoto,

@flornquake Ho dimenticato di scrivere, l'ho usato ' 'e ho provato a sostituire la stringa con le virgolette con una variabile. Questo continuava a dare un indice fuori portata:for _ in[0]*N:exec("b=i%2;c+=2*b-1;L+=[[" "]*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);")
xnor

Intendevo dire che devi scrivere exec("b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);"), cioè le citazioni interne devono essere diverse da quelle esterne.
terremoto del

@flornquake Wow, mi sento sciocco, ho cambiato un paio di virgolette ma non l'altro. Grazie!
xnor

7

APL (88)

{{⍉↑'\/'[1+⍵=1]/⍨¨¯1+2×K=⊂⌽⍳⌈/K←(⍵≠1)++\⍵}¨Z/⍨{(0=+/⍵)∧∧/0≤+\⍵}¨Z←↓⍉¯1+2×(N/2)⊤⍳2*N←2×⍵}

Uscita per n=3:

      {{⍉↑'\/'[1+⍵=1]/⍨¨¯1+2×K=⊂⌽⍳⌈/K←(⍵≠1)++\⍵}¨Z/⍨{(0=+/⍵)∧∧/0≤+\⍵}¨Z←↓⍉¯1+2×(N/2)⊤⍳2*N←2×⍵}3
 /\/\/\     /\    /\      /\/\     /\   
         /\/  \  /  \/\  /    \   /  \  
                                 /    \ 

Spiegazione:

  • (N/2)⊤⍳2*N←2×⍵: ottieni un campo bit per ogni numero da 0a 2^⍵.
  • Z←↓⍉¯1+2×: moltiplica per 2 e sottrai 1, dando 1su e -1giù. Conservare un vettore di vettori, ogni vettore contenente la rappresentazione per un numero, in Z.
  • {... }¨Z: per ogni elemento di Z:
    • ∧/0≤+\⍵: verifica che la somma corrente non scenda mai al di sotto 0(non scende al di sotto del livello del suolo),
    • (0=+/⍵): e che la somma totale è 0(finisce a livello del suolo).
  • {... }¨Z/⍨: seleziona quegli elementi da Zcui è vero. Per ciascuno di essi:
    • K←(⍵≠1)++\⍵: trova l'altezza per ogni personaggio e memorizza in K. Sollevane \uno, in modo che si /allineino correttamente con la s. Questo rende l'altezza del terreno 1.
    • ¯1+2×K=⊂⌽⍳⌈/K: per ogni colonna, crea un elenco [1..max(K)]e segna la posizione del personaggio in quella colonna con 1e il resto come -1. (La replica di -1 riempie quella posizione con uno spazio.)
    • '\/'[1+⍵=1]/⍨¨: trova il carattere corretto per ogni colonna e replicalo dall'elenco per quella colonna.
    • ⍉↑: trasforma il risultato in una matrice e mettilo con il lato destro rivolto verso l'alto

Va bene, orizzontale!
Matt Noonan,

2

Python, 261 241 236 caratteri

import itertools as I
n=input()
S={}
for q in I.permutations((-1,1)*n):
 s=0;B=[[' ']*n*2 for _ in range(n+2)];o=0
 for i in q:
    B[n-s+(i==-1)][o]=' /\\'[i];s+=i;o+=1
    if s<0:break
 else:
    for l in (B,[])[q in S]:print''.join(l)
 S[q]=1

Inizia a prendere un po 'per n=5e su ...

$ echo 1 | py mountrange.py

/\



Laxori@Laxori-PC /cygdrive/c/Programmin
$ echo 2 | py mountrange.py


/\/\



 /\
/  \



Laxori@Laxori-PC /cygdrive/c/Programmin
$ echo 3 | py mountrange.py



/\/\/\




   /\
/\/  \




 /\
/  \/\




 /\/\
/    \



  /\
 /  \
/    \



Laxori@Laxori-PC /cygdrive/c/Programmin
$ echo 4 | py mountrange.py




/\/\/\/\





     /\
/\/\/  \





   /\
/\/  \/\





   /\/\
/\/    \




    /\
   /  \
/\/    \





 /\
/  \/\/\





 /\  /\
/  \/  \





 /\/\
/    \/\





 /\/\/\
/      \




    /\
 /\/  \
/      \




  /\
 /  \
/    \/\




  /\
 /  \/\
/      \




  /\/\
 /    \
/      \



   /\
  /  \
 /    \
/      \

2

JavaScript (ES6) 159 163

Proprio come la mia risposta per Fibonacci Domino Tiling, esamino tutte le sequenze di n + n bit, con 1 che contrassegna un '/' e 0 che contrassegna un '\' (solo per l'output, '2' viene successivamente aggiunto per contrassegnare una nuova riga) . Mentre costruisco il modello ascii, controllo l'equilibrio - stessi numeri di 0 e 1, senza mai andare al di sotto della linea di base iniziale - e produco ciò che obbedisce alle regole.

Output fatto con 'alert', che è standard per JS codegolf ma piuttosto fastidioso, e forse contro le regole. Usando console.log il conteggio dei caratteri arriva a 165.

F=n=>{
  for(i=0;++i<1<<n+n;l||alert((o+'').replace(/,\d?/g,r=>'\\/\n '[r[1]||3])))
    for(p=l=o=[],j=i;l+1&&p++-n-n;j/=2)
      b=j&1,
      l-=1-b-b,
      (o[k=b+n-l]=o[k]||[2])[p]=b;
}

Meno golf

F=n=>{
  m = n+n
  outer:
  for (i=1; i < 1<<m; i+=2)
  {
    o=[]
    l=0;
    p=1;
    for (j = 1; j <1<<m; j+=j,p++)
    {
      if (i&j)
      {
        q=o[n-l]||[]
        q[p]=1;
        o[n-l]=q
        ++l;
      }
      else
      {
        --l;
        if (l<0) continue outer;
        q=o[n-l]||[]
        q[p]=0;
        o[n-l]=q
      }
    }
    if (l==0) console.log(o.join('\n').replace(/,\d?/g,r=>'\\/'[r[1]]||' '));
  }
}

Test nella console FireFox / FireBug.

F(4)

Produzione

   /\
  /  \
 /    \
/      \ 

  /\/\
 /    \
/      \ 

    /\
 /\/  \
/      \ 

    /\
   /  \
/\/    \ 

  /\
 /  \/\
/      \ 

 /\/\/\
/      \ 

   /\/\
/\/    \ 

 /\  /\
/  \/  \ 

     /\
/\/\/  \ 

  /\
 /  \
/    \/\ 

 /\/\
/    \/\ 

   /\
/\/  \/\ 

 /\
/  \/\/\ 

/\/\/\/\ 

Curioso se hai qualche motivo particolare che scrivi -b-be -n-ninvece di -2*b?
Steve Bennett,

@SteveBennett nessun motivo. A volte questo schema è più breve, ma non questa volta (ad esempio: 2*b+1-> b-~b)
edc65

1

CJam, 84 byte

q~:Q{Q[XW]*mr1\{\_@+}%_{*}*{(\{_Q\-)S*@2$m0<" /""\\"?+QS*+Q)<\}%);z{N\++}*o}{;}?1}g

Nota che questo programma stampa le montagne in un ciclo infinito in modo che l'interprete online non ti aiuti; invocare dalla riga di comando utilizzando

java -jar cjam-0.6.2.jar mountain.cjam <<< 5

o per provare l'uso online

q~:Q{Q[XW]*mr1\{\_@+}%_{*}*{(\{_Q\-)S*@2$m0<" /""\\"?+QS*+Q)<\}%);z{N\++}*o}{;}?}fZ

e basta premere il pulsante Esegui più volte in successione e immaginare che l'output sia concatenato.

L'idea di base è che sappiamo che una catena montuosa di dimensioni Q ha Q di ogni transizione verso l'alto e verso il basso.

 Q[XW]*mr                                   #shuffled list of Q 1s and -1s
1        {\_@+}%                            #height map after each transition
                _{*}*                       #if it passes through 0 it's invalid

Quindi, se è valido, lo stampiamo, altrimenti lo estraiamo dalla pila in modo che non trabocchi.

Il routing di stampa fondamentalmente costruisce ogni colonna come Q - spazi di altezza, quindi il simbolo, quindi abbastanza più spazi per colpire Q + 1 caratteri totali, e quindi trasponiamo e stampiamo le linee con nuove linee tra loro.

z{N\++}*o                                   #transpose, insert newlines, print

Mentre stavo lavorando su questo, la domanda è stata chiarita per richiedere che le montagne fossero stampate una volta ciascuna. Ciò richiederà un ripensamento e probabilmente più personaggi: /
paradigmsort,

0

C, 179

escluso spazi bianchi non necessari.

Una strategia simile a edc65. Corro attraverso tutti i n*2valori binari -bit, considerando /= 1 e\ = 0.

Formatto una singola stringa contenente ninterruzioni di riga ogni n*3carattere. Come scritto la stringa contiene 1000 caratteri, quindi di solito c'è molto spazio stampato dopo la montagna. (Questo può essere risolto aggiungendo s[n*n*3]=0prima del puts.) Comunque, questo mi permette di produrre l'intera montagna con un singoloputs dopo aver verificato che sia conforme alle regole.

Proverò a convertirlo in una funzione e a ridurlo a un singolo forciclo più tardi.

i,n,x,y,q,r;
main(){
  scanf("%d",&n);
  for(i=1<<n*2;i--;){                              //run though all n*2-digit binary numbers
    char s[]={[0 ...999]=32};                      //fill an array with spaces. This syntax is allowed by GCC
    y=n;                                           //start y one square below the grid (note: r is initialised to 0 by default.)
    for(x=n*2;x--;)                                //for each digit of i
      q=i>>x&1,
      y+=q+r-1,                                    //move up if the current and last digit are 0, down if they are 1, and stay on the same line if they are different.
      y<n?s[y*n*3]=10,s[y*n*3+x+1]=92-45*q:(x=0),  //if y is within the grid, put a newline (ASCII 10)at the beginning of the row and write \ or / (ASCII 92 or 47) to the correct square. Otherwise abort the x loop.
      r=q;                                         //store the current bit of i to r as it will be needed on the next iteration 
    n-1-y||puts(s);                                //if y is on the bottom row of the grid, output the mountain 
  }
}

Output (notare l'enorme quantità di spazi bianchi a destra)

$ ./a
4

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

0

Haskell, 140 byte

Dopo diversi tentativi non riusciti a essere molto giocabili, ho finito con questa implementazione di Haskell. Sono felice solo di essere all'interno di un fattore 2 della soluzione APL!

Soluzione golfizzata:

e=' ':e
m=[[]]:[[('/':e):map(' ':)x++('\\':e):y|k<-[0..n],x<-m!!(n-k),y<-m!!k]|n<-[0..]]
f n=putStr$unlines[map(!!(n-k))a|a<-m!!n,k<-[1..n]]

Ungolf e commentato:

Il programma crea ricorsivamente l'insieme dei diagrammi di montagna n -step. Ogni diagramma è rappresentato da un elenco di stringhe infinitamente lunghe, che rappresentano la montagna disegnata lateralmente seguita da spazi che si estendono all'infinito. Ciò garantisce che tutti i diagrammi abbiano la stessa altezza, il che semplifica la ricorsione. La stampante da montagna accetta un parametro che fissa l'altezza a un valore finito.

import Data.List (transpose)

-- Elementary picture slices, extending to infinity.
empty = ' ' : empty
up    = '/' : empty
down  = '\\': empty

-- A function which draws a mountain picture to stdout, clipping
-- its height to n.
printMtn n = putStr . unlines . reverse . take n . transpose 

{-- Combine mountain pictures x and y by

              x
 x # y  ==   / \y

--}
x # y = up : raised x ++ down : y
    where raised = map (' ':)

-- Given two sets X,Y of mountain pictures, compute the set X <> Y of all
-- combined pictures x#y for x in X, y in Y.
xs <> ys = [ x # y | x <- xs, y <- ys ]

-- Compute the (++,<>)-convolution of a list with itself, e.g.:
--   autoConvolve [x0,x1,x2] == (x2 <> x0) ++ (x1 <> x1) ++ (x0 <> x2)
autoConvolve xs = concat $ zipWith (<>) (reverse xs) xs

{--
    mtns is a list whose nth entry is the list of all n-step mountain diagrams.
    It is defined recursively by:
        --  The only 0-step mountain diagram is empty.
        --  Each (n+1)-step diagram can be uniquely drawn as x#y for
            some k-step diagram x and (n-k)-step diagram y.
--}
mtns = [[]] : [autoConvolve (prefix n) | n <- [1..]]
    where prefix n = take n mtns

-- The driver function: apply the height n mountain printer to each
-- n-step mountain diagram.  Whitespace is guaranteed by the order
-- in which the diagrams appear.
test n = mapM_ (printMtn n) $ mtns!!n

Esempio di utilizzo:

$ ghci mtn3.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( mtn3.hs, interpreted )
Ok, modules loaded: Main.
λ> f 3
  /\  
 /  \ 
/    \

 /\/\ 
/    \

 /\   
/  \/\

   /\ 
/\/  \


/\/\/\
λ> 

0

GolfScript 103 ( demo )

2*:§2\?,{2base.,§\-[0]*\+:a 1\{.2*@(.@+@@+}%:l$)\;),-1%{a,,{.l=2$=\a=1$+*' \\/'= }%\;n+}%\1=*l$(\;0>*}/

Il programma accetta un parametro intero che tenta di eseguire il rendering come montagne di tutte le rappresentazioni binarie dei numeri da 0 a 2 ^ (n-1). Non rende combinazioni non valide (es: quelle che vanno al di sotto del livello 0).

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.