Przepełnienie stosu

47

(Zainspirowany tym pytaniem )

Cel

Twoim zadaniem jest napisanie programu lub funkcji do wydrukowania wersji ASCII logo Stack Overflow w STDOUT

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

Twój program powinien przyjmować dwa dane wejściowe, określane tutaj jako H i N. Wysokość „kontenera” stosu (nawiasy) jest określana przez H. Liczba elementów w stosie jest określana przez N. Jeśli N> H, stos „przepełni się”.

Wejście wyjście

H określi wysokość pojemników

Na przykład:

H = 1:

( )

H = 2:

( )
( )

H = 3:

( )
( )
( )

H zawsze będzie wynosić co najmniej 1

N określi liczbę przedmiotów na stosie. Wszystkie poniższe przykłady to H = 2:

N = 0

( )
( )

N = 1

( )
(-)

N = 2

(-)
(-)

N = 3

 \
(-)
(-)

N = 4

 \|
(-)
(-)

N = 5

 \|/
(-)
(-)

N = 6

 \|/
(-)-
(-)

N = 7

 \|/
(-)-
(-)-

N nigdy nie będzie więcej niż 2H+3(innymi słowy, stos nigdy nie przejdzie przez ziemię).

Zasady

  • Brak standardowych luk.
  • Twój program nie może generować żadnych błędów.
  • Wszystkie przypadki testowe muszą przejść pomyślnie.
  • Możesz wprowadzić H i N w dowolny sposób.
  • Poważnie wątpię, czy twój język ma do tego wbudowaną funkcję.
  • Każda linia może opcjonalnie mieć dodatkową spację na końcu. Pusta linia powyżej stosu, gdzie N <= H jest opcjonalna, podobnie jak końcowy znak nowej linii.
  • To jest , więc wygrywa najkrótszy kod w bajtach!

Przypadki testowe

Oprócz wszystkich przypadków testowych H = 2 z sekcji Wejście / Wyjście muszą przejść wszystkie następujące przypadki testowe:

H = 1, N = 1

(-)

H = 1, N = 5

 \|/
(-)-

H = 4, N = 7

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

H = 5, N = 0

( )
( )
( )
( )
( )

Liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie tabeli wyników:

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

Daniel M.
źródło
4
Czy mogę opublikować niekonkurencyjny program, który faktycznie przepełnia stos zamiast drukować logo?
dorukayhan
@dorukayhan Jeśli przepełnia się tylko, gdy n> h :)
Daniel M.
Mam na myśli, czy mogę utworzyć program, który ulega awarii po przepełnieniu stosu?
dorukayhan
@dorukayhan tylko wtedy, gdy ulega awarii, gdy jest więcej przedmiotów, niż może pomieścić stos
Daniel M.

Odpowiedzi:

14

Pyth, 43 41 40 bajtów

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

Wypróbuj online. Zestaw testowy.

Pierwsze przejście, szybkie i brudne. Dane wejściowe do STDIN as N\nH.

