Création d'un interprète HQ9 +

31

Le but de ce code golf est de créer un interpréteur pour le langage de programmation HQ9 +
Il y a 4 commandes dans ce langage de programmation:

  • H - imprime "Bonjour tout le monde!"
  • Q - imprime le code source du programme
  • 9 - imprime les paroles de la chanson "99 bouteilles de bière"
  • + - incrémente l'accumulateur

Les règles:

  1. Parce que l'accumulateur n'est pas défini, vous pouvez ignorer la commande +
  2. Votre programme doit demander une entrée (cette entrée sera le code source) ou le code source est lu à partir d'un fichier
  3. Vous n'êtes pas autorisé à mettre les paroles de "99 bouteilles de bière" dans un fichier et à lire le texte du fichier
  4. Vous n'êtes pas autorisé à utiliser un algorithme de compression tel que GZip ou BZip pour compresser le texte du morceau: vous devez créer votre propre algorithme de compression. Cela ne doit pas être un algorithme complexe, mais essayez de compresser le texte autant que possible (rappelez-vous: c'est un code-golf, le code avec le moins d'octets gagne)
  5. Si le code source contient un caractère qui n'est pas H , Q , 9 ou + , alors affichez "Le code source contient des caractères invalides" avant d'exécuter des commandes! Cela signifie que, si le code source est H1par exemple, ne sortez pas Hello, world!avant de sortir Source code contains invalid characters. Non, sortie immédiateSource code contains invalid characters
  6. Si votre interprète accepte à la fois les majuscules et les minuscules, alors vous obtenez -8 à votre nombre de caractères

Bonne chance!

ProgramFOX
la source
3
La règle 4 n'a pas de sens au "pourquoi interdirait-il cela?!" niveau; la règle 5 n'a pas de sens au "qu'est-ce qu'il veut dire?!" niveau.
Peter Taylor
4
Comment la règle 5 n'a-t-elle pas de sens?
Mike C
Je pense qu'il serait préférable de simplement exiger qu'il n'utilise que des majuscules, plutôt que de dire arbitrairement que vous obtenez gratuitement 8 caractères s'il accepte l'un ou l'autre. 8 peut ou peut ne pas le couvrir selon la langue.
Mike C
10
La règle 5 n'a pas de sens car elle casse la spécification HQ9 +.
stand
2
Un interprète en HQ9 + devrait gagner automatiquement.
TheNumberOne

Réponses:

16

APL (Dyalog) (326 - 8 = 318)

Collez-le dans une fenêtre de l'éditeur et appelez H. L'entrée provient du clavier.

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
la source
6

Mathematica, 349 346 341 caractères

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
la source
Très impressionnant mais il semble y avoir quelques petits gliches.'h ["Q"] sort "Q". h ["9"] fonctionne, mais h [9] génère tout le programme (je ne comprends pas comment.)
DavidC
@DavidCarraher Il génère du code en raison de la façon dont StringMatchQ et If échoue:If[StringMatchQ[3, "a"], x, y]
ssch
6

C, 599 587 487 481 467 caractères

Je suis sûr que cela peut être battu. J'utilise C après tout. Il y a une raison pour laquelle vous ne voyez pas beaucoup d'entrées de golf gagnantes écrites en C. C'est maintenant 467 caractères grâce à l'abus criminel de #define.

Spécifiez le fichier source HQ9 + comme argument de ligne de commande.

EDIT: accepte maintenant la source de stdin, pas un fichier. Démarrez le programme, commencez à taper le code,CTRL - une Cfois terminé pour l'exécuter.

Il compile au moins dans MinGW / GCC avec: gcc -o hq9+.exe hq9+.c

Devrait fonctionner dans MSVC, mais je n'avais pas envie de créer une solution complète juste pour cela. :)

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

Ou:

#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
la source
Je l'ai réduit à 487 caractères en utilisant stdin au lieu d'un fichier d'entrée.
Mike C
Faites cela 464 en abusant de #define.
Mike C
Vous pourriez vous débarrasser des espaces, comme ceux après Cet quelques avant R;. Pourrait également raser 8 caractères avec p[s++]=0;après la boucle d'entrée pour simplifier l'impression p.
Daniel Lubarov
3

Python 2-452 453 443 octets

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. Il était déjà bloqué, mais j'ai découvert un bogue qui me coûtait un octet à corriger. Bleh.

(J'avais l'habitude de ne pas inclure +dans la sortie pour Q. Une entrée de Q+++donnait la sortie Q, par exemple.)

Enregistré certains caractères en ne quittant pas sur une entrée invalide comme je le pensais.

