Crear un intérprete HQ9 +

31

El objetivo de este código de golf es crear un intérprete para el lenguaje de programación HQ9 +
Hay 4 comandos en este lenguaje de programación:

  • H - imprime "¡Hola, mundo!"
  • Q : imprime el código fuente del programa
  • 9 - imprime la letra de la canción "99 botellas de cerveza"
  • + - incrementa el acumulador

Las normas:

  1. Como el acumulador no está definido, puede ignorar el comando +
  2. Su programa debe solicitar la entrada (esta entrada será el código fuente) o el código fuente se lee desde un archivo
  3. No está permitido poner la letra de "99 botellas de cerveza" en un archivo, y leer el texto del archivo
  4. No puede utilizar un algoritmo de compresión como GZip o BZip para comprimir el texto de la canción: debe crear su propio algoritmo de compresión. Esto no tiene que ser un algoritmo complejo, pero intente comprimir el texto tanto como sea posible (recuerde: este es un código de golf, gana el código con la menor cantidad de bytes)
  5. Si el código fuente contiene un carácter que no es H , Q , 9 o + , ¡entonces la salida "El código fuente contiene caracteres no válidos" antes de ejecutar cualquier comando! Esto significa que, si el código fuente es, H1por ejemplo, no emita Hello, world!antes de la salida Source code contains invalid characters. No, salida inmediataSource code contains invalid characters
  6. Si su intérprete acepta caracteres en mayúscula y minúscula, entonces obtiene -8 en su recuento de caracteres

¡Buena suerte!

ProgramFOX
fuente
3
La regla 4 no tiene sentido en el "¿por qué prohibiría eso?" nivel; la regla 5 no tiene sentido en el "¿qué quiere decir?" nivel.
Peter Taylor
44
¿Cómo no tiene sentido la regla 5?
Mike C
Creo que sería mejor simplemente requerir que solo use mayúsculas, en lugar de decir arbitrariamente que obtienes 8 caracteres libres si acepta cualquiera. 8 puede o no cubrirlo dependiendo del idioma.
Mike C
10
La regla 5 no tiene sentido porque rompe la especificación HQ9 +.
stand
2
Un intérprete en HQ9 + debería ganar automáticamente.
TheNumberOne

Respuestas:

16

APL (Dyalog) (326-8 = 318)

Pégalo en una ventana del editor y llama H. La entrada se toma del teclado.

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

Mathematica, 349346341 caracteres

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
fuente
Muy impresionante, pero parece que hay algunos gliches menores. 'H ["Q"] genera "Q". h ["9"] funciona, pero h [9] genera todo el programa (no entiendo cómo).
DavidC
@DavidCarraher Produce código debido a cómo StringMatchQ y If falla:If[StringMatchQ[3, "a"], x, y]
ssch
6

C, 599 587 487 481 467 caracteres

Estoy seguro de que esto puede ser mejor. Estoy usando C después de todo. Hay una razón por la que no ves muchas entradas de golf ganadoras escritas en C. Esto ahora tiene 467 caracteres gracias al abuso criminal de #define.

Especifique el archivo fuente HQ9 + como argumento de línea de comando.

EDITAR: ahora acepta la fuente de stdin, no un archivo. Iniciar el programa, comience a escribir el código, CTRL- Ccuando se hace para ejecutarlo.

Compila al menos en MinGW / GCC con: gcc -o hq9+.exe hq9+.c

Debería funcionar en MSVC, pero no tenía ganas de crear una solución completa solo para esto. :)

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

O:

#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
fuente
Lo redujo a 487 caracteres mediante el uso de stdin en lugar de un archivo para la entrada.
Mike C
Haz que 464 abusando de #define.
Mike C
Podrías deshacerte de espacios, como los que están después Cy un par antes R;. También podría eliminar 8 caracteres p[s++]=0;después del bucle de entrada para simplificar la impresión 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 Ya estaba mal, pero luego descubrí un error que me costó un byte para solucionarlo. Bleh

(No solía incluir +en la salida para Q. Una entrada de Q+++dio la salida Q, por ejemplo).

Guarde algunos caracteres al no salir de una entrada no válida como pensé que se suponía que debía hacer

Versión explicada próximamente.Me di por vencido. Apenas entiendo cómo funciona esta monstruosidad. Si hay demanda, lo intentaré otra vez, pero hasta entonces no está sucediendo.

