Tworzenie interpretera HQ9 +

31

Celem tego kodu golfowego jest stworzenie interpretera dla języka programowania HQ9 +
W tym języku programowania dostępne są 4 polecenia:

  • H - drukuje „Witaj, świecie!”
  • Q - drukuje kod źródłowy programu
  • 9 - drukuje tekst piosenki „99 butelek piwa”
  • + - zwiększa akumulator

Zasady:

  1. Ponieważ akumulator nie jest zdefiniowany, możesz zignorować polecenie +
  2. Twój program powinien poprosić o podanie danych wejściowych (będzie to kod źródłowy) lub kod źródłowy zostanie odczytany z pliku
  3. Nie wolno umieszczać tekstu „99 butelek piwa” w pliku ani czytać tekstu z pliku
  4. Nie możesz używać algorytmu kompresji, takiego jak GZip lub BZip do kompresji tekstu piosenki: musisz stworzyć swój własny algorytm kompresji. Nie musi to być skomplikowany algorytm, ale spróbuj skompresować tekst tak bardzo, jak to możliwe (pamiętaj: to jest golf-golf, kod z najmniejszą liczbą bajtów wygrywa)
  5. Jeśli kod źródłowy zawiera znak inny niż H , Q , 9 lub + , wówczas przed uruchomieniem jakichkolwiek poleceń wypisz „Kod źródłowy zawiera nieprawidłowe znaki” ! Oznacza to, że jeśli H1na przykład jest kod źródłowy , nie należy generować danych wyjściowychHello, world! przed wypisaniem Source code contains invalid characters. Nie, natychmiast wyjścieSource code contains invalid characters
  6. Jeśli twój tłumacz akceptuje zarówno wielkie, jak i małe litery, to dostajesz -8 do liczby znaków

Powodzenia!

ProgramFOX
źródło
3
Zasada 4 nie ma sensu, kiedy „dlaczego miałby tego zabraniać ?!” poziom; reguła 5 nie ma sensu w „co on ma na myśli ?!” poziom.
Peter Taylor
4
Dlaczego reguła 5 nie ma sensu?
Mike C
Myślę, że lepiej byłoby po prostu wymagać, aby używała tylko wielkich liter, zamiast arbitralnie mówić, że masz wolne 8 znaków, jeśli akceptuje jedno z nich. 8 może, ale nie musi, obejmować w zależności od języka.
Mike C
10
Reguła 5 nie ma sensu, ponieważ łamie specyfikację HQ9 +.
stoisko
2
Tłumacz w HQ9 + powinien automatycznie wygrać.
TheNumberOne

Odpowiedzi:

16

APL (Dyalog) (326–8 = 318)

Wklej go w oknie edytora i zadzwoń H. Dane pobierane są z klawiatury.

H
⎕←'Source code contains invalid characters'/⍨~∧/'HhQq9+'∊⍨V←⍞
B←' of beer'
W←' on the wall'
L←⎕TC[2]
Z←{k←' bottle','s'/⍨⍵≠1⋄⍵<0:'99',k⋄⍵=0:'No',k⋄k,⍨⍕⍵}
{⍵∊'Hh':⎕←'Hello, world!'
⍵∊'Qq':⎕←V
⍵∊'9':{⎕←G,K,(G←Z⍵),B,L,(⊃'Go to the store and buy some more' 'Take one down and pass it around'[1+×⍵]),L,(Z⍵-1),K←B,W,L}¨1-⍨⌽⍳100}¨V
marinus
źródło
6

Mathematica, 349 346 341 znaków

