Gambarlah serangkaian pegunungan

16

Terinspirasi oleh ubin domino Fibonacci , masalah ini adalah tentang menghasilkan seni ASCII yang mewakili urutan kombinatorial terkenal lainnya.

Sebuah diagram gunung n-langkah adalah gambar dari pegunungan, menggunakan persis n '/' dan n '\' karakter, sehingga karakter sketsa kurva terus menerus yang tidak pernah dips di bawah "ketinggian" awal. Sebagai contoh,

   /\/\
/\/    \

dan

   /\
/\/  \/\

keduanya diagram gunung 4 langkah, tetapi

/\  /\/\
  \/

tidak.

Memasukkan

Program harus menerima bilangan bulat n dari stdin atau sebagai parameter ke suatu fungsi.

Keluaran

Cetak semua n -langkah diagram gunung ke stdout. Diagram bisa dalam urutan apa pun, tetapi harus dipisahkan oleh semacam spasi putih. Anda dapat memutuskan apakah berbagai diagram akan ditampilkan secara horizontal, vertikal, dll.

Seperti dalam masalah ubin domino, Anda dapat menggunakan spasi putih apa pun yang Anda inginkan. Ini termasuk baris baru tambahan sebelum atau setelah hasil cetak.

Contoh

Beberapa sampel keluaran valid untuk n = 3:

Output yang valid A:

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

Output yang valid B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

Output yang valid C:

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

Ini adalah kode golf; program terpendek (dalam byte) menang.

Matt Noonan
sumber
Ketika Anda mengatakan "Anda dapat memutuskan apakah berbagai diagram akan ditampilkan secara horizontal, vertikal, dll.", Bisakah pegunungan itu sendiri menyamping?
xnor
Barisan gunung itu sendiri seharusnya tidak menyamping. Langit kosong di antara puncak menambah tantangan, saya pikir.
Matt Noonan
Bisakah beberapa rentang muncul lebih dari satu kali?
haskeller bangga
@MattNoonan Anda benar, mencetak pegunungan secara horizontal jelas sulit.
xnor
@ proud-haskeller Seharusnya masing-masing satu kali.
Matt Noonan

Jawaban:

10

Python 2: 151 karakter

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, ini berantakan.

Ide pertama adalah menggunakan angka-angka 0 to 2**N-1untuk menyandikan semua urutan Ngerakan naik dan turun dalam bit mereka. Kami membaca bit-bit ini satu per satu dengan mengulangi %2dan /2, berulang dalam satu execlingkaran.

Kami menyimpan deretan pegunungan yang mengalir ke samping dalam daftar string yang dialihkan L. Setiap kali, kami menghasilkan baris spasi baru menggantikan satu spasi di baris baru dengan /atau \tergantung pada apakah gerakan naik atau turun terjadi.

Indeks ruang itu adalah cruang dari ujung, di mana ctinggi lari. Melakukannya dari depan akan membuat gunung-gunung terbalik. Kami selanjutnya menggesernya dengan bmenyejajarkan gerakan ke atas dan ke bawah, mendapatkan [b-c]. Mulai cdari 1 daripada 0 memperbaiki kesalahan tidak langsung oleh satu.

Untuk menghilangkan kasus di mana cdips di bawah nilai awal 1, ketika hal ini terjadi, kami menetapkan iuntuk 0, yang menyebabkan semua bergerak lebih lanjut untuk menjadi ke bawah, membuat cmenjadi lebih negatif. Kemudian, ketika kami memeriksa apakah cberakhir pada 1, kami juga memeriksa apakah cpernah jatuh di bawahnya. Kami hanya printpegunungan jika cini 1.

Untuk mencetak, kita lakukan zip(*L)untuk mengubah rentang dari vertikal ke horizontal, dan mencetak setiap string yang bergabung. Banyak masalah dalam jawaban ini berasal dari Python memperlakukan string sebagai tidak dapat diubah, jadi kami bekerja dengannya sebagai daftar karakter dan hanya menggabungkannya menjadi string untuk dicetak.

Terima kasih kepada @florn untuk bantuan dan peningkatan.