Wyjaśnienie

  1. Zapisz drugie wejście (wysokość) na J( JE) i odejmij je od pierwszego wejścia (liczba elementów). ( -QJE)
  2. Zapisz różnicę (liczbę przepełnionych przedmiotów) do K. ( K-QJE)
  3. Dodaj 1 do liczby. ( hK-QJE)
  4. Weź max(0, previous). Jest to wymagane, ponieważ liczby ujemne przerwałyby następny krok. ( g#0hK-QJE)
  5. Weź maksymalnie tyle liter z ciągu, " \|/"aby uzyskać pierwszą linię i wydrukować. ( <" \|/"g#0hK-QJE)
  6. Pętla Nnad range(0, J). ( VJ) Dla każdego Nwydruku konkatenacja następujących elementów: ( s[)
    • "("( \()
    • " "jeśli N+1na stosie ( <N_K) są przynajmniej wolne miejsca, w "-"przeciwnym razie. ( ?<N_Kd\-)
    • ")"( \))
    • "-"jeśli N+4na stosie ( <N-K3) znajdują się przynajmniej przepełnione elementy, w ""przeciwnym razie. ( *<N-K3\-)
PurkkaKoodari
źródło
13

JavaScript (ES6), 105 102 bajtów

@Edit: Zapisano 3 bajty dzięki @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>

Neil
źródło
Można wymienić substringz substrzaoszczędzić 3 bajty, i wymienić i+n<h?' ':'-'z '- '[i+n<h]aby zapisać 2 bajty i wymienić i+h+3<n?'-':''z ' -'[i+h+3<n]zaoszczędzić 1 bajt. To sprawi, że nie będziesz mieć 100 lat
Patrick Roberts
@PatrickRoberts Nie pamiętam, czy substrzignorowałem negatywne indeksy dolne, ale nie mogę użyć innych wskazówek, ponieważ indeksy łańcuchowe są łańcuchami, więc booleany nie są wystarczająco dobre.
Neil
bzdury, zapomniałem o tym, dobra uwaga
Patrick Roberts,
Naprawdę sprytne użycie otagowanego szablonu w celu uratowania tych dwóch znaków!
Benjamin Gruenbaum
@BenjaminGruenbaum co to jest „otagowany szablon”?
Patrick Roberts,
12

JavaScript (ES6), 126 122 112 bajtów

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)

Test

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

Test alternatywny (jeśli twoja przeglądarka nie obsługuje ES6)

Zobacz test na Babeljs.io i zaznacz „oceń”.

Ciekawe alternatywne podejście przy 136 bajtach

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

To przenosi ilości powtórzeń do ciągu szablonu i używa wyrażenia regularnego i zamienia, aby wstrzyknąć powtarzające się grupy. Niestety podpis .replace()jest po prostu za długi.

Patrick Roberts
źródło
Pojawia się błąd ...?
Addison Crump
1
@VTCAKAVSMoACE Twoja przeglądarka musi obsługiwać składnię ES6. Działa dla mnie dobrze. Zapraszam do wklejenia test na Babel .
Patrick Roberts,
@VTCAKAVSMoACE Chrome 52 (w wersji beta od czerwca 2016 r.) Obsługuje wszystkie modele ES6 i ES7, z wyjątkiem optymalizacji połączeń ogonowych i ładowania modułów.
gcampbell
10

C ++ 14 (funkcja lambda), 196

Zaoszczędzono 1 bajt dzięki Quentin.

Zaoszczędził 2 bajty dzięki Adamowi Martinowi.

#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';}

Sama funkcja zajmuje 157 bajtów.

Zobacz to w akcji tutaj .

Wersja bez golfa:

[](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';
    }
};
sklepienie
źródło
2
Nie widzę sensu w włączaniu includes i using namespace std;liczeniu bajtów, chyba że twoja odpowiedź jest kompletnym programem (co nie jest).
Alexander Revo
9

CJam, 57 bajtów

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

Sprawdź to tutaj.

Zdecydowanie przydałaby się poprawa. Chodzi o zbudowanie siatki, w której -\|/-komórki zostaną zastąpione kolejnymi liczbami całkowitymi, np

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

A następnie zamień je na prawidłowe znaki (potencjalnie spacje) na końcu.

Martin Ender
źródło
6

Python 2, 101 100 98 bajtów

def f(h,n):
 print" \|/"[:max(0,n-h+1)]
 for i in range(h):print("(-)","( )")[h-i>n]+"-"*(n>i+h+3)
Chuck Morris
źródło
Przestrzenie po printsą niepotrzebne
Cyoce
@Cyoce Dzięki, to oszczędza 2 znaki.
Chuck Morris,
4

JavaScript (ES6), 87 80 bajtów

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

Używa rekurencji do utworzenia ciągu wyjściowego od dołu do góry.

EDYCJA : Dzięki @Neil za golenie 7 bajtów z 87 bajtów

Oryginał

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

Fragment testowy:

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>

George Reith
źródło
dzięki za miły fragment! Powinien dać dodatkowy punkt: P
Kimmax
1
@Kimmax Dzięki, kolego, nikt nie chce się bawić w konsolę
George Reith,
Przynajmniej kiedy próbowałem, stos był dość duży i miałby tylko 78 bajtów ze zwykłą rekurencją.
Neil
Snippet Console pokazuje SyntaxErrormi.
ArtOfCode
1
@ArtOfCode Konieczność korzystania z przeglądarki zgodnej z ES6
George Reith
3

JavaScript (ES6), 149 139 137 bajtów

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

Podobał mi się pomysł MartinEndera dotyczący indeksowania -\|/znaków i chciałem zobaczyć, jak sobie poradzi w ES6. Najwyraźniej nie zrobiłem tego zbyt dobrze. Próbuję dowiedzieć się, czy można to poprawić za pomocą for...of.

Edycje

  • Udało mi się usunąć wyrażenie regularne i wywołanie .replace, przenosząc indeksowanie bezpośrednio do g().
  • Przypadkowo policzyłem f=w drugim bajcie

Test

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

Patrick Roberts
źródło
3

Java, 186 177 bajtów

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 spróbuj online

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;
}
Khaled.K
źródło
Możesz zaoszczędzić bajty za pomocą lambda
Daniel M.
2
Czy potrzebuję niestandardowego środowiska IDE do kompilacji kodu Ungoled Java ? : D
Kimmax
@Kimmax .. D'oh!
Khaled.K
3