h = If[StringMatchQ[#, ("H" | "Q" | "9" | "+") ...], 
   b = If[# > 0, ToString@#, "No"] <> " bottle" <> 
      If[# == 1, "", "s"] <> " of beer" &; 
   w = b@# <> " on the wall" &; 
   Print /@ 
    StringCases[#, {"H" -> "Hello, world!", "Q" -> #, 
      "9" -> "" <> 
        Table[w@n <> ",\n" <> b@n <> 
          ".\ntake one down, pass it around,\n" <> w[n - 1] <> 
          If[n == 1, ".", ".\n\n"], {n, 99, 1, -1}]}];, 
   "Source code contains invalid characters"] &
alephalpha
źródło
Bardzo imponujące, ale wydaje się, że są pewne drobne niedociągnięcia. H [„Q”] wyprowadza „Q”. h [„9”] działa, ale h [9] generuje cały program (nie rozumiem jak.)
DavidC
@DavidCarraher Wysyła kod ze względu na to, jak StringMatchQ i If nie powiedzie się:If[StringMatchQ[3, "a"], x, y]
ssch
6

C, 599 587 487 481 467 znaków

Jestem pewien, że można to pokonać. W końcu używam C. Jest powód, dla którego nie widzisz zbyt wielu zwycięskich wpisów do golfa napisanych w C. To teraz 467 znaków dzięki przestępstwu #define.

Podaj plik źródłowy HQ9 + jako argument wiersza poleceń.

EDYCJA: Teraz akceptuje źródło ze standardowego wejścia, a nie plik. Uruchom program, zacznij pisać kod, CTRL- Cpo zakończeniu, aby go uruchomić.

Kompiluje przynajmniej w MinGW / GCC z: gcc -o hq9+.exe hq9+.c

Powinien działać w MSVC, ale nie miałem ochoty tworzyć całego rozwiązania tylko do tego. :)

#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;
main(){
char p[9999],c;
for(;;) {
    switch(c=getch()){
    C 'H':C 'Q':C '9':C '+': C 3: R;
    default:P("Source code contains invalid characters\n");
    }
    if (c==3) R;
    p[s++]=c;
}
for(i=0;i<s;i++){
    c = p[i];
    switch(c){
    C 'H':
        P("Hello world!");
        R;
    C 'Q':
        for(j=0;j<s;j++)putchar(p[j]);
        R;
    C '9':
        j=99;
        while(j){
            P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);
            j--;
        }
        R;
    C '+':
        a++;
    }
}
}

Lub:

#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;main(){char p[9999],c;for(;;){switch(c=getch()){C 'H':C 'Q':C '9':C '+': C 3: R;default:P("Source code contains invalid characters\n");}if (c==3) R;p[s++]=c;}for(i=0;i<s;i++){c = p[i];switch(c){C 'H':P("Hello world!");R;C 'Q':for(j=0;j<s;j++)putchar(p[j]);R;C '9':j=99;while(j){P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);j--;}R;C '+':a++;}}}
Mike C.
źródło
Zmniejszono go do 487 znaków, używając stdin zamiast pliku do wprowadzania danych.
Mike C
Zrób to 464, nadużywając #define.
Mike C
Możesz pozbyć się spacji, takich jak te przed Ci kilka wcześniej R;. Można również zgolić 8 znaków p[s++]=0;po pętli wejściowej, aby uprościć drukowanie p.
Daniel Lubarov
3

Python 2 - 452 453 443 bajtów

q=raw_input()
if set(q)-set('HQ9+'):print'Source code contains invalid characters'
b=' bottles of beer'
b=[b,b.replace('s','')]
w=[a+' on the wall'for a in b]
t='Take one down, pass it around,\n'
c={'H':'Hello, world!','Q':q,'9':''.join(`i`+w[i<2]+',\n'+`i`+b[i<2]+'.\n'+t+(`i`if i>1 else'No')+w[0]+'.\n'for i in range(1,100)[::-1])+'No'+w[0]+',\nNo'+b[0]+'.\n'+'Go to the store, buy some more,\n99'+w[0]+'.'}
for d in q:
 if d in c:print c[d]

Bleh To było już ponure, ale potem odkryłem błąd, który kosztował mnie bajt do naprawienia. Bleh

(Kiedyś nie włączałem +do wyjścia Q. Na przykład dane wejściowe Q+++dawały dane wyjściowe Q.)

Zapisano niektóre znaki, nie wychodząc z nieprawidłowego wejścia, jak myślałem, że powinieneś.

Wersja wyjaśniona już wkrótce.Poddałem się. Ledwo rozumiem, jak działa ta potworność. Jeśli będzie zapotrzebowanie, spróbuję jeszcze raz, ale do tego czasu tak się nie dzieje.

