Erstellen eines HQ9 + -Interpreters

31

Ziel dieses Codegolfs ist es, einen Interpreter für die Programmiersprache HQ9 + zu erstellen.
Diese Programmiersprache enthält 4 Befehle:

  • H - druckt "Hallo Welt!"
  • Q - druckt den Quellcode des Programms
  • 9 - druckt den Text des Liedes "99 Flaschen Bier"
  • + - erhöht den Akku

Die Regeln:

  1. Da der Akku nicht definiert ist, können Sie den Befehl + ignorieren
  2. Ihr Programm sollte zur Eingabe auffordern (diese Eingabe ist der Quellcode) oder der Quellcode wird aus einer Datei gelesen
  3. Sie dürfen den Text von "99 Flaschen Bier" nicht in eine Datei einfügen und den Text aus der Datei lesen
  4. Sie dürfen keinen Komprimierungsalgorithmus wie GZip oder BZip zum Komprimieren des Liedtexts verwenden: Sie müssen Ihren eigenen Komprimierungsalgorithmus erstellen. Dies muss kein komplexer Algorithmus sein, aber versuchen Sie, den Text so weit wie möglich zu komprimieren (denken Sie daran: Dies ist ein Code-Golf, der Code mit den wenigsten Bytes gewinnt).
  5. Wenn der Quellcode ein Zeichen enthält, das nicht H , Q , 9 oder + ist , geben Sie "Quellcode enthält ungültige Zeichen" aus, bevor Sie Befehle ausführen! Dies bedeutet, dass, wenn der Quellcode H1zum Beispiel ist, nicht ausgegeben wird, Hello, world!bevor Sie ausgeben Source code contains invalid characters. Nein, sofort ausgebenSource code contains invalid characters
  6. Wenn Ihr Interpreter sowohl Groß- als auch Kleinbuchstaben akzeptiert, erhalten Sie -8 als Zeichenanzahl

Viel Glück!

ProgramFOX
quelle
3
Regel 4 ergibt keinen Sinn bei "Warum sollte er das verbieten ?!" Niveau; Regel 5 ergibt keinen Sinn bei "Was meint er ?!" Niveau.
Peter Taylor
4
Wie macht Regel 5 keinen Sinn?
Mike C
Ich denke, es wäre besser, nur die Verwendung von Großbuchstaben zu verlangen, anstatt willkürlich zu sagen, dass Sie 8 Zeichen frei haben, wenn es eines von beiden akzeptiert. 8 kann es je nach Sprache abdecken oder nicht.
Mike C
10
Regel 5 macht keinen Sinn, da sie die HQ9 + -Spezifikation verletzt.
Stand
2
Ein Dolmetscher in HQ9 + sollte automatisch gewinnen.
TheNumberOne

Antworten:

16

APL (Dyalog) (326 - 8 = 318)

Fügen Sie es in ein Editorfenster ein und rufen Sie es auf H. Die Eingabe erfolgt über die Tastatur.

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
quelle
6

Mathematica, 349 346 341 Zeichen

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
quelle
Sehr eindrucksvoll, aber es scheint ein paar kleine Klischees zu geben. 'H ["Q"] gibt "Q" aus. h ["9"] funktioniert, aber h [9] gibt das gesamte Programm aus (ich verstehe nicht wie.)
DavidC
@DavidCarraher Gibt Code aus, weil StringMatchQ und If fehlschlagen:If[StringMatchQ[3, "a"], x, y]
ssch
6

C, 599 587 487 481 467 Zeichen

Ich bin sicher, das kann geschlagen werden. Ich benutze schließlich C. Es gibt einen Grund, warum Sie nicht viele in C geschriebene Gewinngolfeinträge sehen. Das sind jetzt 467 Zeichen, dank kriminellem Missbrauch von #define.

Geben Sie die HQ9 + -Quelldatei als Befehlszeilenargument an.

