Стек переповнення


47

(Натхненний цим питанням )

Об'єктивна

Ваше завдання - написати програму або функцію для друку ASCII версії логотипу Переповнення стека до STDOUT

 \|/
(-)
(-)
(-)
(-)

Ваша програма повинна приймати два входи, згадані тут H і N. Висота стека "контейнер" (круглі дужки) визначається H. Кількість елементів у стеці визначається N. Якщо N> H, стек "переповниться".

Введення-виведення

Н визначатиме висоту контейнерів

Наприклад:

H = 1:

( )

H = 2:

( )
( )

H = 3:

( )
( )
( )

H завжди буде принаймні 1

N визначатиме, скільки предметів у стеку. Наступні приклади - H = 2:

N = 0

( )
( )

N = 1

( )
(-)

N = 2

(-)
(-)

N = 3

 \
(-)
(-)

N = 4

 \|
(-)
(-)

N = 5

 \|/
(-)
(-)

N = 6

 \|/
(-)-
(-)

N = 7

 \|/
(-)-
(-)-

N ніколи не буде більше 2H+3(Іншими словами, стек ніколи не пройде через землю).

Правила

  • Немає стандартних бійниць.
  • Ваша програма не повинна створювати помилок.
  • Усі тестові справи повинні пройти.
  • Ви можете вводити H і N будь-яким способом.
  • Я серйозно сумніваюся, що ваша мова має для цього вбудований.
  • Кожен рядок може додатково мати додаткове місце в кінці. Порожній рядок над стеком, де N <= H необов’язковий, як і останній новий рядок.
  • Це , тому найкоротший код у байтах виграє!

Випробування

На додаток до всіх тестових випадків H = 2 з розділу Введення / Виведення, всі наступні тестові випадки повинні пройти:

H = 1, N = 1

(-)

H = 1, N = 5

 \|/
(-)-

H = 4, N = 7

 \|/
(-)
(-)
(-)
(-)

H = 5, N = 0

( )
( )
( )
( )
( )

Табло лідерів

Ось фрагмент стека для створення як звичайного табло, так і огляду переможців за мовою.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат становить суму двох файлів або ви хочете окремо перерахувати штрафні санкції для перекладача), переконайтесь, що фактичний бал є останнім номером у заголовку:

# Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке потім з’явиться у фрагменті таблиць лідерів:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


4
Чи можу я опублікувати неконкурентну програму, яка фактично переповнює стек замість друку логотипу?
снідакайхан

@dorukayhan Якщо вона переповнюється лише тоді, коли n> h :)
Даніель М.

Я маю на увазі, чи можу я зробити програму, яка вибивається із переповнення стека?
снідакайхан

@dorukayhan, лише якщо він виходить з ладу, коли в ньому є більше предметів, ніж вміщує стек
Daniel M.

Відповіді:


14

Pyth, 43 41 40 байт

<" \|/"g#0hK-QJEVJs[\(?<N_Kd\-\)*<N-K3\-

Спробуйте в Інтернеті. Тестовий набір.

Перший прохід, швидкий і брудний. Вхід до STDIN як N\nH.