Tidak
sumber
Anda harus menggunakan ' 'alih-alih " "jika ingin mengulang menggunakan exec. :) Btw, Anda tidak perlu melarikan diri dari backslash.
flornquake
@flakequake Saya lupa menulis, saya menggunakan ' 'dan mencoba mengganti string dengan tanda kutip dengan variabel untuknya. Ini masih memberikan indeks di luar kisaran: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
Maksud saya, Anda perlu menulis exec("b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);"), yaitu kutipan dalam harus berbeda dari kutipan luar.
flornquake
@flakequake Wow saya merasa konyol, saya mengubah satu pasang tanda kutip tetapi tidak yang lain. Terima kasih!
xnor
7

APL (88)

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

Output untuk n=3:

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

Penjelasan:

  • (N/2)⊤⍳2*N←2×⍵: dapatkan bitfield untuk setiap nomor dari 0hingga 2^⍵.
  • Z←↓⍉¯1+2×: kalikan dengan 2 dan kurangi 1, memberi 1untuk naik -1turun. Menyimpan vektor vektor, masing-masing vektor berisi representasi untuk satu angka, dalam Z.
  • {... }¨Z: untuk setiap elemen Z:
    • ∧/0≤+\⍵: periksa bahwa jumlah berjalan tidak pernah jatuh di bawah 0(tidak pergi di bawah permukaan tanah),
    • (0=+/⍵): dan jumlah totalnya adalah 0(berakhir kembali di permukaan tanah).
  • {... }¨Z/⍨: pilih elemen-elemen dari Zmana itu benar. Untuk masing-masing:
    • K←(⍵≠1)++\⍵: temukan ketinggian untuk setiap karakter, dan simpan di K. Angkat masing \- masing satu, sehingga mereka sejajar dengan /huruf s dengan benar. Ini membuat ketinggian tanah 1.
    • ¯1+2×K=⊂⌽⍳⌈/K: untuk setiap kolom, buat daftar [1..max(K)], dan tandai posisi karakter dalam kolom itu dengan 1dan sisanya sebagai -1. (Replikasi dengan -1 mengisi posisi itu dengan spasi.)
    • '\/'[1+⍵=1]/⍨¨: temukan karakter yang benar untuk setiap kolom, dan gandakan dengan daftar untuk kolom itu.
    • ⍉↑: ubah hasilnya menjadi matriks dan letakkan di sebelah kanan
marinus
sumber
Baiklah, horisontal!
Matt Noonan
2

Python, 261 241 236 karakter

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

Itu mulai memakan waktu untuk n=5dan ke atas ...

$ 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




/\/\/\/\





     /\
/\/\/  \





   /\
/\/  \/\





   /\/\
/\/    \




    /\
   /  \
/\/    \





 /\
/  \/\/\





 /\  /\
/  \/  \





 /\/\
/    \/\





 /\/\/\
/      \




    /\
 /\/  \
/      \




  /\
 /  \
/    \/\




  /\
 /  \/\
/      \




  /\/\
 /    \
/      \



   /\
  /  \
 /    \
/      \
Claudiu
sumber
2

JavaScript (ES6) 159 163

Sama seperti jawaban saya untuk Fibonacci Domino Tiling, saya memeriksa semua urutan n + n bit, dengan 1 menandai '/' dan 0 menandai '\' (hanya untuk output, '2' kemudian ditambahkan untuk menandai baris baru) . Sambil membangun pola ascii saya memeriksa saldo - angka yang sama 0 dan 1, dan tidak pernah pergi di bawah garis dasar awal - dan menampilkan apa yang mematuhi aturan.

Keluaran dilakukan dengan 'waspada', yaitu standar untuk codegolf JS tetapi cukup menjengkelkan, dan mungkin melanggar aturan. Menggunakan console.log jumlah karakter menjadi 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;
}

Kurang 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]]||' '));
  }
}

Tes di konsol FireFox / FireBug.

F(4)

Keluaran

   /\
  /  \
 /    \
/      \ 

  /\/\
 /    \
/      \ 

    /\
 /\/  \
/      \ 

    /\
   /  \