BEARBEITEN: Akzeptiert jetzt die Quelle von stdin, keine Datei. Starten Sie das Programm, geben Sie den Code ein, CTRL- Cwenn Sie damit fertig sind.

Es kompiliert mindestens in MinGW / GCC mit: gcc -o hq9+.exe hq9+.c

Sollte in MSVC funktionieren, aber ich hatte keine Lust, eine vollständige Lösung dafür zu erstellen. :)

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

Oder:

#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
quelle
Durch die Verwendung von stdin anstelle einer Datei für die Eingabe wurden 487 Zeichen erreicht.
Mike C
Machen Sie das 464, indem Sie #define missbrauchen.
Mike C
Sie könnten Räume wie die nach Cund ein paar vor loswerden R;. 8 Zeichen könnten p[s++]=0;nach der Eingabeschleife abgeschnitten werden , um das Drucken zu vereinfachen p.
Daniel Lubarov
3

Python 2 - 452 453 443 Bytes

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. Es war schon schlimm, aber dann entdeckte ich einen Fehler, dessen Behebung mich ein Byte gekostet hat. Bleh.

(Früher habe ich nicht +in die Ausgabe für aufgenommen Q. Eine Eingabe von Q+++gab die AusgabeQ zum Beispiel.)

Einige Zeichen wurden gespeichert, indem bei ungültiger Eingabe nicht beendet wurde, wie ich es erwartet hatte.

Erklärte Version folgt in Kürze.Ich gab auf. Ich verstehe kaum noch, wie diese Monstrosität funktioniert. Wenn es Nachfrage gibt, werde ich es noch einmal versuchen, aber bis dahin passiert es nicht.

untergrundbahn
quelle
Wenn Sie exitdas ungültige Zeichen nicht verwenden, zeigen Sie einfach die Nachricht an, damit Sie dort 7 Zeichen speichern können.
Kyle Kanos
@KyleKanos Oh, das habe ich falsch verstanden. Vielen Dank!
U-
Deine Texte stimmen nicht - momentan heißt es: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *99* bottles of beer on the wall. Es soll heißen : 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
Es gibt auch einen Fehler, wenn ich eingebe +. Sie sollten ignorieren + , keinen Fehler machen
Oliver Ni
Es sollte auch nichts zwischen den Ausgängen sein. Als ob ich eintrete HQHHsollte es sagenHello 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}

Erweitert:

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
quelle
2

Ruby, 364 360 - 8 = 352

Hat noch viel Raum für Verbesserungen. 99 Flaschen Code von hier gestohlen .

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
Türknauf
quelle
Es soll No more bottles of beer on the wallnach dem 1 bottleAbschnitt sein. dann ist esGo 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 Die Frage gibt nicht den genauen Liedtext an. An keiner Stelle muss der Abschnitt "Nicht mehr" enthalten sein.
Türklinke
Ok, aber es sollte auch keinen Zeilenumbruch zwischen den Ausgaben geben.
Oliver Ni
@Oliver Wo sagt die Herausforderung das aus?
Türklinke
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

das ist ganz einfach. %Gibt die Ausgabe eines Befehls zurück (unter Angabe des Quellcodes für die Verwendung in Q). dgibt den 99 Flaschen Song mit einer Junk Line am Start aus Golfgründen zurück. Alles ist in eine Interaktion eingebunden (möglicherweise möchten Sie diese verwenden, ganstatt sie zu maintesten)