podziemny monorail
źródło
Nie exitużywasz nieprawidłowego znaku, po prostu wyświetl wiadomość, aby zapisać tam 7 znaków.
Kyle Kanos
@KyleKanos Och, źle to zrozumiałem. Dzięki!
undergroundmonorail
Twoje teksty są niewłaściwe - obecnie mówi: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *99* bottles of beer on the wall. Powinno to brzmieć: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *98* bottles of beer on the wall.
Oliver Ni
Daje również błąd, kiedy wchodzę +. Powinieneś to zignorować + , nie dać błędu
Oliver Ni
Poza tym między wyjściami nie powinno być niczego. Jakbym wszedł HQHH, powinienem powiedziećHello World!HQHHHelloWorld!Hello World!
Oliver Ni
3

Perl, 325–8 = 317

sub p{print@_}$_=<>;$a=' on the wall';$b=' bottle';$e=' of beer';$c='Take one down, pass it around';if(!/^[hqHQ9+]+$/){p"Source code contains invalid characters";exit}$k=$_;for(/./g){/H|h/&&p"Hello, World!";if(/9/){$i=99;$d=$b."s$e";while($i>0){p"$i$d$a
$i$d
$c
";$q=--$i==1?'':'s';$d="$b$q$e";$i||=No;p"$i$d$a
"}}/Q|q/&&p$k}

Rozszerzony:

sub p{print@_}
$_=<>;
$a=' on the wall';
$b=' bottle';
$e=' of beer';
$c='Take one down, pass it around';
if(!/^[hqHQ9+]+$/){
    p"Source code contains invalid characters";
    exit
}
$k=$_;
for(/./g){
    /H|h/&&p"Hello, World!";
    if(/9/){
        $i=99;
        $d=$b."s$e";
        while($i>0){
            p"$i$d$a
$i$d
$c
";
            $q=--$i==1?'':'s';
            $d="$b$q$e";
            $i||=No;
            p"$i$d$a
"
        }
    }
    /Q|q/&&p$k
}
faubi
źródło
2

Rubin, 364 360 - 8 = 352

Wciąż jest dużo miejsca na ulepszenia. Skradziono stąd kod 99 butelek .

p=gets.upcase
if p=~/[^HQ9+
]/
puts"Source code contains invalid characters"else
p.each_char{|x|case x
when ?H
puts"Hello, world!"
when ?Q
puts p
when ?9
def c;"#{$n} bottle#{'s'if$n>1} of beer on the wall"end
($n=99).times{puts"#{c}, #{c[0..-13]}.
#{$n<2?"Go to the store and buy some more":"Take one down and pass it around"}, #{$n=($n-2)%99+1;c}.

"}end}end
Klamka
źródło
Powinno być No more bottles of beer on the wallpo 1 bottlesekcji. to jestGo to the store...
Oliver Ni
1 bottle of beer on the wall, 1 bottle of beer on the wall, take one down, pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer, go to the store, buy some more, 99 bottles of beer on the wall.
Oliver Ni
@Oliver Pytanie nie określa dokładnego tekstu piosenki. W żadnym miejscu nie wymaga uwzględnienia sekcji „nie więcej”.
Klamka
Ok, ale też między wyjściami nie powinna być nowa linia.
Oliver Ni
@Oliver Gdzie mówi to wyzwanie?
Klamka
2

Haskell, 298

main=interact g
g s|all(`elem`"HQ9+")s=s>>=(%s)|0<1="Source code contains invalid characters"
'H'%_="hello World!"
'Q'%s=s
'9'%_=drop 32$d 99
_%_=""
k=" bottles of beer on the wall"
d 0="No more"++k++"."
d n|a<-shows n k=[a,".\n\n",a,",\n",take 18a,".\ntake one down, pass it around\n",d$n-1]>>=id

jest to dość proste. %zwraca wynik polecenia (podany kod źródłowy do użycia na Q). dzwraca piosenkę 99 butelek z linią śmieci na początku z powodów golfowych. wszystko jest zawinięte w interakcję (możesz chcieć użyć gzamiast mainpodczas testowania)

dumny haskeller
źródło
Jak mam to uruchomić? Próbowałem wkleić go w WinGHCi, ale rozumiem <interactive>:8:5: parse error on input ‘=’.
ProgramFOX
@ProgramFOX nie mam pojęcia ... Sprawdzę, kiedy będę mógł
dumny haskeller
@ProgramFOX przepraszam, że to trwało długo :-). nie używasz poprawnie GHCi. w GHCi nie można poprawnie wprowadzić definicji, ponieważ oczekuje ona wyrażeń. możesz użyć a, letaby wstawić definicje (powoduje to przerwanie przy wstawianiu wielu definicji niepoddzielonych przez ;) lub uruchomić kod z pliku.
dumny haskeller
Widzę. Wciąż jednak próbuję go uruchomić; kiedy ładuję plik i wywołuję main, mówi, że kod źródłowy zawiera nieprawidłowe znaki, gdy próbuję wykonać H. Gdy próbuję uruchomić gzamiast main, natychmiast powoduje błąd.
ProgramFOX
@ ProgramFOX mainnie działa, ponieważ dołączony nowy wiersz nie jest poleceniem prawnym. Dlatego zaleciłem użycie gzamiast tego. Jeśli chodzi o g, putStrLn $ g "H" nie działa poprawnie?
dumny haskeller
2

J - 444 bajty

Podobał mi się numer, więc przestałem grać w golfa. Proszę bardzo, funkcja pojedynczego wyrażenia!

f=:'Source code contains invalid characters'"_`('Hello, world!'"_`[`((((s=:(<:@[s],L,(v,LF,'Take one down and pass it around, '"_,b@<:,' of beer on the wall.'"_)@[,''"_)`(],(L=:LF,LF),(v=:1&b,' of beer on the wall, '"_,b,' of beer.'"_)@[)@.([<1:))''"_),LF,'Go to the store and buy some more, '"_,(b=:({&'Nn'@([=0:),'o more'"_)`(":@])@.(]>0:),{.&' bottles'@(8:-=&1@])),' of beer on the wall.'"_)@(99"_))`]@.('HQ9+'&i.@])"0 1 0])@.(*./@e.&'HQ9+')

Przykłady:

   hq9 '9QHHQ+'
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.

...

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
9QHHQ+
Hello, world!
Hello, world!
9QHHQ+
+
   hq9 '9QHHaQ'
Source code contains invalid characters
patrz
źródło
I nie, nie napiszę tego wyjaśnienia. Za długo.
patrz
Czekaj, dlaczego to jest przegłosowane?
patrz
2

Fortran 528 470 481

Wymaga skompilowania z -fppflagą (+3, aby zdobyć) 1, aby użyć dyrektyw przetwarzania wstępnego (co pozwala zaoszczędzić znacznie więcej niż 3 znaki, więc nie mam nic przeciwko). Rozróżnia także małe i duże litery, więc jest -8: D. Zapisano 5 znaków, nie przetwarzając wstępnie endiftak, jak i tak jest używane raz .

Wymaga, aby plik miał .F90rozszerzenie (warto go nazwać hq9+.F90), aby kompilator wymusił wstępne przetwarzanie. W kodzie rozróżniana jest wielkość liter; sprawia, że ​​rozróżnia małe i duże litery dodaje około 16 znaków, więc nie warto zapisywać 8 znaków. Moja poprzednia odpowiedź nie uwzględniała zmiany liczby mnogiej bottlesna 9; ta wersja to poprawia (i niestety dodaje o wiele więcej znaków).

#define P print*,
#define W " of beer on the wall"
#define N print'(x,i0,a,a)',
#define e enddo
#define S case
#define J len(trim(c))
character(len=99)::c,b=" bottles";read*,c;do i=1,J;if(all(c(i:i)/=["H","Q",'9',"+"])) then;P"Source code contains invalid characters";exit;endif;e;do i=1,J;select S(c(i:i));S("H");P"Hello, world!";S("Q");P c;S("9");l=8;do k=99,1,-1;N k,b(1:l),W;N k,b(1:l)," of beer";P "Take one down, pass it around";if(k==2)l=l-1;if(k==1)exit;N k-1,b(1:l),W;P"";e;P"No more",trim(b),W;S default;endselect;e;end

Wygląda o wiele lepiej nieprzetworzony i nieprzetworzony (prawdopodobnie dlatego, że widać, co się dzieje):

program hq9
   character(len=99)::c,b=" bottles"
   read*,c
   do i=1,len(trim(c))
! change the below to ["H","h","Q","q","9","+"] to be case-insensitive
      if(all(c(i:i)/=["H","Q","9","+"]))then
         print*,"Source code contains invalid characters"
         exit
      endif
   enddo
   do i=1,len(trim(c))
      select case(c(i:i))
        case("H")                ! change to case("H","h") for case-insensitive
           print*,"Hello, world!"
        case("Q")                ! change to case("Q","q") for case-insensitive
           print*, c
        case("9")
           l=8
           do k=99,1,-1
              print'(x,i0,a,a)', k,b(1:l)," of beer on the wall"
              print'(x,i0,a)', k,b(1:l)," of beer"
              print*,"Take one down, pass it around"
              if(k==2) l=l-1
              if(k==1) exit
              print'(x,i0,a)', k-1,b(1:l)," of beer on the wall"
              print*,""
           enddo
           print*,"No more",trim(b)," of beer on the wall"
        case default
           ! do nothing
      endselect
   enddo
end program hq9
Kyle Kanos
źródło
Myślę, że akceptowalne jest wymaganie określonego rozszerzenia, aby kompilator wiedział, co się kompiluje. Analog może wymagać nazwy pliku C ++, .ccaby uniknąć konieczności używania -lstdc++flagi.
primo
2

Python 2, 340 - 8 = 332

s,o=raw_input(),''
for z in s:
 if z in'Hh':o+='Hello World!'
 elif z in'Qq':o+=s
 elif'9'==z:
  i=298
  while~-i:print i/3or 99,'bottle'+'s of beer on the wall.\n'[2<i<6:9+i%3*12]+'..\nGToa kteo  otnhee  dsotwonr,e ,p absusy  isto maer omuonrde,,'[(i>3)+i%3*68::2];i-=1
 elif'+'!=z:o='Source code contains invalid characters';break
print o
Oliver Ni
źródło
1

Lua 443 - 8 = 435 464 - 8 = 456

Udało mi się zapisać 21 znaków, używając wielu if-ends zamiast if-elseif-end. Miałem też dodatkowe białe przestrzenie pływające po kilku ).

p=print o=" of beer"t=" on the wall"B=" bottle"b=" bottles"l=io.read("*l");g=l:lower()if g:match"[^hq9+]"then p("Source code contains invalid characters")end for i=1,#g do s=g:sub(i,i)if s=='h'then p("Hello, world")end if s=='q'then p(l)end if s=='9'then n=99 repeat p(n..b..o..t..", "..n..b..o)n=n-1 p("Take one down, pass it around, "..n..b..o..t..".")p()until n==1 p("1"..B..o..t..", 1"..B..o)p("No more"..b..o..t..", no more"..b..o)end end

Jestem dość zadowolony z tego, chociaż nie jest on znacznie krótszy niż moja odpowiedź w Fortranie . Kod 99 butelek piwa został zmodyfikowany z tej odpowiedzi przez Alessandro . Nie mamy golfa, mamy

-- reuse stuff
p=print
o=" of beer"
t=" on the wall"
B=" bottle"
b=" bottles"
-- read the line & then lowercase it for case insensitivity
l=io.read("*l");g=l:lower()
if g:match"[^hq9+]" then -- horray for basic regex
   p("Source code contains invalid characters")
end
for i=1,#g do
   s=g:sub(i,i)               -- take substring
   if s=='h' then p("Hello, world") end
   if s=='q' then p(l) end
   if s=='9' then
      n=99
      repeat
         p(n..b..o..t..", "..n..b..o)
         n=n-1
         p("Take one down, pass it around, "..n..b..o..t..".")
         p()
      until n==1
      p("1"..B..o..t..", 1"..B..o)
      p("No more"..b..o..t..", no more"..b..o)
   end
end
Kyle Kanos
źródło
Kod do wprowadzania małych liter kosztuje 12 znaków, więc bonus nie jest tego wart.
nyuszika7h
Nie musisz wpisywać małych liter, możesz po prostu zrobić coś takiegoif s in'Hh'
Oliver Ni
Zapisuje 8 znaków
Oliver Ni
@MCParadox: Eee, to jest Python, o którym myślisz, Lua insłuży do iteratorów pętli for, a nie porównań; dostaniesz błąd, jeśli go tam włożysz. Istnieją tutaj trzy opcje: (1) użyj matchw każdej linii, (2) użytkownik s=='h'or s=='H'w każdej linii, (3) zrób to tak, jak to zrobiłem. Wyraźnie (3) jest krótszy niż (1) i (2).
Kyle Kanos
1

Julia, 362

s = chomp(readline(STDIN))
l=""
z=" of beer"
q,r,w,t=" bottles$z"," bottle$z"," on the wall.\n","take one down, pass it around,\n"
for j=99:-1:2
b="$j$q"
l*="$b$w$b.\n$t"
end
l*="1$r$(w)1$r.\n$(t)No$q$w"
p=println
all(c->c in "HQ9+", s)||p("Source code contains invalid characters")
for c in s
    c=='Q'&&p(s)
    c=='H'&&p("Hello, world!")
    c=='9'&&p(l)
end
gggg
źródło
1

Tcl, 515

set d [read stdin]
if {![regexp {^[hq9\+HQ]*$} $d]} {puts "Source code contains invalid characters"}
lmap c [split $d {}] {set b { bottles of beer}
switch -- $c H {puts "Hello, world"} Q {puts $d} 9 {for {set i 99} {$i>2} {incr i -1} {puts "$i$b on the wall,
$i$b.
Take one down, pass it around,
[expr $i-1]$b on the wall.
"}
puts "2$b on the wall,
2$b.
Take one down, pass it around,
1 bottle of beer on the wall.

1 bottle of beer on the wall,
1 bottle of beer.
Take one down, pass it around,
No$b on the wall."}}

Tylko trochę golfa, wciąż mniejszy niż C i poprawne 99 butelek końca piwa.

Johannes Kuhn
źródło
Okej, teraz, kiedy ktoś jest legalny. Dobra robota, pokonałeś mnie. Powinienem przestać używać C do gry w golfa.
Mike C
Możesz usunąć pierwszy wiersz i osadzić go przy ostatnim parametrze regexp. Możesz zagrać w
sergiol
1

JavaScript (ES6), 385

s=>{n=99,b=' bottle',j=' of beer',d=' on the wall',e='Take one down, pass it around',k='Go to the store, buy some more',l='No',o='s',f=', ';for(i=s.split(m=v='');~n;)v+=[n||l,b,n-1?o:m,j,d,f,n||l,b,n-1?o:m,j,f,n?e:k,f,--n<1?99:n,b,n-1?o:m,j,d,'! '].join(m);return s.match(/[^HQ9\+]/,r='')?'Source code contains invalid characters':[...s].map(c=>({H:'Hello World!',9:v,Q:s})[c]).join``}

Nie zdecydowałem się na rozróżnianie wielkości liter, kosztowałoby zbyt wiele znaków. Nawet nie blisko niektórych innych wpisów, ale mimo to było fajnie!

JavaScript, 344

Stworzyłem wersję z mniej kompletną wersją piosenki:

(function(i){if(s.match(/[^HQ9\+]/)){m='Source code contains invalid characters'}else{n=99,b=' bottles of beer ',d='on the wall',e='take one down, pass it around',f=', ';for(;n;)v+=[n,b,d,f,n,b,f,e,f,--n||'no more',b,d,'! '].join(m);h={H:'Hello World!',Q:arguments.callee+m,9:v};for(;c=i[n++];)m+=h[c]||''}alert(m)})((s=prompt()).split(m=v=''))

ale po obejrzeniu innych wpisów (i po tekstach, kto wiedział!), pomyślałem, że to trochę głupiec!

Dom Hastings
źródło
Powinno być Go to the store, buy some more, *99* bottles of beer on the wall, nie*No more* bottles of beer on the wall
Oliver Ni
Jeśli kupisz więcej, jak może ich już nie być?
Oliver Ni
I też Qnie działa dla mnie.
Oliver Ni
@Oliver wtedy nie zauważył, że skomentowałeś to ... Całkowicie źle zrozumiałem, kiedy Qmiałem to zrobić, i podałem kod źródłowy funkcji zamiast danych wejściowych ... To był pierwotnie mój powód, aby to zrobić w JS ta część byłaby łatwa, ale teraz wiem, że wcale nie jest to wymagane!
Dom Hastings,
@Oliver zaktualizował teksty!
Dom Hastings,
1

C, 562 bajtów

char*c="%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";main(int a,char**b){int x=0;for(int i=0;i<strlen(b[1]);i++){if(b[1][i]=='+')x++;else if(b[1][i]=='9'){int k=99;while(1){printf(&c[0],k,k,k==1?"bottle":"bottles","beer","wall");if(k!=1){printf(&c[49],k,k,"bottles","beer","wall");k--;}else{k=99;printf(&c[114],k,k,"bottles","beer","wall");break;}}}else printf("%s",b[1][i]=='H'?"Hello, world!":(b[1][i]=='Q'?b[1]:""));}}

Jako pełny program. Pierwszym argumentem jest program HQ9 +. Z rzeczywistym akumulatorem. Postanowiłem nie używać definicji.

Wersja bez golfa:

char* c = "%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";
main (int a, char** b) {
    int x = 0;
    for (int i = 0; i < strlen(b[1]); i++) {
        if (b[1][i] == '+')
            x++;
        else if (b[1][i] == '9') {
            int k = 99;
            while (1) {
                printf(&c[0], k, k, k == 1 ? "bottle" : "bottles", "beer", "wall");
                if (k != 1) {
                    printf(&c[49], k, k, "bottles", "beer", "wall");
                    k--;
                } else {
                    k=99;
                    printf(&c[114], k, k, "bottles", "beer", "wall");
                    break;
                }
            }
        } else
            printf("%s",b[1][i] == 'H' ? "Hello, world!" : (b[1][i] == 'Q' ? b[1] : ""));
    }
}
ciastko
źródło
0

Java, 546 bajtów

To jest mój pierwszy kod golfowy. Jestem pewien, że moglibyśmy z tym zrobić więcej. Odczytuje dane wejściowe jako argument wiersza poleceń. Kod piwa „pożyczony” z „99 butelek piwa” odpowiedź java (twórcze elementy wspólne)

class a{public static void main(String[] a){if(a[0].matches("^[HQ9\\Q+\\E]+$")){for(char c:a[0].toCharArray()){if(c=='H')p("Hello, world!");if(c=='Q')p(a[0]);if(c=='9')b();}}else{System.out.println("Source code contains invalid characters");}}static void p(String s){System.out.println(s);}static void b(){String b=" of beer",c=" on the wall",n=".\n",s;for(int i=100;i-->1;){s=" bottle"+(i>1?"s":"");p(i+s+b+c+", "+i+s+b+n+(i<2?"Go to the store and buy some more, 99":"Take one down and pass it around, "+(i-1))+" bottle"+(i!=2?"s":"")+b+c+n);}}}

Daj mi znać, jeśli argumenty wiersza poleceń są niedopuszczalne. To była świetna zabawa!

Rohan Jhunjhunwala
źródło
CLA są w porządku. Niezła odpowiedź.
Rɪᴋᴇʀ
0

Excel VBA, 489 bajtów

Unindented:

Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
Case "H"
Debug.? "Hello,World!"
Case "Q"
Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule:For n=1 To v.countoflines:Debug.? v.Lines(n,1):Next
Case "+"
a=a+1
Case "9"
s=" Bottles of Beer":o=" Bottle of Beer":w=" on the wall":t=". Take 1 down pass it around,":p=",":d=".":For n=99 To 3 Step -1:Debug.? n;s;w;p;n;s;t;n-1;s;w;d:Next:Debug.? 2;s;w;p;2;s;t;1;o;w;d:Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub

(z naciskiem na czytelność)

Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
    Case "H"
        Debug.? "Hello,World!"
    Case "Q"
        Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule
        For n=1 To v.countoflines
            Debug.? v.Lines(n,1)
        Next
    Case "+"
        a=a+1
    Case "9"
        s=" Bottles of Beer"
        o=" Bottle of Beer"
        w=" on the wall"
        t=". Take 1 down pass it around,"
        p=","
        d="."
        For n=99 To 3 Step -1
            Debug.? n;s;w;p;n;s;t;n-1;s;w;d
        Next
        Debug.? 2;s;w;p;2;s;t;1;o;w;d
        Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub

Zmień nazwę domyślnego wywołania Modułu 1 na M za
pomocą h "+++++++++Your Code"
To będzie działać również w innych aplikacjach biurowych, zmieniając ActiveWorkbook na odpowiedni typ dokumentu

SeanC
źródło
zwróć uwagę, że excel doda spacje i rozszerzy skróty, więc w
excelu
To 636 znaków
Oliver Ni
Usuń wszystkie białe znaki z mojego wcięcia, @oliver
SeanC
Możesz stracić 3 bajty, konwertując wszystkie instancje For n=1 Tona For n=1To(wcześniej usuwając spację To) i 4 bajty, konwertując wszystkie instancje Debug.? 2;na Debug.?2;(usuwając białe spacje po ?słowie kluczowym)
Taylor Scott