Стек переполняется


47

(Вдохновлен этим вопросом )

Задача

Ваша задача - написать программу или функцию для печати ASCII-версии логотипа Stack Overflow в STDOUT.

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

Ваша программа должна принимать два входа, называемые здесь H и N. Высота стека "контейнер" (скобки) определяется как H. Количество элементов в стеке определяется как N. Если N> H, то стек будет «переполнен».

Ввод, вывод

H определит высоту контейнеров

Например:

Н = 1:

( )

Н = 2:

( )
( )

Н = 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

( )
( )
( )
( )
( )

Leaderboards

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# 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, только если происходит сбой, когда больше элементов, чем может вместить стек
Даниэль М.

Ответы:


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 байта

@ Редактировать: 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. Он отлично работает для меня. Не стесняйтесь вставить тест в Babel .
Патрик Робертс

@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

А затем заменить их правильными символами (возможно, пробелами) в конце.



4

JavaScript (ES6), 87 80 байт

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

Использует рекурсию для создания выходной строки снизу вверх.

РЕДАКТИРОВАТЬ : благодаря @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
Kimmax

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.

Правки

  • Мне удалось удалить регулярное выражение и вызов .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

Ява, 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;
}

Вы можете сэкономить байты с помощью лямбды - вы, вероятно, даже можете опустить лямбда-тело
Даниэль М.

2
Нужна ли мне какая-то специальная IDE для компиляции Ungoled Java- кода? : D
Kimmax

@ Киммакс .. Ой!
Khaled.K

3

Excel, 131 байт

Входные данные принимаются как кортеж, высота Hв A1, Nв B1. В ячейке, содержащей формулу, необходимо включить перенос текста. Предложите использовать моноширинный шрифт.

=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");}

Ungolfed :

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

Un-golfed:

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*>£š»

Можно определенно играть в гольф .. Не слишком доволен этим в его нынешнем виде.

Попробуйте онлайн или проверьте все тесты .

Объяснение:

-                # 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)˜»и это только половина дела.
Волшебная Осьминог Урна
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.