stolzer haskeller
quelle
Wie soll ich es ausführen? Ich habe versucht, es in WinGHCi einzufügen, aber ich verstehe <interactive>:8:5: parse error on input ‘=’.
ProgramFOX
@ProgramFOX Ich habe keine Ahnung ... Ich werde nachsehen, wann ich kann
stolzer Haskeller
@ProgramFOX sorry es hat lange gedauert :-). Sie verwenden GHCi nicht richtig. In GHCi können Sie Definitionen nicht direkt eingeben, da sie Ausdrücke erwarten. Sie können entweder a letzum Einfügen von Definitionen verwenden (dies bricht ab, wenn Sie mehrere Definitionen ohne Trennzeichen einfügen ;) oder den Code aus einer Datei ausführen.
stolzer Haskeller
Aha. Ich kann es immer noch nicht ausführen. Wenn ich die Datei lade und aufrufe main, heißt es, dass der Quellcode ungültige Zeichen enthält, wenn ich versuche, sie auszuführen H. Wenn ich versuche zu laufen gstatt main, gibt es sofort einen Fehler.
ProgramFOX
@ProgramFOX mainfunktioniert nicht, da der angehängte Zeilenumbruch kein zulässiger Befehl ist. Deshalb habe ich gstattdessen empfohlen . Wie für g, funktioniert das putStrLn $ g "H" nicht richtig?
stolzer haskeller
2

J - 444 Bytes

Ich mochte die Nummer, also hörte ich auf zu golfen. Komm schon, Funktion mit einem Ausdruck!

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

Beispiele:

   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
seequ
quelle
Und nein, ich werde keine Erklärung dafür schreiben. Zu lang.
Siehe auch
Warten Sie, warum ist das downvoted?
Siehe auch
2

Fortran 528 470 481

Es erfordert das Kompilieren mit -fppFlag (+3, um zu punkten) 1 , um Vorverarbeitungs-Direktiven zu verwenden (was weit mehr als 3 Zeichen spart, also bin ich damit völlig einverstanden). Es wird auch nicht zwischen Groß- und Kleinschreibung unterschieden, daher gibt es -8: D. 5 Zeichen gespart, indem das nicht vorverarbeitet wird, endifda es sowieso einmal verwendet wird .

Erfordert eine Dateierweiterung .F90(es ist sinnvoll, sie aufzurufen hq9+.F90), damit der Compiler die Vorverarbeitung erzwingt. Der Code unterscheidet zwischen Groß- und Kleinschreibung. Wenn die Groß- / Kleinschreibung nicht beachtet wird, werden 16 Zeichen hinzugefügt. Es lohnt sich also nicht, 8 Zeichen zu speichern. Meine bisherige Antwort berücksichtigt nicht die wechselnden Plurale in bottlesfür 9; Diese Version korrigiert es (und fügt leider viel mehr Zeichen hinzu).

#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

Sieht viel besser ungolfed & unverarbeitet aus (wahrscheinlich, weil Sie sehen können, was los ist):

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
quelle
Ich denke, es ist akzeptabel, eine bestimmte Erweiterung zu fordern, damit der Compiler weiß, was er kompiliert. Bei einem Analog muss möglicherweise eine C ++ - Datei benannt werden .cc, damit das -lstdc++Flag nicht benötigt wird.
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
quelle
1

Lua 443 - 8 = 435 464 - 8 = 456

Ich habe es geschafft, 21 Zeichen zu speichern, indem ich mehrere if-ends anstelle von verwendet habe if-elseif-end. Ich hatte auch einige zusätzliche Leerzeichen nach ein paar schweben ).

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

Ich bin ziemlich zufrieden damit, auch wenn es nicht viel kürzer ist als meine Fortran-Antwort . Die 99 Flaschen Biercode wurden von dieser Antwort von Alessandro modifiziert . Ungolfed haben wir

-- 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
quelle
Der Code zum Kleinschreiben der Eingabe kostet 12 Zeichen, sodass sich der Bonus nicht lohnt.
nyuszika7h
Sie brauchen die Eingabe nicht in Kleinbuchstaben zu schreiben, Sie können einfach so etwas tunif s in'Hh'
Oliver Ni
Es spart 8 Zeichen
Oliver Ni
@MCParadox: Ähm, das ist Python, an das Sie denken. Lua inist für for-loop-Iteratoren und nicht für Vergleiche. Sie erhalten eine Fehlermeldung, wenn Sie das dort hineinstecken. Hier gibt es drei Möglichkeiten: (1) matchin jeder Zeile verwenden, (2) Benutzer s=='h'or s=='H'in jeder Zeile, (3) es tun, wie ich es getan habe. Offensichtlich ist (3) kürzer als (1) und (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
quelle
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."}}

Nur ein bisschen Golf gespielt, immer noch kleiner als C und die richtigen 99 Flaschen Bier enden in Versen.

Johannes Kuhn
quelle
Okay, jetzt ist das echt. Gute Arbeit, du hast mich geschlagen. Ich sollte aufhören, C zum Golfen zu verwenden.
Mike C
Sie können die erste Zeile entfernen und beim letzten Parameter von einbetten regexp. Sie können mein Golfspiel mit 99 Bieren auf codegolf.stackexchange.com/a/109818/29325
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``}