monorraíl subterráneo
fuente
No exitutiliza el carácter no válido, solo muestra el mensaje, para que pueda guardar 7 caracteres allí.
Kyle Kanos
@KyleKanos Oh, entendí mal eso. ¡Gracias!
undergroundmonorail
Sus letras no son correctas - actualmente dice: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *99* bottles of beer on the wall. se supone que debe decir: 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
También da un error cuando entro +. Se supone que debes ignorar + , no dar un error
Oliver Ni
Tampoco se supone que haya nada entre salidas. Como si entro HQHHdebería decirHello 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}

Expandido:

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

Rubí, 364 360-8 = 352

Todavía tiene mucho margen de mejora. Código de 99 botellas robadas de aquí .

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
Pomo de la puerta
fuente
Se supone que debe haber No more bottles of beer on the walldespués de la 1 bottlesección. entonces 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 La pregunta no especifica la letra exacta de la canción. En ningún lugar requiere que se incluya la sección "no más".
Pomo de la puerta
Ok, pero también, no se supone que haya una nueva línea entre salidas.
Oliver Ni
@ Oliver ¿Dónde dice eso el desafío?
Pomo de la puerta
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

Esto es bastante sencillo. %devuelve la salida de un comando (dado el código fuente para usar en Q). ddevuelve la canción de 99 botellas con una línea de basura al comienzo por razones de golf. todo está envuelto en una interacción (es posible que desee usar en glugar de mainal probar)

orgulloso Haskeller
fuente
¿Cómo debo ejecutarlo? Intenté pegarlo en WinGHCi, pero lo consigo <interactive>:8:5: parse error on input ‘=’.
ProgramFOX
@ProgramFOX no tengo idea ... Comprobaré cuando pueda
orgulloso Haskeller
@ProgramFOX lo siento, tomó mucho tiempo :-). no estás usando GHCi correctamente. en GHCi no puede ingresar definiciones directamente ya que espera expresiones. puede usar a letpara insertar definiciones (esto se rompe al insertar múltiples definiciones no separadas por ;) o ejecutar el código desde un archivo.
orgulloso Haskeller
Veo. Sin embargo, todavía no intento ejecutarlo; cuando cargo el archivo y llamo main, dice que el código fuente contiene caracteres no válidos cuando intento ejecutar H. Cuando intento ejecutar en glugar de main, inmediatamente me da un error.
ProgramFOX
@ProgramFOX mainno funciona porque la nueva línea agregada no es un comando legal. Es por eso que recomendé usar en su glugar. En cuanto a g, ¿ putStrLn $ g "H" no funciona correctamente?
orgulloso Haskeller
2

J - 444 bytes

Me gustó el número, así que dejé de jugar al golf. ¡Aquí tienes, función de expresión única!

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

Ejemplos:

   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
fuente
Y no, no escribiré una explicación para esto. Demasiado largo.
verqu
Espera, ¿por qué se rechaza esto?
seequ
2

Fortran 528 470 481

Requiere compilar con -fppflag (+3 para calificar) 1 para usar directivas de preprocesamiento (lo que ahorra más de 3 caracteres, así que estoy totalmente de acuerdo con eso). También es insensible a mayúsculas y minúsculas, por lo que hay -8: D. Se guardaron 5 caracteres al no procesar previamente el endifque se usa una vez de todos modos .

Requiere que el archivo tenga una .F90extensión (tiene sentido llamarlo hq9+.F90) para que el compilador fuerce el preprocesamiento. El código distingue entre mayúsculas y minúsculas; hacer que no distinga entre mayúsculas y minúsculas agrega algo así como 16 caracteres, por lo que realmente no vale la pena guardar 8 caracteres. Mi respuesta anterior no tenía en cuenta los plurales cambiantes de bottlesfor 9; esta versión lo corrige (y lamentablemente agrega muchos más caracteres).

#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

Se ve mucho mejor sin golf y sin preprocesar (probablemente porque puedes ver lo que está sucediendo):

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
fuente
Creo que es aceptable requerir una extensión específica para que el compilador sepa lo que está compilando. Un análogo puede requerir que se nombre un archivo C ++ .ccpara evitar necesitar la -lstdc++bandera.
primo
2

