Vẽ một dãy các dãy núi


16

Lấy cảm hứng từ ốp lát Fibino domino , vấn đề này là về việc tạo ra nghệ thuật ASCII đại diện cho một chuỗi tổ hợp nổi tiếng khác.

Một sơ đồ núi n bước là một bản vẽ của một dãy núi, sử dụng chính xác n '/' và n '\' nhân vật, như vậy mà nhân vật phác họa một đường cong liên tục mà không bao giờ dips dưới "độ cao" ban đầu của nó. Ví dụ,

   /\/\
/\/    \

   /\
/\/  \/\

là cả hai sơ đồ núi 4 bước, nhưng

/\  /\/\
  \/

không phải.

Đầu vào

Chương trình nên chấp nhận một số nguyên n từ stdin hoặc làm tham số cho hàm.

Đầu ra

In tất cả các sơ đồ núi n -step đến thiết bị xuất chuẩn. Các sơ đồ có thể theo bất kỳ thứ tự nào, nhưng nên được phân tách bằng một số khoảng trắng. Bạn có thể quyết định nếu các sơ đồ khác nhau sẽ được xuất theo chiều ngang, chiều dọc, v.v.

Như trong bài toán ốp lát domino, bạn có thể sử dụng bất kỳ khoảng trắng nào bạn muốn. Điều này bao gồm các dòng mới bổ sung trước hoặc sau khi đầu ra được in.

Thí dụ

Một số mẫu đầu ra hợp lệ cho n = 3:

Đầu ra hợp lệ A:

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

Đầu ra hợp lệ B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

Đầu ra hợp lệ C:

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

Đây là mã golf; chương trình ngắn nhất (tính bằng byte) thắng.


Khi bạn nói "Bạn có thể quyết định xem các sơ đồ khác nhau sẽ được xuất theo chiều ngang, chiều dọc, v.v.", các dãy núi có thể nằm ngang không?
xnor

Các dãy núi không nên đi ngang. Bầu trời trống giữa các đỉnh núi làm tăng thêm thách thức, tôi nghĩ vậy.
Matt Noonan

Một số phạm vi có thể xuất hiện nhiều hơn một lần?
tự hào

@MattNoonan Bạn nói đúng, in các dãy núi theo chiều ngang chắc chắn là khó khăn.
xnor

@ kiêu hãnh-haskeller Nó nên là một lần mỗi.
Matt Noonan

Câu trả lời:


10

Python 2: 151 ký tự

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, đây là một mớ hỗn độn.

Ý tưởng đầu tiên là sử dụng các số 0 to 2**N-1để mã hóa tất cả các chuỗi Nchuyển động lên và xuống trong bit của chúng. Chúng tôi lần lượt đọc từng bit một %2/2lặp đi lặp lại trong một execvòng lặp.

Chúng tôi lưu trữ các dãy núi chạy ngang trong một danh sách các chuỗi chuyển L. Mỗi lần, chúng tôi tạo ra một hàng không gian mới sẽ thay thế một không gian trong hàng mới bằng /hoặc \tùy thuộc vào việc xảy ra di chuyển lên hay xuống.

Chỉ số của không gian đó là ckhoảng trắng từ cuối, cchiều cao đang chạy. Làm điều đó từ phía trước sẽ làm cho những ngọn núi lộn ngược. Chúng tôi tiếp tục thay đổi nó bằng cách bsắp xếp di chuyển lên và xuống, nhận được [b-c]. Bắt đầu từ c1 thay vì 0 sửa lỗi tắt.

Để loại bỏ trường hợp cdips dưới giá trị bắt đầu 1, khi điều này xảy ra, chúng tôi đặt iđể 0, khiến tất cả di chuyển xa hơn là đi xuống, làm cho ctrở nên tiêu cực hơn. Sau đó, khi chúng tôi kiểm tra xem cđã kết thúc vào lúc nào chưa 1, chúng tôi cũng kiểm tra xem có cbao giờ giảm xuống dưới mức đó không. Chúng tôi chỉ có printdãy núi nếu c1.