Habe mich nicht für die Groß- / Kleinschreibung entschieden, hätte zu viele Zeichen gekostet. Nicht einmal in der Nähe von einigen der anderen Einträge, aber es hat trotzdem Spaß gemacht!

JavaScript, 344

Ich habe eine Version mit einer weniger vollständigen Version des Songs gemacht:

(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=''))

aber nachdem ich die anderen Einträge gesehen hatte (und die tatsächlichen Texte angeschaut hatte, wer wusste!), dachte ich, es wäre ein bisschen ein Cop out!

Dom Hastings
quelle
Es sollte Go to the store, buy some more, *99* bottles of beer on the wallnicht sein*No more* bottles of beer on the wall
Oliver Ni
Wenn Sie mehr kaufen, wie kann es dann noch nicht mehr geben?
Oliver Ni
Und Qfunktioniert auch nicht bei mir.
Oliver Ni
@Oliver merkte damals nicht, dass du das kommentiert hast ... Ich habe es total missverstanden, als der Qdas mal machen sollte und den Quellcode der Funktion anstelle der Eingabe lieferte ... Das war ursprünglich mein Grund dafür in JS wäre dieser Teil einfach, aber ich weiß jetzt, dass das überhaupt nicht erforderlich ist!
Dom Hastings
@Oliver hat den Songtext aktualisiert!
Dom Hastings
1

C 562 Bytes

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

Als volles Programm. Das erste Argument ist das Programm HQ9 +. Mit einem tatsächlichen Akku. Ich habe mich herausgefordert, keine define-Anweisungen zu verwenden.

Ungolfed-Version:

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] : ""));
    }
}
Plätzchen
quelle
0

Java, 546 Bytes

Dies ist meine erste Code Golf Einreichung. Ich bin sicher, wir könnten mehr damit anfangen. Die Eingabe wird als Befehlszeilenargument gelesen. Biercode "ausgeliehen" von "99 Bottles of Beer" Java-Antwort (Creative Commons)

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

Lassen Sie mich wissen, wenn Befehlszeilenargumente nicht akzeptabel sind. Das hat viel Spaß gemacht!

Rohan Jhunjhunwala
quelle
CLA geht es gut. Gute Antwort.
14.
0

Excel VBA, 489 Bytes

Ungerückt:

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

(zur besseren Lesbarkeit eingerückt)

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

Standardmodul1 in M- Aufruf mit umbenennen Dies funktioniert auch in anderen Office-Anwendungen, indem ActiveWorkbook in den entsprechenden Dokumenttyp geändert wird
h "+++++++++Your Code"

SeanC
quelle
Beachten Sie, dass Excel Leerzeichen hinzufügt und Abkürzungen erweitert. In Excel lautet der Code also 531 Zeichen
SeanC
Das sind 636 Charaktere
Oliver Ni
Entfernen Sie alle Leerzeichen aus meinem Einzug, @oliver
SeanC
Sie können 3 Bytes verlieren, indem Sie alle Instanzen von For n=1 Toto konvertieren For n=1To(vorher Leerzeichen entfernen To) und 4 Bytes, indem Sie alle Instanzen von Debug.? 2;to konvertieren Debug.?2;(nach dem ?Schlüsselwort Leerzeichen entfernen )
Taylor Scott