Пояснення

  1. Збережіть другий вхід (висоту) до J( JE) і відніміть його від першого вводу (кількість елементів). ( -QJE)
  2. Збережіть різницю (кількість елементів, що переповнюються) до K. ( K-QJE)
  3. Додайте 1 до числа. ( hK-QJE)
  4. Беріть max(0, previous). Це потрібно, оскільки негативні цифри порушать наступний крок. ( g#0hK-QJE)
  5. Візьміть максимум стільки літер з рядка, " \|/"щоб отримати перший рядок та друкувати. ( <" \|/"g#0hK-QJE)
  6. Петля Nзакінчиться range(0, J). ( VJ) Для кожного Nдруку з'єднання наступного: ( s[)
    • "("( \()
    • " "якщо N+1в стеку є принаймні вільні пробіли ( <N_K), "-"інакше. ( ?<N_Kd\-)
    • ")"( \))
    • "-"якщо N+4в стеку є хоча б переповнені шматки ( <N-K3), ""інакше. ( *<N-K3\-)

13

JavaScript (ES6), 105 102 байт

@Edit: Збережено 3 байти завдяки @PatrickRoberts.

f=
(n,h)=>` \\|/`.substr(0,n+1-h)+[...Array(h)].map((_,i)=>`
(${i+n<h?` `:`-`})${i+h+3<n?`-`:``}`).join``
;
<div oninput=o.textContent=f(+n.value,+h.value)>n<input id=n type=number min=0 value=0>h<input id=h type=number min=0 value=0><pre id=o>


Ви можете замінити substringз , substrщоб зберегти 3 байта, і замінити i+n<h?' ':'-'з , '- '[i+n<h]щоб зберегти 2 байти і замінити i+h+3<n?'-':''з , ' -'[i+h+3<n]щоб зберегти 1 байт. Це отримає тебе до 100 років
Патрік Робертс

@PatrickRoberts Я не міг згадати, substrігнорували негативні підписки чи ні, але я не можу використовувати інші ваші поради, тому що рядкові підписки - це рядки, тому булеви недостатньо хороші.
Ніл

лайно Я забув про це, хороший момент
Патрік Робертс

Дійсно розумне використання позначеного шаблону, щоб зберегти ці два символи!
Бенджамін Груенбаум

@BenjaminGruenbaum що таке "позначений шаблон"?
Патрік Робертс

12

JavaScript (ES6), 126 122 112 байт

h=>n=>' \\|/'.substr(0,(o=n-h)+1)+`
( )`[r='repeat'](0>-o?0:-o)+`
(-)-`[r](o=0>o-3?0:o-3)+`
(-)`[r](n<h-o?n:h-o)

Тест

f=h=>n=>' \\|/'.substr(0,(o=n-h)+1)+`
( )`[r='repeat'](0>-o?0:-o)+`
(-)-`[r](o=0>o-3?0:o-3)+`
(-)`[r](n<h-o?n:h-o)
document.write(`<pre>${[[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[1,1],[1,5],[4,7],[5,0]].map(a=>f(a.shift())(a.shift())).join`

`}</pre>`)

Альтернативний тест (якщо ваш браузер не підтримує ES6)

Дивіться тест на Babeljs.io і поставте галочку "оцінити".

Цікавий альтернативний підхід у 136 байт

h=>n=>' \\|/'.substr(0,(o=n-h)+1)+`
( )${0>-o?0:-o}
(-)-${o=0>o-3?0:o-3}
(-)${n<h-o?n:h-o}`.replace(/(\n.*)(\d+)/g,(_,s,r)=>s.repeat(r))

Це переміщує кількість повторень у рядок шаблону та використовує повторне вираження та заміну для введення повторюваних груп. На жаль, підпис за .replace()надто довгий.


Я отримую помилку ...?
Аддісон Кримп

1
@VTCAKAVSMoACE Ваш браузер повинен підтримувати синтаксис ES6. Це прекрасно працює для мене. Сміливо вставляйте тест у Вавілон .
Патрік Робертс

@VTCAKAVSMoACE Chrome 52 (у бета-версії станом на червень 2016 року) підтримує всі ES6 та ES7, крім оптимізації хвостових викликів та завантаження модуля.
gcampbell

10

C ++ 14 (лямбда-функція), 196

Збережено 1 байт завдяки Квентіну.

Збережено 2 байти завдяки Адаму Мартіну.

#include<iostream>
using namespace std;[](int h,int n){auto s=" \\|/( ) (-) (-)-"s;int t=max(min(n-h,3),0);n-=t;cout<<s.substr(0,t+1)+'\n';for(;h;h--)n-=t=n>h?2:h<=n,cout<<s.substr(4+4*t,4)+'\n';}

Сама функція займає 157 байт.

Дивіться це в дії тут .

Безгольова версія:

[](int h, int n) {
    auto s = " \\|/( ) (-) (-)-"s;
    int t = max(min(n - h, 3), 0);
    n -= t;
    cout << s.substr(0, t + 1) + '\n';
    for(; h; h--) {
        if (n > h) t = 2;
        else if (h > n) t = 0;
        else t = 1;
        n -= t;
        cout << s.substr(4 + 4 * t, 4) + '\n';
    }
};

2
Я не бачу сенсу включати includes і using namespace std;в кількість байтів, якщо ваша відповідь не є повною програмою (чого це не так).
Олександр Рево

9

CJam, 57 байт

Sri:X'(*+X),W%X)X')*+X),X))f+]zN*X5*,X'-*_"\|/"\++ri<S+er