Pitón 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
fuente
1

Lua 443 - 8 = 435 464 - 8 = 456

Logré guardar 21 caracteres usando múltiples if-ends en lugar de if-elseif-end. También tuve algunos espacios en blanco adicionales flotando después de algunos ).

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

Estoy bastante contento con este, aunque no es mucho más corto que mi respuesta de Fortran . El código de 99 botellas de cerveza ha sido modificado a partir de esta respuesta por Alessandro . Sin golf, tenemos

-- 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
fuente
El código para minúscula la entrada cuesta 12 caracteres, por lo que la bonificación no vale la pena.
nyuszika7h
No necesita poner en minúscula la entrada, simplemente puede hacer algo comoif s in'Hh'
Oliver Ni
Ahorra 8 caracteres
Oliver Ni
@MCParadox: Er, eso es Python en lo que estás pensando, Lua ines para iteradores for-loop y no para comparaciones; obtendrá un error si lo pega allí. Aquí hay tres opciones: (1) usar matchen cada línea, (2) usuario s=='h'or s=='H'en cada línea, (3) hacerlo como lo hice. Claramente (3) es más corto que (1) y (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
fuente
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."}}

Solo un poco golf, aún más pequeño que C y las 99 botellas correctas de cerveza terminan el verso.

Johannes Kuhn
fuente
Bien, ahora ese es legítimo. Buen trabajo, me ganaste. Debería dejar de usar C para el golf.
Mike C
Puede eliminar la primera línea e incrustarla en el último parámetro de regexp. Puede obtener mi golf de 99 cervezas en 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``}

No opté por las mayúsculas y minúsculas, habría costado demasiados caracteres. Ni siquiera cerca de algunas de las otras entradas, ¡pero fue divertido!

JavaScript, 344

Hice una versión con una versión menos completa de la canción:

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

pero después de ver las otras entradas (y mirar las letras reales, ¡quién sabe!), ¡pensé que era un poco policial!

Dom Hastings
fuente
Debería ser Go to the store, buy some more, *99* bottles of beer on the wall, no*No more* bottles of beer on the wall
Oliver Ni
Si compra un poco más, ¿cómo puede no haber más?
Oliver Ni
Y Qtampoco funciona para mí.
Oliver Ni
@Oliver no se dio cuenta de que comentabas sobre esto en ese momento ... No entendí totalmente cuándo Qse suponía que debía hacerlo en ese momento y proporcioné el código fuente de la función en lugar de la entrada ... Esa fue originalmente mi razón para hacerlo en JS, esa parte sería fácil, sin embargo, ahora sé que eso no es lo que se requiere.
Dom Hastings
¡@Oliver actualizó la letra!
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]:""));}}

Como un programa completo. El primer argumento es el programa HQ9 +. Con un acumulador real. Me desafié a mí mismo a no usar declaraciones definitorias.

Versión sin golf:

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

Java, 546 bytes

Esta es mi primera presentación de código de golf. Estoy seguro de que podríamos hacer más con eso. Lee la entrada como el argumento de la línea de comando. Código de cerveza "prestado" de "99 Botellas de cerveza" respuesta de Java (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);}}}

Avíseme si los argumentos de la línea de comando no son aceptables. ¡Esto fue muy divertido!

Rohan Jhunjhunwala
fuente
CLA están bien. Buena respuesta.
Rɪᴋᴇʀ
0

Excel VBA, 489 bytes

Sin sangría:

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

(sangrado para facilitar la lectura)

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

Cambie el nombre de la llamada predeterminada del Módulo 1 a M
con h "+++++++++Your Code"
Esto también funcionará en otras aplicaciones de oficina, cambiando ActiveWorkbook al tipo de documento apropiado

SeanC
fuente
tenga en cuenta que Excel agregará espacios y expandirá las abreviaturas, por lo que dentro de Excel, el código es 531 caracteres
SeanC
Son 636 personajes
Oliver Ni
Eliminar todo el espacio en blanco de mi sangría, @oliver
SeanC
Puede perder 3 bytes al convertir todas las instancias de For n=1 Toa For n=1To(eliminar espacios en blanco antes To) y 4 bytes al convertir todas las instancias de Debug.? 2;a Debug.?2;(eliminar espacios en blanco después de la ?palabra clave)
Taylor Scott