Excel, 131 bajtów

Wejście traktowane jako krotki, wysokość Hw A1, Nw B1. Formuła zawierająca komórkę musi mieć włączone zawijanie tekstu. Zaproponuj użycie czcionki z odstępem mono.

=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))
Wernisch
źródło
Cudowne rozwiązanie! Należy dodać, że pobiera to dane wejściowe jako 2-krotkę z A1i B1dodaje prostą notatkę, że wymaga to, aby komórka wywołująca miała opcję zawijania tekstu, aby była prawdziwa. Być może również, aby uzyskać prawidłowe wyrównanie, powinna mieć czcionkę o jednolitych odstępach, taką jak Courier New lub Lucidia Console
Taylor Scott
1
Dzięki @TaylorScott. Zaktualizowana odpowiedź z twoimi sugestiami.
Wernisch
2

C ++ 11, 155 148 145 bajtów

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

Nie golfowany :

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

Zastosowanie :

#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);
}
Alexander Revo
źródło
137 bajtów
pułapkat
1

Python 3, 134 121 118 111 bajtów

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

Przetestuj tutaj: https://repl.it/CYL1/0

Bez golfa:

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

Chciałbym dodać przepełnienie boczne do opisu listy, ale nie mogłem go wcisnąć, więc musiałem skorzystać z pętli while. Zapisano 13 bajtów!

atlasolog
źródło
Wyjście jest wyłączone, prawdopodobnie musisz zmienić, '\|/'[:max(0,n-h)]aby było podobne do rozwiązania Python 2.
awaria autobusu
1

Pip , 50 bajtów

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

Wypróbuj online!

Ugh, to za długo ... nie wiem już, jak to skrócić. Tym razem cykliczne indeksowanie, które zwykle jest pomocne, kosztuje dodatkowe bajty.

DLosc
źródło
1

PowerShell , 109 108 104 bajtów

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

Wypróbuj online!

Wiele straciłem na kosztownym indeksowaniu, ale nadal przyzwoitym. Nie jestem jednak pewien, czy moja matematyka indeksu jest optymalna. Ukryj logikę z innych odpowiedzi, aby zapisać bajt. Pamiętano również o pierwszeństwie przed wstawieniem niektórych parenów dla -4 bajtów.

Veskah
źródło
0

05AB1E , 45 bajtów

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

Zdecydowanie można grać w golfa .. Niezbyt szczęśliwy z tego powodu w obecnej formie tbh.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

-                # 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(-)"
Kevin Cruijssen
źródło
Jeśli to sprawi, że poczujesz się lepiej, oto co miałem: LR'(ì')«¹x‚3+¬UŸ¦ζJ¹XŸJ¦1úr)˜»i to tylko w połowie zrobione.
Magic Octopus Urn