Version expliquée à venir.J'ai abandonné. Je comprends à peine comment fonctionne cette monstruosité. S'il y a une demande, je recommence, mais jusque-là, cela ne se produit pas.

métro monorail
la source
Vous n'êtes pas exitsur le caractère invalide, affichez simplement le message, vous pouvez donc y enregistrer 7 caractères.
Kyle Kanos
@KyleKanos Oh, j'ai mal compris cela. Merci!
undergroundmonorail
Vos paroles ne sont pas correctes - actuellement, il dit: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *99* bottles of beer on the wall. Il est censé dire: 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
Il donne également une erreur lorsque j'entre +. Vous êtes censé ignorer + , ne pas donner d'erreur
Oliver Ni
De plus, il n'y a rien à supposer entre les sorties. Comme si j'entre, HQHHil devrait direHello 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}

Étendu:

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
la source
2

Rubis, 364360 - 8 = 352

Il y a encore beaucoup de place pour l'amélioration. 99 bouteilles code volé d' ici .

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
Poignée de porte
la source
Il doit y avoir No more bottles of beer on the wallaprès la 1 bottlesection. alors c'estGo 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 La question ne précise pas les paroles exactes de la chanson. En aucun cas, il ne faut inclure la section «plus».
Poignée de porte
D'accord, mais aussi, il n'est pas censé y avoir de nouvelle ligne entre les sorties.
Oliver Ni
@Oliver Où le défi dit-il cela?
Poignée de porte
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

c'est assez simple. %renvoie la sortie d'une commande (étant donné le code source à utiliser sur Q). drenvoie la chanson de 99 bouteilles avec une ligne indésirable au début pour des raisons de golf. tout est enveloppé dans une interaction (vous voudrez peut-être utiliser à la gplace du maintest)

fier haskeller
la source
Comment dois-je l'exécuter? J'ai essayé de le coller dans WinGHCi, mais je comprends <interactive>:8:5: parse error on input ‘=’.
ProgramFOX
@ProgramFOX je n'en ai aucune idée ... Je vérifierai quand je peux
fier haskeller
@ProgramFOX désolé, cela a pris du temps :-). vous n'utilisez pas correctement GHCi. dans GHCi, vous ne pouvez pas saisir directement des définitions car il attend des expressions. vous pouvez soit utiliser un letpour insérer des définitions (cela casse lors de l'insertion de plusieurs définitions non séparées par ;), soit exécuter le code à partir d'un fichier.
fier haskeller
Je vois. Je n'arrive toujours pas à le faire fonctionner cependant; lorsque je charge le fichier et appelle main, il indique que le code source contient des caractères non valides lorsque j'essaie de l'exécuter H. Lorsque j'essaie d'exécuter gau lieu de main, cela donne immédiatement une erreur.
ProgramFOX
@ProgramFOX mainne fonctionne pas car la nouvelle ligne ajoutée n'est pas une commande légale. C'est pourquoi j'ai recommandé d'utiliser à la gplace. Quant à g, ne putStrLn $ g "H" fonctionne pas correctement?
fier haskeller
2

J - 444 octets

J'ai aimé le numéro, alors j'ai arrêté de jouer au golf. Voilà, fonction d'expression unique!

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

Exemples:

   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
voir
la source
Et non, je n'écrirai pas d'explication à ce sujet. Trop long.
seequ
Attendez, pourquoi est-ce sous-voté?
seequ
2

Fortran 528 470 481