Để in, chúng tôi thực hiện zip(*L)chuyển đổi phạm vi từ dọc sang ngang và in từng chuỗi đã nối. Rất nhiều rắc rối trong câu trả lời này đến từ Python coi các chuỗi là bất biến, vì vậy chúng tôi đã làm việc với chúng dưới dạng danh sách các ký tự và chỉ nối chúng thành các chuỗi để in.

Cảm ơn @flornquake đã giúp đỡ và cải thiện.


Bạn sẽ cần sử dụng ' 'thay vì " "nếu bạn muốn lặp lại bằng cách sử dụng exec. :) Btw, bạn không cần phải thoát khỏi dấu gạch chéo ngược.
flornquake

@flornquake Tôi quên viết, tôi đã sử dụng ' 'và thử thay thế chuỗi bằng dấu ngoặc kép bằng một biến cho nó. Điều này vẫn đưa ra chỉ số ngoài phạm vi: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

Tôi có nghĩa là bạn cần phải viết exec("b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);"), tức là các trích dẫn bên trong phải khác với bên ngoài.
flornquake

@flornquake Wow tôi cảm thấy ngớ ngẩn, tôi đã thay đổi một cặp trích dẫn nhưng không phải cái khác. Cảm ơn!
xnor

7

APL (88)

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

Đầu ra cho n=3:

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

Giải trình:

  • (N/2)⊤⍳2*N←2×⍵: lấy bitfield cho mỗi số từ 0đến 2^⍵.
  • Z←↓⍉¯1+2×: nhân với 2 và trừ 1, 1cho lên và -1xuống. Lưu trữ một vectơ của vectơ, mỗi vectơ chứa biểu diễn cho một số, trong Z.
  • {... }¨Z: cho từng yếu tố của Z:
    • ∧/0≤+\⍵: kiểm tra xem tổng chạy không bao giờ giảm xuống dưới 0(không đi dưới mặt đất),
    • (0=+/⍵): và tổng tiền là 0(kết thúc trở lại ở mặt đất).
  • {... }¨Z/⍨: chọn những yếu tố mà từ Zđó là đúng. Đối với mỗi người trong số họ:
    • K←(⍵≠1)++\⍵: tìm chiều cao cho mỗi ký tự và lưu trữ trong K. Nâng từng cái \lên một, sao cho chúng thẳng hàng với /s. Điều này làm cho chiều cao mặt đất 1.
    • ¯1+2×K=⊂⌽⍳⌈/K: cho mỗi cột, tạo một danh sách [1..max(K)]và đánh dấu vị trí của ký tự trong cột đó 1và phần còn lại là -1. (Sao chép bằng -1 lấp đầy vị trí đó bằng một khoảng trắng.)
    • '\/'[1+⍵=1]/⍨¨: tìm ký tự chính xác cho mỗi cột và sao chép nó theo danh sách cho cột đó.
    • ⍉↑: biến kết quả thành ma trận và đặt nó ở bên phải

Được rồi, một ngang!
Matt Noonan

2

Con trăn, 261 241 236 ký tự

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

Nó bắt đầu mất một lúc n=5và lên ...

$ 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

Giống như câu trả lời của tôi dành cho Fibre Domino Tiling, tôi kiểm tra tất cả các chuỗi của n + n bit, với 1 đánh dấu '/' và 0 đánh dấu '\' (chỉ cho đầu ra, '2' sau đó được thêm vào để đánh dấu một dòng mới) . Trong khi xây dựng mô hình tha ascii, tôi kiểm tra số dư - cùng số 0 và 1, và không bao giờ đi dưới đường cơ sở bắt đầu - và đưa ra những gì tuân theo quy tắc.

Đầu ra được thực hiện với 'alert', đó là tiêu chuẩn cho codegolf JS nhưng khá khó chịu và có thể trái với quy tắc. Sử dụng console.log, số lượng ký tự lên tới 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;
}

Ít chơi gôn

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

Thử nghiệm trong bảng điều khiển FireFox / FireBug.

F(4)

Đầu ra

   /\
  /  \
 /    \
/      \ 

  /\/\
 /    \
/      \ 

    /\
 /\/  \
/      \ 

    /\
   /  \
/\/    \ 

  /\
 /  \/\
