Намалюйте діапазон гірських хребтів


16

Натхненна плиткою доміно в Фібоначчі , ця проблема полягає у створенні мистецтва ASCII, що представляє ще одну відому комбінаторну послідовність.

Гори діаграма п кроків є малюнком гірського масиву, використовуючи саме п «/» і п «\» символів, таким чином, що символи накидати безперервні криві , яка ніколи не опускається нижче своєї первісної «висоти». Наприклад,

   /\/\
/\/    \

і

   /\
/\/  \/\

обидві 4-крокові гірські діаграми, але

/\  /\/\
  \/

не.

Вхідні дані

Програма повинна приймати ціле число n від stdin або як параметр функції.

Вихідні дані

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

Як і в проблемі плитки доміно, ви можете використовувати будь-який пробіл. Сюди входять додаткові нові рядки до або після друкованого виводу.

Приклад

Деякі дійсні вибірки для n = 3:

Дійсний вихід A:

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

Дійсний вихід B:

   /\
/\/  \

 /\/\
/    \

/\/\/\   

  /\
 /  \
/    \

 /\
/  \/\

Дійсний вихід C:

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

Це код гольфу; виграє найкоротша програма (у байтах).


Коли ви говорите "Ви можете вирішити, чи будуть різні діаграми виводитись горизонтально, вертикально тощо", чи можуть самі гірські хребти бути збоку?
xnor

Самі гірські хребти не повинні бути збоку. Порожнє небо між вершинами додає виклику, я думаю.
Метт Нунан

Чи можуть деякі діапазони з’являтися не один раз?
гордий haskeller

@MattNoonan Ви маєте рацію, друкувати гірські хребти горизонтально, безумовно, було складним.
xnor

@ гордий-haskeller Це повинен бути один раз кожен.
Метт Нунан

Відповіді:


10

Пітон 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 за допомогу та вдосконалення.


Вам потрібно буде використовувати ' 'замість цього, " "якщо ви хочете користуватися циклом exec. :) До речі, вам не потрібно уникати нахилу.
flornquake

@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

@flornquake Нічого не відчуваю себе дурним, я змінив одну пару цитат, а не іншу. Спасибі!
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

Пітон, 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

Так само, як і моя відповідь за плиткою Доміно до Фібоначчі, я вивчаю всі послідовності n + n бітів, 1 позначення '/' та 0 маркування '' . Під час побудови шаблону ascii я перевіряю рівновагу - однакові числа 0 і 1, і ніколи не опускаюся нижче початкової базової лінії - і виводжу те, що підкоряється правилам.

Вихід зроблений з "настороженості", що є стандартним для кодового гольфу JS, але досить дратує і, можливо, суперечить правилам. За допомогою 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

С, 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

 /\
/  \/\/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
/\/  \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \
/    \/\                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

     /\
/\/\/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\  /\
/  \/  \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\/\
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

 /\/\/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\
 /  \/\
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
   /  \
/\/    \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

    /\
 /\/  \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

  /\/\
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

   /\
  /  \
 /    \
/      \                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.