Il faut compiler avec le -fppdrapeau (+3 pour marquer) 1 pour utiliser les directives de prétraitement (ce qui enregistre bien plus de 3 caractères, donc je suis tout à fait d'accord avec ça). Il est également insensible à la casse, il y a donc -8: D. 5 caractères enregistrés en ne prétraitant pas le endifcar il est utilisé une fois de toute façon .

Nécessite que le fichier ait une .F90extension (il est logique de l'appeler hq9+.F90) pour que le compilateur force le prétraitement. Le code est sensible à la casse; le rendre insensible à la casse ajoute quelque chose comme 16 caractères, donc cela ne vaut pas vraiment la peine d'enregistrer 8 caractères. Ma réponse précédente ne tenait pas compte des changements de pluriels dans bottlespour 9; cette version le corrige (et ajoute malheureusement beaucoup plus de caractères).

#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

Ressemble beaucoup mieux non golfé et non prétraité (probablement parce que vous pouvez voir ce qui se passe):

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
la source
Je pense qu'il est acceptable d'exiger une extension spécifique pour que le compilateur sache ce qu'il compile. Un analogue peut nécessiter un nom de fichier C ++ .ccpour éviter d'avoir besoin de l' -lstdc++indicateur.
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
la source
1

Lua 443 - 8 = 435 464 - 8 = 456

J'ai réussi à enregistrer 21 caractères en utilisant plusieurs if-ends au lieu de if-elseif-end. J'ai également eu quelques espaces blancs supplémentaires flottant après quelques-uns ).

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

Je suis assez satisfait de celui-ci, même s'il n'est pas beaucoup plus court que ma réponse Fortran . Le code des 99 bouteilles de bière a été modifié à partir de cette réponse par Alessandro . Non golfé, nous avons

-- 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
la source
Le code pour minuscule l'entrée coûte 12 caractères, donc le bonus n'en vaut pas la peine.
nyuszika7h
Vous n'avez pas besoin de mettre en minuscule l'entrée, vous pouvez simplement faire quelque chose commeif s in'Hh'
Oliver Ni
Il enregistre 8 caractères
Oliver Ni
@MCParadox: Euh, c'est Python auquel vous pensez, celui de Lua inest pour les itérateurs for-loop et non pour les comparaisons; vous obtiendrez une erreur si vous collez cela dedans. Il y a trois choix ici: (1) utiliser matchà chaque ligne, (2) utilisateur s=='h'or s=='H'à chaque ligne, (3) le faire comme je l'ai fait. Il est clair que (3) est plus court que (1) et (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
la source
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."}}

Juste un peu de golf, toujours plus petit que C et les 99 bouteilles de bière finales.

Johannes Kuhn
la source
D'accord, maintenant celui-là est légitime. Bon travail, tu m'as battu. Je devrais arrêter d'utiliser C pour le golf.
Mike C du
Vous pouvez supprimer la première ligne et l'intégrer au dernier paramètre de regexp. Vous pouvez obtenir mon golf de 99 bières sur 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``}

N'a pas opté pour la casse, aurait coûté trop de caractères. Pas même proche de certaines des autres entrées, mais c'était quand même amusant!

JavaScript, 344

J'ai fait une version avec une version moins complète de la chanson:

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

mais après avoir vu les autres entrées (et vu les paroles réelles, qui savait!), j'ai pensé que c'était un peu flic!

Dom Hastings
la source
Ça devrait être Go to the store, buy some more, *99* bottles of beer on the wall, pas*No more* bottles of beer on the wall
Oliver Ni
Si vous en achetez plus, comment peut-il n'y en avoir plus?
Oliver Ni
Et aussi, Qça ne marche pas pour moi.
Oliver Ni
@Oliver n'a pas remarqué que vous commentiez cela à l'époque ... J'ai totalement mal compris quand le Qdevait le faire à l'époque et j'ai fourni le code source de la fonction au lieu de l'entrée ... C'était à l'origine ma raison de le faire dans JS, cette partie serait facile, mais je sais maintenant que ce n'est pas du tout nécessaire!
Dom Hastings
@Oliver a mis à jour les paroles!
Dom Hastings du
1

C, 562 octets

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

En tant que programme complet. Le premier argument est le programme HQ9 +. Avec un véritable accumulateur. Je me suis efforcé de ne pas utiliser de déclarations de définition.

Version non-golfée:

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] : ""));
    }
}
biscuit
la source
0

Java, 546 octets

Ceci est ma première soumission de code golf. Je suis sûr que nous pourrions en faire plus. Il lit l'entrée comme argument de ligne de commande. Code de bière «emprunté» à la réponse Java «99 bouteilles de bière» (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);}}}

Faites-moi savoir si les arguments de la ligne de commande ne sont pas acceptables. C'était très amusant!

Rohan Jhunjhunwala
la source
Les CLA vont bien. Bonne réponse.
Rɪᴋᴇʀ
0

Excel VBA, 489 octets

Indenté:

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

(en retrait pour la lisibilité)

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

Renommer l' appel Module1 en M par défaut
avec h "+++++++++Your Code"
Cela fonctionnera également sur d'autres applications bureautiques, en remplaçant ActiveWorkbook par le type de document approprié

SeanC
la source
Notez qu'Excel ajoutera des espaces et étendra les abréviations, donc dans Excel, le code est de 531 caractères
SeanC
C'est 636 personnages
Oliver Ni
Supprimer tous les espaces blancs de mon indentation, @oliver
SeanC
Vous pouvez perdre 3 octets en convertissant toutes les instances de For n=1 Toen For n=1To(en supprimant les espaces avant To) et 4 octets en convertissant toutes les instances de Debug.? 2;enDebug.?2; (supprimer les espaces après le ?mot clé)
Taylor Scott