/      \ 

 /\/\/\
/      \ 

   /\/\
/\/    \ 

 /\  /\
/  \/  \ 

     /\
/\/\/  \ 

  /\
 /  \
/    \/\ 

 /\/\
/    \/\ 

   /\
/\/  \/\ 

 /\
/  \/\/\ 

/\/\/\/\ 

Tò mò nếu có bất kỳ lý do cụ thể bạn viết -b-b-n-nthay vì -2*b?
Steve Bennett

@SteveBennett không có lý do. Đôi khi mẫu này ngắn hơn, nhưng không phải lúc này (ví dụ: 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

Lưu ý rằng chương trình này in các ngọn núi trong một vòng lặp vô hạn để trình thông dịch trực tuyến sẽ không giúp bạn; gọi vào dòng lệnh bằng cách sử dụng

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

hoặc để thử sử dụng trực tuyến

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

và chỉ cần nhấn nút chạy liên tiếp nhiều lần và tưởng tượng đầu ra được nối.

Ý tưởng cơ bản là chúng ta biết một dãy núi có kích thước Q có Q của mỗi lần chuyển tiếp lên và xuống.

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

Sau đó, nếu nó hợp lệ, chúng tôi sẽ in nó, nếu không chúng tôi sẽ bật nó khỏi ngăn xếp để nó không bị tràn.

Định tuyến in về cơ bản xây dựng mỗi cột dưới dạng không gian Q - chiều cao, sau đó là ký hiệu, sau đó đủ nhiều khoảng trống hơn để đạt tổng số ký tự Q + 1, sau đó chúng tôi hoán chuyển và in các dòng với dòng mới giữa chúng.

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

Trong khi tôi đang làm việc này, câu hỏi đã được làm rõ để yêu cầu rằng các ngọn núi phải được in một lần mỗi ngọn. Điều đó sẽ đòi hỏi một số suy nghĩ lại và có thể nhiều nhân vật hơn: /
paradigmsort

0

C, 179

Không bao gồm khoảng trắng không cần thiết.

Một chiến lược tương tự như edc65. Tôi chạy qua tất cả các n*2giá trị nhị phân -bit, xem xét /= 1 và \= 0.

Tôi định dạng một chuỗi chứa chuỗi nngắt mỗi n*3ký tự. Như đã viết, chuỗi chứa 1000 ký tự, do đó thường có rất nhiều khoảng trắng được in sau ngọn núi. (Điều này có thể được khắc phục bằng cách thêm vào s[n*n*3]=0trước puts.) Dù sao, điều này cho phép tôi xuất toàn bộ ngọn núi bằng một lần duy nhất putssau khi kiểm tra xem nó có tuân thủ các quy tắc không.

Tôi sẽ thử chuyển đổi nó thành một chức năng và giảm xuống một forvòng lặp sau.

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

Đầu ra (lưu ý số lượng lớn khoảng trắng ở bên phải)

$ ./a
4

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

0

Haskell, 140 byte

Sau nhiều lần thất bại trong việc chơi golf, tôi đã kết thúc với việc thực hiện Haskell này. Tôi rất vui khi được nằm trong hệ số 2 của giải pháp APL!

Giải pháp đánh gôn:

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

Ungolfed và bình luận:

Chương trình xây dựng tập hợp các sơ đồ núi n -step đệ quy. Mỗi sơ đồ được thể hiện bằng một danh sách các chuỗi dài vô tận, đại diện cho ngọn núi được vẽ sang một bên theo sau là các không gian kéo dài đến vô tận. Điều này đảm bảo rằng tất cả các sơ đồ có cùng chiều cao, giúp việc đệ quy dễ dàng hơn. Máy in núi chấp nhận một tham số cắt chiều cao thành giá trị hữu hạn.

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

Sử dụng mẫu:

$ 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 ( bản demo )

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

Chương trình lấy một tham số nguyên cố gắng hiển thị dưới dạng núi tất cả các biểu diễn nhị phân của các số từ 0 đến 2 ^ (n-1). Nó không hiển thị các kết hợp không hợp lệ (ví dụ: các kết hợp dưới mức 0).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.