8
\$\begingroup\$

Your task is "simple" should you choose to accept it.

Write an HQ9+ compiler in a language of your choice.

HQ9+ has four commands (as you may be able to tell) H prints "Hello, World!" Q prints out the source code (this can either be the compiled source or HQ9+ source for the purpose of this challenge),9 prints out the lyrics to 99 bottles of beer on the wall, and + is essentially a noop.

Your submission should be written in some language X, and should take input of HQ9+ source and output a program in X.

Wait, I know what you're thinking. This is not a duplicate of Creating a HQ9+ interpreter as it should not run HQ9+ code, but rather compile it. It should output a fully functional program.


Rules

  1. Language X should satisfy the traditional definition of a language
  2. Standard loopholes disallowed
  3. This is code golf (shortest program in bytes wins)
  4. Your solution must be testable
  5. X cannot be HQ9+ or an extension of HQ9+


Clarifications

There has been some confusion as to what the q command should do. I had originally thought that it would output the compiled code (i.e code in langauge X), but my reference implementation outputs the hq9+ code. I would like to see either one depending on your golfing preferences.

\$\endgroup\$
23
  • \$\begingroup\$ What would HH produce? \$\endgroup\$
    – Leaky Nun
    Jul 1, 2016 at 0:07
  • 4
    \$\begingroup\$ This would be a perhaps better challenge for languages X and Y to be the same. \$\endgroup\$ Jul 1, 2016 at 0:22
  • 4
    \$\begingroup\$ Should Q output the source of the input program, or the compiled program? \$\endgroup\$ Jul 1, 2016 at 1:05
  • 6
    \$\begingroup\$ The post would benefit from the inclusion of HQ9+ specs. \$\endgroup\$
    – Fatalize
    Jul 1, 2016 at 6:16
  • 2
    \$\begingroup\$ This should stay closed. If you can interpret HQ9, then all you have to do is stringify the commands used in your code and output them at the correct moments. \$\endgroup\$
    – Riker
    Apr 11, 2017 at 3:27

5 Answers 5

11
\$\begingroup\$

Actually, 17 bytes