/\/    \ 

  /\
 /  \/\
/      \ 

 /\/\/\
/      \ 

   /\/\
/\/    \ 

 /\  /\
/  \/  \ 

     /\
/\/\/  \ 

  /\
 /  \
/    \/\ 

 /\/\
/    \/\ 

   /\
/\/  \/\ 

 /\
/  \/\/\ 

/\/\/\/\ 
edc65
sumber
Penasaran apakah ada alasan khusus yang Anda tulis -b-bdan -n-nbukan -2*b?
Steve Bennett
@SteveBennett tanpa alasan. Terkadang pola ini lebih pendek, tetapi tidak kali ini (misalnya: 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

Perhatikan bahwa program ini mencetak pegunungan dalam loop yang tidak terbatas sehingga penerjemah online tidak akan membantu Anda; aktifkan di baris perintah menggunakan

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

atau untuk mencoba penggunaan online

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

dan cukup tekan tombol run beberapa kali berturut-turut dan bayangkan outputnya digabungkan.

Ide dasarnya adalah bahwa kita tahu pegunungan dengan ukuran Q memiliki Q untuk setiap transisi ke atas dan ke bawah.

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

Kemudian jika itu valid, kita mencetaknya, jika tidak kita keluarkan dari tumpukan agar tidak meluap.

Perutean cetak pada dasarnya membangun setiap kolom sebagai ruang tinggi Q, lalu simbol, lalu cukup banyak ruang untuk mencapai karakter total Q + 1, dan kemudian kami mengubah dan mencetak garis dengan garis baru di antaranya.

z{N\++}*o                                   #transpose, insert newlines, print
paradigma
sumber
Ketika saya sedang mengerjakan ini, pertanyaannya diklarifikasi untuk mengharuskan gunung dicetak masing-masing. Itu akan membutuhkan beberapa pemikiran ulang dan mungkin lebih banyak karakter: /
paradigmsort
0

C, 179

tidak termasuk spasi yang tidak perlu.

Strategi yang mirip dengan edc65. Saya menjalankan semua nilai n*2biner -bit, dengan mempertimbangkan /= 1 dan \= 0.

Saya memformat string tunggal yang berisi nlinebreak setiap n*3karakter. Seperti ditulis, string berisi 1000 karakter, jadi biasanya ada banyak spasi putih yang dicetak setelah gunung. (Ini dapat diperbaiki dengan menambahkan s[n*n*3]=0sebelum puts.) Bagaimanapun, ini memungkinkan saya untuk output seluruh gunung dengan satu putssetelah memeriksa apakah itu sesuai dengan aturan.

Saya akan mencoba mengubahnya menjadi suatu fungsi dan mengurangi ke satu forloop nanti.

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

Keluaran (catat jumlah besar spasi putih di kanan)

$ ./a
4

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
Level River St
sumber
0

Haskell, 140 byte

Setelah beberapa upaya gagal menjadi golf, saya berakhir dengan implementasi Haskell ini. Saya senang hanya berada dalam faktor 2 dari solusi APL!

Solusi golf:

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

Tidak dikumpulkan dan berkomentar:

Program ini membangun himpunan diagram gunung n-langkah secara rekursif. Setiap diagram diwakili oleh daftar string yang panjangnya tak terhingga, mewakili gunung yang ditarik ke samping diikuti oleh ruang yang memanjang hingga tak terbatas. Ini memastikan bahwa semua diagram memiliki ketinggian yang sama, yang membuat rekursi lebih mudah. Printer gunung menerima parameter yang memotong ketinggian hingga nilai yang terbatas.

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

Penggunaan sampel:

$ 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
  /\  
 /  \ 
/    \

 /\/\ 
/    \

 /\   
/  \/\

   /\ 
/\/  \


/\/\/\
λ> 
Matt Noonan
sumber
0

GolfScript 103 ( demo )

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

Program ini mengambil parameter integer yang akan di-render karena mem-mount semua representasi biner dari angka dari 0 menjadi 2 ^ (n-1). Itu tidak membuat kombinasi yang tidak valid (mis: yang masuk di bawah level 0).

Cristian Lupascu
sumber