Перевірте це тут.

Можливо, певне вдосконалення. Ідея полягає у створенні сітки, де -\|/-комірки замінюються послідовними цілими числами, наприклад

 345
(2)6
(1)7
(0)8

А потім замінити їх правильними символами (потенційно пробілами) наприкінці.


6

Python 2, 101 100 98 байт

def f(h,n):
 print" \|/"[:max(0,n-h+1)]
 for i in range(h):print("(-)","( )")[h-i>n]+"-"*(n>i+h+3)

Пробіли після printцього непотрібні
Cyoce

@Cyoce Спасибі, що економить 2 символи.
Чак Морріс

4

JavaScript (ES6), 87 80 байт

F=(h,n)=>h?F(h-1,n-1)+`
(${n>0?'-':' '})${n>2*h+2?'-':''}`:' \\|/'.substr(0,n+1)

Використовує рекурсію для створення вихідного рядка знизу вгору.

EDIT : Дякуємо @Neil за те, що голили 7 байт із 87 байт

Оригінал

(h,n)=>(E=s=>h--?E(`
(${n>0?'-':' '})${--n>2*h+3?'-':''}`+s):` \\|/`.substr(0,n+1)+s)``

Фрагмент тесту:

F=(h,n)=>h?F(h-1,n-1)+`
(${n>0?'-':' '})${n>2*h+2?'-':''}`:' \\|/'.substr(0,n+1)


h.oninput = n.oninput = () => output.innerHTML = F(+h.value, +n.value);
<label>h <input type="number" min="0" value="0" id="h" /></label>
<label>n <input type="number" min="0" value="0" id="n" /></label>
<hr />
<pre id="output"></pre>


дякую за приємний фрагмент! Слід надати додатковий бал: P
Кіммакс

1
@Kimmax Спасибі, нікому не хочеться возитися з консоллю
Джордж Рейт

Принаймні, коли я спробував, стек був досить великий, і це було б лише 78 байт із звичайною рекурсією.
Ніл

На консолі фрагмента показано SyntaxErrorдля мене.
ArtOfCode

1
@ArtOfCode Потрібно використовувати браузер, сумісний з ES6
Джордж Рейт

3

JavaScript (ES6), 149 139 137 байт

h=>n=>` ${[(g=(j,m=1)=>` -\\|/`[(j<n)*m])(h,2),g(h+1,3),g(h+2,4)].join``}${[...Array(h)].map((_,i)=>`
(${g(h-i-1)})${g(h+i+3)}`).join``}`

Мені сподобалась ідея @ MartinEnder про індексацію -\|/символів, і я хотів побачити, як це пройде в ES6. Мабуть, я не так добре вчинив. Спробуємо з'ясувати, чи можна це покращити за допомогою for...of.

Правки

  • Мені вдалося видалити regexp та виклик до .replace, перемістивши індексацію безпосередньо g()натомість.
  • Я випадково порахував підрахунок f=другого байта

Тест

