画出山脉


16

斐波那契多米诺骨牌拼贴的启发,此问题与生成代表另一种著名组合序列的ASCII艺术有关。

正步骤山图是山脉的图,使用完全相同Ñ “/”和Ñ “\”字符,使得字符绘制一连续曲线,该曲线永不下降到低于其初始的“高度”。例如,

   /\/\
/\/    \

   /\
/\/  \/\

都是四步山图,但是

/\  /\/\
  \/

不是。

输入值

程序应从stdin 接受整数n或作为函数的参数。

输出量

将所有n步山图打印到stdout。图可以以任何顺序排列,但应以某种空白分隔。您可以决定是否将水平,垂直等输出不同的图。

就像在多米诺砖化问题中一样,您可以使用所需的任何空白。这包括在打印输出之前或之后的多余换行符。

对于n = 3的一些示例有效输出:

有效输出A:

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

有效输出B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

有效输出C:

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

这是代码高尔夫;最短的程序(以字节为单位)获胜。


当您说“您可以决定是否将水平,垂直等方式输出不同的图表”时,山脉本身是否可以横向倾斜?
xnor 2014年

山脉本身不应该侧身。我认为,山峰之间空旷的天空增加了挑战。
Matt Noonan 2014年

某些范围可以出现多次吗?
骄傲的haskeller 2014年

@MattNoonan是的,水平打印山脉绝对是棘手的。
xnor 2014年

@ proud-haskeller每个应该一次。
Matt Noonan 2014年

Answers:


10

Python 2:151个字符

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:




  /\  
 /  \ 
/    \




 /\/\ 
/    \




   /\ 
/\/  \




 /\   
/  \/\





/\/\/\

哇,真是一团糟。

第一个想法是使用数字0 to 2**N-1对位中所有N上移和下移序列进行编码。我们逐个重复地读取这些位,%2然后/2exec循环中进行迭代。

我们将奔跑的山脉侧身存储在转置的弦乐列表中L。每次生成新行时,都会用/\取决于发生上移还是下移来替换新行中的一个空格。

该空间的索引是c从末端开始的空间,其中c是运行高度。从前面做它会使山脉颠倒。我们通过b上下移动来进一步调整它,得到[b-c]。从c1 开始而不是从0开始修正了一对一的错误。

为了消除这种情况,当发生c低于起始值的1情况时,我们将设置i0,这会使所有进一步的移动都向下,从而c变得更加不利。然后,当我们检查是否c在结束时1,我们还要检查是否c跌破了它。print如果c是的话,我们只有山脉1

要进行打印,我们要做的zip(*L)是将范围从垂直移到水平,并打印每个连接的字符串。Python将该字符串视为不可变的,给这个答案带来了很多麻烦,因此我们将它们作为字符列表使用,并且仅将它们加入字符串进行打印。

感谢@flornquake的帮助和改进。


如果要循环使用' '" "则需要使用而不是exec。:)顺便说一句,您不需要转义反斜杠。
flornquake 2014年

我忘了写@flornquake,我确实使用过' '并尝试用带引号的变量替换字符串。这仍然使索引超出范围:for _ in[0]*N:exec("b=i%2;c+=2*b-1;L+=[[" "]*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);")
xnor14

我的意思是您需要编写exec("b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);"),即内部引号必须与外部引号不同。
flornquake

@flornquake哇,我觉得很傻,我更改了一对引号,但没有更改另一对引号。谢谢!
xnor 2014年

7

APL(88)

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

输出为n=3

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