"HQ9"∩εj'N'9(t'.j

Try it online!

This program compiles HQ9+ to Actually.

Actually is (almost) a superset of HQ9+ - the only difference is that the 9 command in HQ9+ is N in Actually. Because + is a NOP in HQ9+ (the accumulator is never actually used or displayed, and thus many implementations treat it as a NOP), it is stripped out.

Explanation:

"HQ9"∩εj'N'9(t'.j
"HQ9"∩εj           strip all characters not in "HQ9", preserving order
        'N'9(t     replace all occurrences of "9" with "N"
              '.j  insert a "." between every pair of characters

-1 byte from Christian Irwin

\$\endgroup\$
7
  • \$\begingroup\$ You... you are good. \$\endgroup\$ Jul 1, 2016 at 0:21
  • \$\begingroup\$ Impressed! Only 533 more bytes of golf needed on my java solution! \$\endgroup\$ Jul 1, 2016 at 0:49
  • \$\begingroup\$ Superset for the win! I've been watching your language for some time, quite interesting xD \$\endgroup\$
    – busukxuan
    Jul 1, 2016 at 4:54
  • \$\begingroup\$ Isn't Actually a variant of HQ9+, since it contains commands that do all of HQ9+'s specification? \$\endgroup\$ Jul 1, 2016 at 22:36
  • \$\begingroup\$ @VTCAKAVSMoACE Actually contains the HW, Quine, and NNBB commands, but does not have an "increment accumulator" command. Additionally, since the NNBB command is N instead of 9, it's not quite an extension/variant/superset. The need to explicitly print with . between every command further differentiates Actually from HQ9+ (since H and N don't do the HW and NNBB commands if the stack is not empty). \$\endgroup\$
    – user45941
    Jul 1, 2016 at 22:38
5
\$\begingroup\$

Java only 551 bytes

Joined in on the fun! This is a java compiler which compilers HQ9+ to java.Java is not verbose at all. Some code shamelssly stolen borrowed from "99 Bottles of Beer".


public class a{public static void main(String[]a){System.out.printf("public class a{public static void main(String[]z){String p=\"%s\";for(char a:p.toCharArray()){if(a=='H')p(\"Hello, World\\n\");if(a=='Q')p(p);if(a=='9'){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);}}}}public static void p(String s){System.out.print(s);}}",a[0]);}}
\$\endgroup\$
3
\$\begingroup\$

Mathematica, 453 bytes

"("<>#~StringReplace~{"H"->"Print[\"Hello, world!\"]; ","Q"->"Print[ToString[#0, InputForm]]; ","9"->"a = StringJoin[ToString[#1], {\" bottle\", If[#1 < 2, \"\", \"s\"], \" of beer\"}] & ; b = StringJoin[a[#1], \" on the wall\"] & ; Do[Print[b[i], \", \", a[i], c = \".\n\", If[i < 2, StringJoin[\"Go to the store and buy some more, \", b[99], \".\"], StringJoin[\"Take one down and pass it around, \", b[i - 1], c]]], {i, 99, 1, -1}]; ",_->""}<>") & "&

"99 Bottles" code adapted from @alephalpha's program. Outputs a function that, when run, will print the output. (Could probably still find a less verbose quine method.)

\$\endgroup\$
2
  • \$\begingroup\$ Looks like you missed the rule change - solutions must compile HQ9+ to the same language as the compiler. \$\endgroup\$
    – user45941
    Jul 1, 2016 at 0:51
  • \$\begingroup\$ @Mego Fixed that \$\endgroup\$ Jul 1, 2016 at 1:15
2
\$\begingroup\$

Haskell, 383 bytes

    s#'Q'="putStrLn\""++s++"\"\n"
    s#'H'="putStr\"Hello, World\\n\"\n"
    s#'9'="f\n"
    s#_=""
    c s="o=\" of beer on the wall\"\na 1=\"1 bottle\" \na n=shows n\" bottles\"\nb 1=\"Go to the store and buy some more, \"++a 99\nb n=\"Take one down and pass it around, \"++a(n-1)\nf=putStr$[99,98..1]>>= \\n->[a n,o,\", \",a n,\" of beer.\\n\",b n,o,\".\\n\\n\"]>>=id\nmain=do\n"++(concat.map(s#)$s)

Thanks to nimi for the beer.

Sample outout

o=" of beer on the wall"
a 1="1 bottle" 
a n=shows n" bottles"
b 1="Go to the store and buy some more, "++a 99
b n="Take one down and pass it around, "++a(n-1)
f=putStr$[99,98..1]>>= \n->[a n,o,", ",a n," of beer.\n",b n,o,".\n\n"]>>=id
main=do
putStr"Hello, World\n"
putStrLn"HQ9+"
f
\$\endgroup\$
1
\$\begingroup\$

Dyalog APL, 244

H P
h←'''hello, world'''
q←M,(P/⍨1+P=M),M←''''
n←'∊{z←8↑k←'' of beer on the wall''⋄r←{r←'' bottles''↑⍨8-⍵=1⋄⍵=0:''No'',r⋄r,⍨⍕⍵}⋄m,k,g,(m←r⍵),z,g,''Take one down and pass it around'',z,g,(r⍵-1),k,g,g←3⌷⎕tc}¨⌽⍳99'
⎕FX'F',h h q q n''['HhQq9'⍳P]

This is a tfn H, which takes a HQ9+ program as its input and defines in the workspace a tfn F, which runs that program.

Example:

      H 'QhqH' ⍝ compile 'QhqH'
      F ⍝ run compiled function F
QhqH
hello, world
QhqH
hello, world
      ⎕CR 'F' ⍝ source code for function F
 F             
 'QhqH'        
 'hello, world'
 'QhqH'        
 'hello, world'
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.