f=h=>n=>` ${[(g=(j,m=1)=>` -\\|/`[(j<n)*m])(h,2),g(h+1,3),g(h+2,4)].join``}${[...Array(h)].map((_,i)=>`
(${g(h-i-1)})${g(h+i+3)}`).join``}`
document.write(`<pre>${[[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[1,1],[1,5],[4,7],[5,0]].map(a=>f(a.shift())(a.shift())).join`

`}</pre>`)


3

Java, 186 177 байт

void f(int h,int n){for(int i=0;i<h+1;i++)System.out.print((i>0?"(":" ")+(i>0?n>h-i-2?"-":" ":n>h+0?"\\":" ")+(i>0?")":n>h+1?"|":" ")+(i>0?n>h+2+i?"-":" ":n>h+2?"/":" ")+"\n");}

Ungolfed спробуйте онлайн

String f(int h, int n)
{
    String s=" ";
    s+=n>h+0?"\\":" ";
    s+=n>h+1? "|":" ";
    s+=n>h+2? "/":" ";
    s+="\n";

    for(int i=0; i<h; i++)
    {
        s+="(";
        s+=n>h-i-1?"-":" ";
        s+=")";
        s+=n>h+3+i?"-":" ";
        s+="\n";
    }

    return s;
}

Ви можете зберегти байти, використовуючи лямбда
Daniel M.

2
Чи потрібен мені спеціальний IDE для компіляції Ungoled Java- коду? : D
Кіммакс

@Kimmax .. D'oh!
Khaled.K

3

Excel, 131 байт

Вхід, прийнятий як кортеж, Висота Hв A1, Nв B1. Формула, що містить комірок, має ввімкнути обтікання тексту. Запропонуйте використовувати шрифт Mono-proced.

=LEFT(" \|/",MAX(0,B1-A1+1))&"
"&REPT("(-)-
",MAX(0,B1-A1-3))&REPT("( )
",MAX(0,A1-B1))&REPT("(-)
",A1-MAX(0,B1-A1-3)-MAX(0,A1-B1))

Чудове рішення! Слід додати , що взяти вхід в якості 2-кортежу з A1і B1додати просту записку , що це вимагає викликають осередків , щоб текст варіанту обруча , щоб бути правдою. Також, щоб отримати правильне вирівнювання, він повинен мати монорозміщений шрифт, такий як Courier New або Lucidia Console
Taylor Scott

1
Дякую @TaylorScott Оновлена ​​відповідь із вашими пропозиціями.
Верніш

2

C ++ 11, 155 148 145 байт

void f(int h,int n){cout<<string{" \\|/",max(min(3,n-h),0)+1}<<'\n';for(int i=0;i<h;++i)cout<<(h-i<=n?"(-)":"( )")<<(i<max(n-h-3,0)?"-\n":"\n");}

Безголівки :

void f(int h,int n)
{
  cout << string{" \\|/", max(min(3, n-h), 0) + 1} << '\n';
  for(int i=0; i<h; ++i)
    cout << (h-i <= n ? "(-)" : "( )") << (i < max(n-h-3,0) ? "-\n" : "\n");
}

Використання :

#include <iostream>
#include <string>
using namespace std;

void f(int h,int n){cout<<string{" \\|/",max(min(3,n-h),0)+1}<<'\n';for(int i=0;i<h;++i)cout<<(h-i<=n?"(-)":"( )")<<(i<max(n-h-3,0)?"-\n":"\n");}

int main()
{
  int h,n;
  cin >> h >> n;
  f(h, n);
}


1

Python 3, 134 121 118 111 байт

def f(h,n):print('\|/'[:max(0,n-h)]+'\n'+'\n'.join('(-)-'if h<n-x-3else('(-)','( )')[x+n<h] for x in range(h)))

Тестуйте його тут: https://repl.it/CYL1/0

Без гольфу:

