Нарисуйте ряд горных хребтов

16

Вдохновленная тайлингом Фибоначчи , эта проблема заключается в создании искусства ASCII, представляющего другую известную комбинаторную последовательность.

Горы диаграмма п шагов является рисунком горного массива, используя именно п «/» и п «\» символов, таким образом, что символы набросать непрерывные кривые , которая никогда не опускается ниже своей первоначальной «высоты». Например,

   /\/\
/\/    \

и

   /\
/\/  \/\

обе 4-ступенчатые горные диаграммы, но

/\  /\/\
  \/

не является.

вход

Программа должна принимать целое число n из стандартного ввода или в качестве параметра функции.

Выход

Распечатайте все n- ступенчатые горные диаграммы на стандартный вывод. Диаграммы могут быть в любом порядке, но должны быть разделены пробелами. Вы можете решить, будут ли разные диаграммы выводиться по горизонтали, вертикали и т. Д.

Как и в случае с мозаикой домино, вы можете использовать любой пробел по своему усмотрению. Это включает в себя дополнительные переводы строки до или после вывода на печать.

пример

Некоторые примеры действительных выходов для n = 3:

Допустимый выход A:

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

Допустимый выход B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

Допустимый выход C:

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

Это код гольф; самая короткая программа (в байтах) побеждает.

Мэтт Нунан
источник
Когда вы говорите: «Вы можете решить, будут ли разные диаграммы выводиться по горизонтали, вертикали и т. Д.», Могут ли сами горные хребты быть вбок?
xnor
Сами горные хребты не должны быть боком. Я думаю, что пустое небо между вершинами усугубляет проблему.
Мэтт Нунан
Могут ли некоторые диапазоны появляться более одного раза?
гордый haskeller
@MattNoonan Вы правы, печатать горные хребты по горизонтали было определенно сложно.
xnor
@ гордый-haskeller Это должно быть один раз каждый.
Мэтт Нунан

Ответы:

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и/2 в execцикле.

Мы храним бегущий горный хребет сбоку в транспонированном списке строк L. Каждый раз, мы генерируем новую строку пробелов, заменяем одну пробел в новой строке/ или в \зависимости от того, произошло ли движение вверх или вниз.

Индекс этого пространства - cпробелы с конца, где c- высота бега. Если сделать это спереди, горы перевернутся с ног на голову. Далее мы сдвигаем его, bчтобы выровнять движения вверх и вниз, получая[b-c] . Начиная cс 1, а не с 0, исправляется ошибка «один за другим».

Чтобы исключить случаи, когда cпровалы ниже начального значения 1, когда это происходит, мы устанавливаем iзначение 0, которое заставляет все дальнейшие движения быть нисходящими, делая их cболее отрицательными. Затем, когда мы проверяем, cзакончился ли он при 1, мы также проверяем, cопустился ли когда-либо ниже этого уровня. Мы только printгорный хребет, еслиc есть 1.

Для печати мы делаем zip(*L) чтобы транспонировать диапазон от вертикального до горизонтального, и печатать каждую объединенную строку. В этом ответе много трудностей, связанных с тем, что Python рассматривает строки как неизменяемые, поэтому мы работали с ними как со списками символов и только объединяли их в строки для печати.

Спасибо @flornquake за помощь и улучшения.

XNOR
источник
Вам нужно использовать ' 'вместо, " "если вы хотите использовать цикл exec. :) Кстати, вам не нужно избегать обратной косой черты.
землетрясение
@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);")
xnor
Я имел в виду, что вам нужно написать exec("b=i%2;c+=2*b-1;L+=[[' ']*N];L[-1][b-c]='\\/'[b];i=i//2*(c>0);"), то есть внутренние кавычки должны отличаться от внешних.
землетрясение
@flornquake Wow я чувствую себя глупо, я изменил одну пару цитат, но не другую. Благодарность!
xnor
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×⍵: получить битовое поле для каждого числа от 0до 2^⍵.
  • 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]/⍨¨: найдите правильный символ для каждого столбца и скопируйте его по списку для этого столбца.
    • ⍉↑: превратить результат в матрицу и поместить его правой стороной вверх
Мэринус
источник
Хорошо, горизонтальный!
Мэтт Нунан
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

Так же, как и мой ответ на Tiling Fibonacci Domino, я проверяю все последовательности из 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)

Выход

   /\
  /  \
 /    \
/      \ 

  /\/\
 /    \
/      \ 

    /\
 /\/  \
/      \ 

    /\
   /  \
/\/    \ 

  /\
 /  \/\
/      \ 

 /\/\/\
/      \ 

   /\/\
/\/    \ 

 /\  /\
/  \/  \ 

     /\
/\/\/  \ 

  /\
 /  \
/    \/\ 

 /\/\
/    \/\ 

   /\
/\/  \/\ 

 /\
/  \/\/\ 

/\/\/\/\ 
edc65
источник
Любопытно, есть ли какая-то конкретная причина, которую вы пишете, -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
источник
Пока я работал над этим, вопрос прояснился и потребовал, чтобы горы были напечатаны по одному разу. Это потребует некоторого переосмысления и, возможно, большего количества символов: /
paradigmsort
0

С, 179

исключая ненужные пробелы.

Стратегия, аналогичная edc65. Я пробегаю все n*2двоичные значения -бит, учитывая /= 1 и \= 0.

Я форматирую одну строку, содержащую nразрывы строк для каждого n*3символа. Как написано, строка содержит 1000 символов, поэтому после горы обычно печатается много пробелов. (Это можно исправить, добавив s[n*n*3]=0перед puts.) В любом случае, это позволяет мне выводить целую гору синглом 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

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
Уровень реки St
источник
0

Haskell, 140 байт

После того, как несколько попыток оказались не очень удачными, я закончил с реализацией на Haskell. Я счастлив просто быть в 2 раза от решения APL!

Гольф решение:

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

Кристиан Лупаску
источник