说明:

  • (N/2)⊤⍳2*N←2×⍵:获取从每个号码位域02^⍵
  • Z←↓⍉¯1+2×:乘以2并减去1,得出1向上和-1向下的值。将向量的向量存储在中,每个向量均包含一个数字的表示形式Z
  • {... }¨Z:针对Z
    • ∧/0≤+\⍵:请检查运行总和0是否不低于(不低于地面水平),
    • (0=+/⍵):总和为0(返回地面)。
  • {... }¨Z/⍨:从中选择正确的元素Z。对于每个人:
    • K←(⍵≠1)++\⍵:找到每个字符的高度,然后存储在中K。向上\调高每个,使它们与/s正确对齐。这使得地面高度1
    • ¯1+2×K=⊂⌽⍳⌈/K:对于每一列,创建一个列表[1..max(K)],并用标记字符在该列中的位置,1其余标记为-1。(以-1复制将在该位置填充一个空格。)
    • '\/'[1+⍵=1]/⍨¨:找到每列的正确字符,然后按该列的列表复制它。
    • ⍉↑:将结果转换成矩阵并将其正面朝上

好吧,水平的!
Matt Noonan 2014年

2

Python,第261个 241 236字符

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=5...

$ 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

就像我对Fibonacci Domino Tiling的回答一样,我检查了所有n + n位的序列,其中1标记为'/',0标记为'\'(仅用于输出,以后添加'2'来标记换行符) 。在建立ASCII模式时,我检查余额-相同的0和1,并且从不低于起始基准线-输出遵循规则的内容。

输出是通过“ alert”完成的,这是JS codegolf的标准功能,但很烦人,而且可能违反了规则。使用console.log,字符数达到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;
}

少打高尔夫球

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

在FireFox / FireBug控制台中进行测试

F(4)

输出量

   /\
  /  \
 /    \
/      \ 

  /\/\
 /    \
/      \ 

    /\
 /\/  \
/      \ 

    /\
   /  \
/\/    \ 

  /\
 /  \/\
/      \ 

 /\/\/\
/      \ 

   /\/\
/\/    \ 

 /\  /\
/  \/  \ 

     /\
/\/\/  \ 

  /\
 /  \
/    \/\ 

 /\/\
/    \/\ 

   /\
/\/  \/\ 

 /\
/  \/\/\ 

/\/\/\/\ 

好奇您是否有任何特定原因-b-b-n-n不是-2*b
史蒂夫·本内特

@SteveBennett没有理由。有时这种模式会更短一些,但这次却不如此(例如:2*b+1-> b-~b
edc65

1

CJam,84个字节

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

请注意,该程序无限循环地打印山脉,因此在线解释器不会为您提供帮助;在命令行使用

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

或尝试在线使用

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

然后连续多次点击运行按钮,然后想象输出是串联的。

基本思想是,我们知道大小为Q的山脉在每个上,下过渡处都有Q。

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

然后,如果有效,我们将其打印,否则将其从堆栈中弹出,以免溢出。

打印路由基本上将每一列构建为Q-高度空格,然后是符号,然后是足够多的空格以命中Q + 1个总字符,然后我们转置并打印它们之间的换行符。

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

当我在进行此操作时,需要澄清的问题是要求每座山都印刷一次。这将需要重新考虑,并且可能需要更多的字符:/
paradigmsort

0

C 179

排除不必要的空格。

与edc65类似的策略。n*2考虑到/= 1和\= 0 ,我遍历了所有-bit二进制值。

我格式化包含n每个n*3字符换行符的单个字符串。由于该字符串包含1000个字符,因此通常在山峰后打印很多空白。(可以通过s[n*n*3]=0puts。之前添加来解决此问题。)无论如何,这使我能够puts在检查山峰是否符合规则后将其输出。

我将尝试将其转换为函数,然后减少为单个for循环。

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

输出(请注意右侧的大量空白)

$ ./a
4

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

0

Haskell,140字节

在多次尝试失败后,我最终完成了此Haskell实现。我很高兴能成为APL解决方案的2分之一!

打高尔夫球的解决方案:

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

取消评论并评论:

该程序以递归方式构建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

用法示例:

$ 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(演示

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

该程序采用一个整数参数尝试将0到2 ^(n-1)的所有二进制表示形式表示为山脉。它不会呈现无效的组合(例如:低于0级的组合)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.