def f(h,n):
  top=['\|/'[:max(0,n-h)]]
  stack=['( )'if x+n<h else'(-)'for x in range(h)]
  overflow=top+stack
  v=n-3
  while v>h:
      overflow[h-v]+='-' #add side overflow
      v-=1

  print('\n'.join(overflow))

Мені б хотілося, щоб бічний перелив додав до розуміння списку, але я не зміг його видавити, тому мені довелося перейти до циклу while. Збережено 13 байт!


Вихідний сигнал вимкнено, вам, мабуть, потрібно змінити так, '\|/'[:max(0,n-h)]щоб бути схожим на рішення Python 2.
busfault


1

Піп , 50 байт

Ps.(0Xa."\|/")@<bDC0Fi,aP"()"WV"- "@[b<a-ib<a+4+i]

Спробуйте в Інтернеті!

Тьфу, це занадто довго ... хоч не знаю, як її скоротити. Циклічна індексація, яка зазвичай корисна, цього разу коштує зайвих байт.


1

PowerShell , 109 108 104 байт

param($n,$h)-join" \|/"[0..(($d=$n-$h),0)[$d-lt0]]
1..$h|%{("( )","(-)")[$h-$_-lt$n]+"-"*($h+$_+2-lt$n)}

Спробуйте в Інтернеті!

Багато втратили на дорогому індексуванні, але все-таки гідному. Я не впевнений, що моя індексна математика оптимальна. Вкрасти трохи логіки з інших відповідей, щоб зберегти байт. Також пам’ятали пріоритет перед поп-файлом на -4 байти.


0

05AB1E , 45 байт

-U…( )¸¹иε²N›ið'-:]RεX4-N@i'-«]" \|/"XdX*>£š»

Однозначно можна пограти в гольф .. Не надто задоволений цим у своєму нинішньому вигляді tbh.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

-                # Subtract the 2nd (implicit) input `n` from the 1st (implicit) input `h`
                 #  i.e. `h`=3, `n`=8 → 5
 U               # Pop and store it in variable `X`
…( )             # Push string "( )"
    ¸            # Wrap it into a list: ["( )"]
     ¹и          # Repeat it the first input (`h`) amount of times
                 #  i.e. 3 → ["( )","( )","( )"]
ε                # Map each to:
 ²Ni            #  If the second input `n` is larger than the map-index N:
                 #    i.e. `n`=8 >= N=0 → 1 (truthy)
     ð'-:       '#   Replace the space with a "-"
                 #    i.e. "( )" → "(-)"
]                # Close both the if and map
 R               # Reverse the list
ε                # Map each to:
 X4-N@i          #  If `X` minus 4 is larger than or equal to the map-index N:
                 #     i.e. `X`=5 and N=0 → 5-4 >= 0 → 1 (truthy)
                 #     i.e. `X`=5 and N=2 → 5-4 >= 2 → 0 (falsey)
       '-«      '#   Append a "-"
]                # Close both the if and map
 " \|/"          # Push String " \|/"
       Xd        # Check if `X` is 0 or positive (0 if negative, 1 if 0 or positive)
                 #  i.e. `X`=5 → 1 (truthy)
         X*      # Multiply it by `X`
                 #  i.e. 1 * 5 → 5
           >     # Increase it by 1
                 #  i.e. 5 → 6
            £    # Take that many character of the string " \|/"
                 #  i.e. 6 → " \|/"
             š   # Prepend it to the list
                 #  i.e. ["(-)-","(-)-","(-)"] and " \|/" → [" \|/","(-)-","(-)-","(-)"]
              »  # Join the list by newlines (and output implicitly)
                 #  i.e. [" \|/","(-)-","(-)-","(-)"] → " \|/\n(-)-\n(-)-\n(-)"

Якщо ви відчуваєте себе краще, ось що я мав: LR'(ì')«¹x‚3+¬UŸ¦ζJ¹XŸJ¦1úr)˜»і це лише наполовину.
Magic Octopus Urn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.