39
\$\begingroup\$

Write a cat program, a quine, and a Hello World in the same language such that when two specific programs of the three are concatenated in a certain order, you get the third program. It does not matter which program is the first, second, and third are as long as all three types are represented once each.

e.g. if \$A\$ is a cat and \$B\$ is a quine then \$AB\$ is Hello World. Alternatively, if \$A\$ is Hello World and \$B\$ is a cat then \$AB\$ is a quine. You only need to make one permutation of the possible 6 work.

For completeness of explanation:

  • A cat program outputs the input exactly
  • A quine is a program that outputs its own source code
  • A hello world program outputs the string "Hello World!"

Rules, Scoring, Formatting

  • Shortest code wins. Scoring goes by the length of the concatenated program, i.e. the longest of the three.
  • Standard rules and loopholes apply.
  • The hello world program and quine might possibly receive input. You must output the appropriate text regardless of what is given as input.
  • Programs may output a trailing newline.
  • You can treat all three programs as if they are surrounded by your language's function closure (please specify the name of your implicit argument in this case) or main function boilerplate if that is required for your solution to work. Use the same convention for all three programs. The quine should not contain the boilerplate in this case.

Format the header of your answer like this:

<first type> + <second type> = <third type>, <language>, <score>

or

<language>, <first type> + <second type> = <third type>, <score>

\$\endgroup\$
19
  • \$\begingroup\$ So iff two programs are put together into one file, they will create the third program. Is my inference correct? \$\endgroup\$
    – Razetime
    Aug 3, 2020 at 16:15
  • 3
    \$\begingroup\$ Can we assume that no input is given for the quine and hello world programs? \$\endgroup\$ Aug 3, 2020 at 16:55
  • \$\begingroup\$ Just to clarify, but if cat + quine = hello world, then do we also need cat + hello world = quine and quine + hello world = cat to work? Also, we only need to write two programs + the concatenation of the two? \$\endgroup\$
    – TehPers
    Aug 3, 2020 at 18:46
  • 3
    \$\begingroup\$ @TehPers No. You only need one of the following to work: C + Q = H, C + H = Q, H + Q = C, H + C = Q, Q + C = H, Q + H = C. \$\endgroup\$
    – Beefster
    Aug 3, 2020 at 18:56
  • 1
    \$\begingroup\$ I'd really like to see this done in Befunge. You should be able to use the misalignment and wraparound properties to route the cursor to the appropriate subprogram when concatenated. \$\endgroup\$
    – Beefster
    Aug 4, 2020 at 22:57

29 Answers 29

23
\$\begingroup\$

Python 3, Hello World + Quine = Cat, 129 bytes

Hello World:

import os,atexit as a
p=print
a.register(p,"Hello World!")
def print(_):
 p(input())
 os._exit(0)

Quine:

s='s=%r;print(s%%s)';print(s%s)

Cat:

import os,atexit as a
p=print
a.register(p,"Hello World!")
def print(_):
 p(input())
 os._exit(0)
s='s=%r;print(s%%s)';print(s%s)

atexit lets you define cleanup steps that will run when your program exits "normally". In this case, I register the print function (renamed p) with the argument "Hello World!", so it will print that string when the program ends.

I then redefine print to become a cat function. Normally, this would cause the program to print its input and "Hello World!", but os._exit() is an "abnormal" exit that bypasses the cleanup steps.

Now that print has been redefined, the Quine simply calls this cat function and the program abruptly exits. If the Quine doesn't exist, then the program exits normally, printing "Hello World!" in the process.

The final program doesn't work on TIO, but it works for me running Python 3.7.3 on MacOS.

\$\endgroup\$
4
  • \$\begingroup\$ Nice approach! Suggestion for -1 byte: tio.run/… \$\endgroup\$ Aug 3, 2020 at 21:25
  • 6
    \$\begingroup\$ def print(_):p(input());os._exit(0) saves two more. \$\endgroup\$ Aug 4, 2020 at 19:48
  • \$\begingroup\$ Doesn't print(input()) ignore lines beyond the first? (For some reason, your TIO link isn't working on my machine). Regardless, nice answer. \$\endgroup\$
    – Quelklef
    Aug 15, 2020 at 17:13
  • \$\begingroup\$ Oh, I see, you noted that it doesn't work on TIO. \$\endgroup\$
    – Quelklef
    Aug 15, 2020 at 17:20
12
\$\begingroup\$

Bash, Quine + Cat = Hello World, 110 bytes

Quine

q='eval printf "$s" "$s"';s='q=\47eval printf "$s" "$s"\47;s=\47%s\47;$q';$q

Cat

true false&&cat||echo Hello World!

Hello World

q='eval printf "$s" "$s"';s='q=\47eval printf "$s" "$s"\47;s=\47%s\47;$q';$qtrue false&&cat||echo Hello World!

This takes advantage of the fact that undefined variables expand to the empty string and that true is a command that can take arguments.

You can trivially swap the cat and the hello world by swapping true and false

\$\endgroup\$
11
\$\begingroup\$

R, Quine + hello, world = cat; 48 + 49 ... 43 + 44 = 87 bytes

Or 75 bytes as internal code of functions and not including function(){} wrappers.

Edit: -14 bytes thanks to Robin Ryder!

Nontrivial quine:

'->T;cat(sQuote(T),T)' ->T;cat(sQuote(T),T)

Try it online!

Hello,world:

~F->y;cat(`if`(T>0,"Hello world!",scan(,T)))

Try it online!

Cat:

'->T;cat(sQuote(T),T)' ->T;cat(sQuote(T),T)~F->y;cat(`if`(T>0,"Hello world!",scan(,T)))

Try it online!

A 'trivial quine' version could be Quine = ~1, and Hello, world = +F->y;cat(`if`(y<0,scan(,''),'Hello world!')), for 2+45=47 bytes.

How? (nontrivial & trivial versions)

The default behaviour of R is to output any unassigned values (such as variables or expressions). So, to print a quine, we simply need to generate an expression containing the program code, and it is output by default (this applies both to the nontrivial quine, which is contructed using cat to join the various text elements together, as well as the trivial quine ~1 consisting simply of a formula which is outputted)

If a value is assigned to a variable, it is not output. So to stop the quines from printing, we incorporate them into an expression and assign this to the variable y.

To do this, we need to use a binary operator, but since this operator will also appear at the start of the 'Hello, world' program, it must also function as a unary operator. Both the ~ (formula) and + (positive/sum) operators have this property.

Conveniently, R also includes a (little used outside coding challenges) left-to-right assignment operator, ->, which - together with a unary/binary operator - lets us package the quine into the variable y & forget about it. Then all we need to do is to determine whether this has happened or not, and use this to switch between 'Hello, world' and 'cat' behaviour.

\$\endgroup\$
17
  • 1
    \$\begingroup\$ Good to see the nontrivial quine. But it looks like it outputs an extra semicolon at the end? \$\endgroup\$
    – Dingus
    Aug 3, 2020 at 18:25
  • \$\begingroup\$ Thanks! I left it in from a previous version! You've saved me a byte! \$\endgroup\$ Aug 3, 2020 at 18:29
  • \$\begingroup\$ All three programs output an extraneous [1] . \$\endgroup\$ Aug 4, 2020 at 5:32
  • 1
    \$\begingroup\$ @Dingus: thanks for spotting that. It was a consequence of the R session locale configured on TIO. I've fixed it now (by resetting the default session locale). \$\endgroup\$ Aug 4, 2020 at 8:01
  • 1
    \$\begingroup\$ Also, scan(,"") can be scan(,T) for -1 byte: in the only case where you need scan, T is of mode character and can therefore be used as the second argument to scan. \$\endgroup\$ Aug 6, 2020 at 14:11
8
\$\begingroup\$

Quine + Cat = Hello World, Jelly, 25 bytes

-2 bytes thanks to @Jonathan Allan

Quine (12 bytes)


“Ṿṭ⁷;⁾v`”v`

(starts with a newline)

Try it online!

Cat (13 bytes)

Ṇ
“,ḷṅḳȦ»³ÑƑ?

Try it online! (argument quoted to avoid casting to a Python object from string as per @Jonathan Allan's suggestion)

Hello World (25 bytes)


“Ṿṭ⁷;⁾v`”v`Ṇ
“,ḷṅḳȦ»³ÑƑ?

(starts with a newline)

Try it online!

How it Works

In Jelly, the last link (last line) is always executed as the main link. The Cat and Hello World have the same last link, so they are differentiated by the value of the first link (blank (identity) or (logical not)).

“,ḷṅḳȦ»³ÑƑ?
          ?  # If
        ÑƑ   # The first link is the identity
“,ḷṅḳȦ»        # Return "Hello World!" (String Compressor: https://codegolf.stackexchange.com/a/151721/68261)
             # Else
       ³       # Return the input

The quine is slightly difficult because it needs to prepend a blank line.

“Ṿṭ⁷;⁾v`”v` 
“Ṿṭ⁷;⁾v`”     # Set the string "Ṿṭ⁷;⁾v`"
         v`   # Eval it on itself:
 Ṿṭ⁷;⁾v`
 Ṿ              # Uneval: "“Ṿṭ⁷;⁾v`”"
  ṭ⁷            # Prepend a newline "¶“Ṿṭ⁷;⁾v`”"
    ;⁾v`        # Concatenate "v`" to get "¶“Ṿṭ⁷;⁾v`”v`"
\$\endgroup\$
4
  • \$\begingroup\$ 25 bytes \$\endgroup\$ Aug 4, 2020 at 23:25
  • \$\begingroup\$ We should probably use ƈȮ¤L¿ rather than ³, since arguments to a program are evaluated if possible TIO \$\endgroup\$ Aug 5, 2020 at 23:07
  • \$\begingroup\$ I enquired and the OP has allowed formatted input, so we can use ³ even though it's not strictly speaking a Cat program - you should quote your example command-line arguments though as it is necessary for anything that is valid Python code. \$\endgroup\$ Aug 6, 2020 at 18:09
  • \$\begingroup\$ @JonathanAllan edited. Under the definition in the post of "A cat program outputs the input exactly," it is strictly speaking a cat program (using standard I/O formats), even though it would not qualify for the stricter rules of codegolf.stackexchange.com/questions/62230/simple-cat-program \$\endgroup\$ Aug 6, 2020 at 22:14
8
\$\begingroup\$

Wolfram Language (Mathematica), Quine + Cat = Hello World, 15+28=43 15 + 22 = 37 bytes

3 functions.

Quine

ToString[#0] & 

Try it online!

Cat

#/.#_:>"Hello World!"&

Try it online!

Hello World

ToString[#0] & #/.#_:>"Hello World!"&

Try it online!


HW+Q=C,46+58=104 Q+C=HW,43+48=91 Cat + Quine = Hello World, 49 + 37 = 86 bytes

Cat

Print[#/._@_->"Hello World!"]&@$ScriptInputString

Try it online!

Quine

Print[ToString[#0, InputForm][]] & []

Try it online!

Hello World

Print[#/._@_->"Hello World!"]&@$ScriptInputStringPrint[ToString[#0, InputForm][]] & []

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Rust, Quine + Cat = Hello, world! (106 + 2 = 108 bytes)

Quine (108 106 bytes):

-2 bytes: removed ',' from "Hello world!"

let s=format!("Hello world!");format!("{},{0:?})","let s=format!(\"Hello world!\");format!(\"{},{0:?})\"")

.into() instead of format! saves a few bytes but is context-dependent.

Cat (2 bytes):

;s

Quine + Cat = Hello, world! (110 108 bytes):

let s=format!("Hello world!");format!("{},{0:?})","let s=format!(\"Hello world!\");format!(\"{},{0:?})\"");s

Try it!

Updated to not use include_str!. Hopefully this doesn't break any rules anymore.

This relies on it being in a closure/function that implements Fn(String) -> String with argument s.


Old answer, uses include_str!:

Quine (67 bytes):

match include_str!("f"){p@_ if p.len()==67=>p,_=>"Hello, world!"}//

(Not very creative, unfortunately)

Cat (1 byte):

s

Quine + Cat = Hello, world! (68 bytes):

match include_str!("f"){p@_ if p.len()==67=>p,_=>"Hello, world!"}//s

Try it! (Repl.it link due to multiple files)

This depends on the code being in its own file named "f" and being include!'d into main.rs before being executed. The Repl.it link has the programs in separate files with different names, which means that the quine and hello world programs are different by one character so that they include the correct string.

This challenge was especially difficult in Rust (without using a comment at the end of one of the programs) because of the syntax of the language. Functions and multi-statement closures have braces surrounding them, so you can't just concat two closures to get a third, unfortunately.

\$\endgroup\$
6
  • \$\begingroup\$ I'm pretty sure your strategy falls under the category of banned loopholes. You might have to use stdin/stdout for Rust. \$\endgroup\$
    – Beefster
    Aug 3, 2020 at 20:11
  • \$\begingroup\$ I added the rule "You can treat all three programs as if they are surrounded by your language's function closure (please list which name is the implicit argument) if using a function definition/lambda/closure as your program convention." to (hopefully) make cases like this easier. \$\endgroup\$
    – Beefster
    Aug 3, 2020 at 20:16
  • \$\begingroup\$ @Beefster I'll update my code and the link in that case. \$\endgroup\$
    – TehPers
    Aug 3, 2020 at 20:45
  • \$\begingroup\$ I'll look for another quine that doesn't include itself then. \$\endgroup\$
    – TehPers
    Aug 3, 2020 at 21:01
  • 1
    \$\begingroup\$ yeah, it was the quine. Reading your own source code is a banned loophole. \$\endgroup\$
    – Beefster
    Aug 3, 2020 at 21:37
7
\$\begingroup\$

Python 2, Hello World + Cat = Quine, 200 198 189 bytes

Hello World

id=0;a="Hello World!";a0='id=0;a="%s";a0=%r;print a0%%((a,a0)if id<1else 1)\nimport sys\nif id:print sys.stdin.read()';print a

Cat

0%((a,a0)if id<1else 1)
import sys
if id:print sys.stdin.read()

My previous answer was actually wrong. raw_input only reads one line. This reads the entire input.

Quine

id=0;a="Hello World!";a0='id=0;a="%s";a0=%r;print a0%%((a,a0)if id<1else 1)\nimport sys\nif id:print sys.stdin.read()';print a0%((a,a0)if id<1else 1)
import sys
if id:print sys.stdin.read()

Try it online!


2020-08-05: -42 bytes thanks to Jonathan Allen, +33 to fix a bug

\$\endgroup\$
3
  • \$\begingroup\$ Save 42 by using id like so. \$\endgroup\$ Aug 4, 2020 at 18:57
  • \$\begingroup\$ a few ameliorations : - by replacing "Hello World!"by 'Hello World!'you can then replace a="%s" by a=%r saving 2 bytes - (a,a0)if id<1else 1 can be simplified into id>1or(a,a0) saving 7 bytes * 2 - instead using the sys module which need an expensive import, you can print raw_input() to get a line from stdin. You will say that it doesn't work for multilines inputs and you will be true ... except if you use a while loop ^^ : replace import sys\nif id:print sys.stdin.read() by while id:print raw_input() and it does the trick saving 13 + 14 bytes Total : - 43 bytes \$\endgroup\$
    – Jakque
    May 8, 2021 at 1:08
  • \$\begingroup\$ I didn' have enough space in my previous comment, here is a link for the 146 bytes solution (46 bytes saved) : Try it online! \$\endgroup\$
    – Jakque
    May 8, 2021 at 1:11
7
\$\begingroup\$

Keg, Hello World + Quine = Cat, 26 bytes

«H%c¡|,!«``:[④|᠀,]`:[④|᠀,]

Try it online!

How it Works

Hello World

«H%c¡|,!«`

Try it online!

This is my answer to the HW challenge with some additional string closing syntax. Why? Because a) the main string needs closing to be concatenated and b) the end ``` is needed to "ignore" the quine part

Quine (non-trivial)

`:[④|᠀,]`:[④|᠀,]

Try it online!

`:[④|᠀,]`           

Push the string :[④|᠀,] to the stack

:[④|᠀,]

Duplicate the string and start an if-block. The if block uses the truthiness of the t.o.s to determine which branch is to be executed. In this case, the string is truthy, so the is executed (printing the string raw). Implicit output then prints the string nicely.

Concatenation

«H%c¡|,!«``

Push the string Hello, World! followed by an empty string onto the stack.

:[④|᠀,]

Duplicate the top of the stack (an empty string) and start the if block. Empty strings are considered falsey, so the ᠀, branch is executed. This takes input and prints it.

`:[④|᠀,]

Push the string :[④|᠀,] and don't do anything with it.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I'll upvote this tomorrow \$\endgroup\$ Aug 4, 2020 at 1:15
6
\$\begingroup\$

Python 3.8, Cat + Quine = Hello, 101 91 89 bytes

Cat (32 bytes)

a=id=""
while 1:a=input(a)+"\n";

Try it online!

Quine (57 bytes)

exec(s:='+input(id and"exec(s:=%r)"%s or"Hello World!")')

Try it online!

Hello World (89 bytes)

a=id=""
while 1:a=input(a)+"\n";exec(s:='+input(id and"exec(s:=%r)"%s or"Hello World!")')

Try it online!

How it works:

For the cat program:

  • a=id=0 we assign a and id to the empty string. id is now evaluated as False (remember it for later)
  • At the first loop of while 1: a=input(a)+"\n" will display a without a new line (so the empty string) and store in a the first line of the input plus a newline
  • Then we loop again, displaying the input of the previous iteration until the program has written all the lines of the input and crash (EOFError)

For the quine program:

  • The main structure of the quine is exec(s:='print("exec(s:=%r)"%s)'), a well known quine in python.
  • We uses input() instead of print() to avoid the trailing new line
  • the + at the start is here to make the program crash as soon as it finished printing to make sure the program ends.
  • id is a python built-in. Because of that it is evaluated as True so id and <code 1> or <code2> will be equal to <code 1> (which contains the code for our quine to work).

For the hello world program:

  • remember the cat program where we assigned id to the empty string?
  • id and <code 1> or <code2> will now execute <code2> since id is now evaluated as False, resulting the printing of Hello World!
  • The + crashes the program avoiding looping in the cat code again

Old solution: cat (37) + quine (64) = hello (101 bytes)

Here is my old solution using triple quoted string and comments to "squeeze" the quine part and directly printing "Hello World!". It uses some cool tricks with comments:

while p:=print:id or p(input());id=""									# cat (37 bytes)
                                     "";exec(s:='input(\'"";exec(s:=%r)\'%s)#"""-p("Hello World!")#')	# quine (64 bytes)
while p:=print:id or p(input());id="""";exec(s:='input(\'"";exec(s:=%r)\'%s)#"""-p("Hello World!")#')	# hello (101 bytes)

Try it online!

Who said that comments were not usefull in codegolfing?

\$\endgroup\$
2
  • \$\begingroup\$ May I ask why the variable has to be named id and can't be a single letter? Is it a special word to make your solution work? \$\endgroup\$
    – user
    May 9, 2021 at 15:18
  • 2
    \$\begingroup\$ I used the variable id because it is a built in function in python so bool(id) == True. If I used a unicharacter variable (let say i) the program will throw an error because i is not defined. It allow me to loop once into the while loop without triggering the input function. \$\endgroup\$
    – Jakque
    May 9, 2021 at 22:27
5
\$\begingroup\$

R, Quine (74 51 bytes) + Cat (77 74 bytes) = Hello world 151 125 bytes

R, Hello world (173 174 bytes) + Cat (77 74 bytes) = Quine 250 248 bytes

R, Quine (74 51 bytes) + Hello world (173 174 bytes) = Cat 247 225 bytes

A set of Quine, Cat & Hello world from which any 2 can be combined to form the third.

Not the shortest answer, but pleasingly symmetric.

Quine (74 51 bytes)

'->F;T=0;cat(sQuote(F),F)' ->F;T=0;cat(sQuote(F),F)

Try it online!

Cat (77 74 bytes)

~1->y;cat(`if`(T>1,sprintf(T,sQuote(T)),`if`(T,scan(,""),"Hello world!")))

Try it online!

Hello world (173 174 bytes)

~1->y;T='~1->y;T=%s;cat(`if`(F<0,scan(,""),"Hello world!"))~1->y;cat(`if`(T>1,sprintf(T,sQuote(T)),`if`(T,scan(,""),"Hello world!")))';cat(`if`(F<0,scan(,""),"Hello world!"))

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ I was hoping someone would make this, very awesome :D \$\endgroup\$ Feb 10, 2022 at 17:07
4
\$\begingroup\$

Aceto, quine (67) + cat (33) = Hello World (100 bytes*)

(*I counted one file including a final newline so that catting them together works as expected)

quine (made it for this challenge):

£"24«cs%55«3+cp24«2+cdpsdpsppn"24«cs%55«3+cp24«2+cdpsdpsppn

cat:

X


n
p el
r"HlX
^^ oldnp
 ^Wor!"

The quine itself was the hardest part, due to the nature of having code on a Hilbert curve (The "Hello World", and cat programs are trivial compared to it). The solution of having the concatenated program do something else than the parts is simple in Aceto: Because the (longer-line) quine enforces a square size of an even power of two (64 = 2^6), and the cat program has, on its own, a square of size 8x8 (8 = 2^3, an odd power of two), the instruction pointer starts moving in a different direction.

\$\endgroup\$
4
\$\begingroup\$

Alice, Cat + Quine = Hello World, 51 bytes

Cat: (With trailing newline)

\ >  "!dlroW olleH"d&O@
  ^/ v
  # < i

Try it online.

Uses # to skip the redirect west and instead hit the redirect south into the i, which pushes the input as a string to the top of the stack. The instruction pointer then reflects off the top and bottom boundaries of the grid, hitting the o and @ from the Hello World program, causing it to output the top of the stack as a string and then terminate. The code requires a trailing newline, which I couldn't get to display here in the code block.

Quine:

"!<@O&9h.

Try it online.

Just a standard Alice quine.

Hello World:

\ >  "!dlroW olleH"d&O@
  ^/ v
  # < i
"!<@O&9h.

Try it online.

The # is now used to skip the @ from the quine program, causing the instruction pointer to instead hit the redirect west, which passes through a mirror and hits two more redirects to hit a standard Alice Hello World program.

\$\endgroup\$
4
\$\begingroup\$

Hello World + Quine = Cat, C (GCC), 149 (81 + 68)

Hello World

a;main(s){a?read(0,&s,1)&&main(putchar(s)):puts("Hello World!");}
#define main m

Try it online!

Quine

a=1;main(s){printf(s="a=1;main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Try it online!

Cat (Hello World + Quine)

a;main(s){a?read(0,&s,1)&&main(putchar(s)):puts("Hello World!");}
#define main m
a=1;main(s){printf(s="a=1;main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Save a character with putchar(s) --> putc(s,1). \$\endgroup\$
    – bta
    Aug 6, 2020 at 15:57
  • \$\begingroup\$ @bta I get a segfault when I try that. I think it requires the FILE pointer (stdout), can't just use the file descriptor. \$\endgroup\$
    – rtpax
    Aug 6, 2020 at 16:31
4
\$\begingroup\$

><>, Quine + Cat = Hello World!, 48 bytes

Quine

"r00gol?!;40.

The classic ><> quine

Cat

"]v"i:0(?;o
>l?!;o
^"Hello World!"<

A simple cat program, loaded with some other code that isn't being run.

Hello World!

"r00gol?!;40."]v"i:0(?;o
>l?!;o
^"Hello World!"<

The quine part makes the instruction pointer stop interpreting "]v" as text, instead clearing the stack and moving down to the "Hello World!" printer.


Equivalently, the program can be written as

'rd3*ol?!;40.']v'i:0(?;o
>l?!;o
^"Hello World!"<

Which, as Jo King points out, avoids using the g code reflection instruction, arguably making the quine more genuine.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'd recommend switching the quine for 'rd3*ol?!;40. (with appropriate changes to the other programs) to avoid using g, which can be considered cheating \$\endgroup\$
    – Jo King
    Aug 5, 2020 at 11:59
  • \$\begingroup\$ @JoKing That's a very nice quine (a drop-in replacement even), although ' is arguably just as much "cheating" as g. \$\endgroup\$ Aug 5, 2020 at 15:18
  • \$\begingroup\$ There's been previous discussion on this, and the general consensus on CGCC was that g counts as cheating, while string literals aren't. (personally, I fall on the side of both being cheating, but that doesn't stop me abusing them) \$\endgroup\$
    – Jo King
    Aug 6, 2020 at 9:33
3
\$\begingroup\$

05AB1E, Quine + Hello World = Cat, 23 bytes

Quine:

2096239D20BJ

Try it online (with input) or try it online (without input).

Hello World:

I.gi”Ÿ™‚ï!

Try it online (with input) or try it online (without input).

Cat:

2096239D20BJI.gi”Ÿ™‚ï!

Try it online (with input) or try it online (without input).

(All three output with trailing newline.)

Explanation:

2096239       # Push integer 2096239
       D      # Duplicate it
        20B   # Convert it to base-20 as list: "D20BJ"
           J  # Join stack together: "2096239D20BJ"
              # (after which it is output implicitly as result)

I             # Push the input (or an empty string if none is given)
 .g           # Get the amount of items on the stack (which will be 1)
   i          # If this amount is 1 (which it always is):
    ”Ÿ™‚ï!    #  Push dictionary string "Hello World!"
              #  (after which it is output implicitly as result)

2096239D20BJ  # Same as above
I             # Push the input (or an empty string if none is given)
 .g           # Get the amount of items on the stack: 2
   i          # If this amount is 1 (which it isn't):
    ”Ÿ™‚ï!    #  Push dictionary string "Hello World!"
              # (implicit else:)
              #  (implicitly output the input we pushed earlier as result)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why ”Ÿ™‚ï! is "Hello World!".
Credit of the quine goes to @Grimmy's answer here.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ By rule 3, the Hello World program should work even if it's given input. "The hello world program and quine might possibly receive input. You must output the appropriate text regardless of what is given as input." \$\endgroup\$
    – Zgarb
    Aug 4, 2020 at 17:27
  • \$\begingroup\$ @Zgarb Correction, fixed at the cost of 2 bytes.. \$\endgroup\$ Aug 4, 2020 at 19:22
3
\$\begingroup\$

Jelly, Quine + Cat = Hello World! 17 bytes

Note that using a formatted input has been deemed valid and this entry takes input as a command-line argument formatted as a Python string. To have a pure-Cat program we'd need to use STDIN in Jelly, since it first attempts to evaluate any command-line argument as Python. This is achievable in 21 bytes with ”ṘṘ + ”1$0¡ƈȮ¤L¿“,ḷṅḳȦ»Ṇ? TIO.

”ṘṘ

Quine

1$0¡³“,ḷṅḳȦ»⁼?

Cat

”ṘṘ1$0¡³“,ḷṅḳȦ»⁼?0

Hello World!

How?

The shortest proper quine in Jelly is:

”ṘṘ - Main Link: any arguments
”Ṙ  - an 'Ṙ' character
  Ṙ - print Jelly representation of x (i.e. ”Ṙ) and yield x ('Ṙ')
    - implicit print (i.e. Ṙ)

To use it we need to not let the execute in the largest program.

One way to not execute a link is to follow it with - repeat zero times, but ¡ needs a link to repeat, like X0¡, so we make X equal 1$.

$ composes the preceding two links into a single monadic link and (slightly surprisingly) 1$ can start a full program, as a monad which yields \$1\$ but when repeated zero times it just yields whatever its left argument is.

As such starting a program which has one command-line argument with 1$0¡ applies 1$ zero times to that argument, i.e. is a no-op, giving the rest of the program that same left argument.

But when 1$0¡ is prefixed with ”ṘṘ we have the X (described earlier) equal to Ṙ1 which when applied zero times to ”Ṙ yields the character 'Ṙ'.

Since the character, 'Ṙ', is not equal to the right argument of the Main Link (which, when given a single command-line argument is that argument) since that is a list of characters, we can use equality, , to test, ?, (effectively) whether the prefix ”ṘṘ is present and either...

...Cat* (if not):

³ - yield the programs 1st command-line argument

...or Hello World!:

“,ḷṅḳȦ» - compressed string = "Hello World!"

* The Cat code for the 21 byte STDIN version is:

ƈȮ¤L¿ - niladic link (no arguments)
    ¿ - do...
  ¤   - ...instruction: nilad followed by link(s) as a nilad
ƈ     -   read a character from STDIN
 Ȯ    -   print & yield
   L  - ...while?: length (0 at EOF)

and we use the monad logical-NOT, , as our test since we get an implicit left argument of 0 with no command-line arguments and by this point gets an argument of 0 (0Ṇ = \$1\$ -> Cat) or 'Ṙ' (”ṘṆ = \$0\$ -> Hello World!).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Is a rather new Jelly builtin? I remember Jelly had a pretty short builtin with V before (6 bytes or so), but never seen the . Is it's usage for quines only, or can it also be used for other purposes? \$\endgroup\$ Aug 6, 2020 at 14:43
  • \$\begingroup\$ @KevinCruijssen No it's been there for many years, I do believe its raison d'etre was to make a terse proper quine and I've never used it for any other purpose (and most quine challenges require use of the “Ṿ...v`”v` construct to have a different payload anyway). \$\endgroup\$ Aug 6, 2020 at 16:54
3
\$\begingroup\$

Ruby, Cat + Quine = Hello World!, 100 97 96 bytes

Reading the source code is prohibited for quines but there is no such rule for Hello World! programs. We exploit this fact using Ruby's DATA/__END__ mechanism. If __END__ appears alone on any line in the code, execution terminates there. However, any further code is accessible via the constant DATA, which is initialised to a File object containing all of this non-executable 'data'.

Cat

$><<(DATA||=$<).read;a

Try it online!

The idiomatic ||= operator sets the value of the variable DATA only if it is not already defined. In this case, DATA is not defined because the program does not contain __END__. In effect, the first part of the code therefore reduces to $><<$<.read, where $< and $> point to STDIN and STDOUT, respectively. For later use, the final a (which is an undefined variable) throws an error, which is inconsequential here.

Quine

eval$s=%q($><<"eval$s=%q(#$s)
__END__
Hello World!")
__END__
Hello World!

Try it online! or verify quine.

All of the real work is done in the first line, which is a basic Ruby quine template. With __END__ now making an appearance, it shouldn't be too hard to see where this is going.

Hello World!

$><<(DATA||=$<).read;a
eval$s=%q($><<"eval$s=%q(#$s)
__END__
Hello World!")
__END__
Hello World!

Try it online!

Finally we have DATA and __END__ together. Unlike in the cat program, DATA is defined this time: it's a File object containing Hello World!. Once this has been printed, there is no further output because of the error thrown by the final a (undefined) in the first line.

\$\endgroup\$
2
\$\begingroup\$

Python 3, Cat + Quine = Hello World, 121 bytes

  • -2 bytes thanks to @Jo King

Cat:

Actual cat part is taken from the top comment of this SO answer.

If the file is long enough, switch to a Hello World program.

len(open(__file__).read())<99or~print('Hello World!')
import sys
print(sys.stdin.read())

The ~print exits the program after printing: print returns None and ~None throws. (Crashing to exit was allowed by OP in a comment.)

Quine:

Pretty standard. Originally wanted to use Python 3.8 := to do print((s:='print((s:=%r)%%s)')%s), but that was longer. Stole the use of ; instead of \n from one of the other Python answers.

s='s=%r;print(s%%s)';print(s%s)

Combined:

len(open(__file__).read())<99or~print('Hello World!')
import sys
print(sys.stdin.read())
s='s=%r;print(s%%s)';print(s%s)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Note that a quine must not access its own source, directly or indirectly. See also the Wikipedia entry for cheating quines \$\endgroup\$ Aug 14, 2020 at 15:40
  • \$\begingroup\$ Thanks for the info. I'll mark my submission as non-competing \$\endgroup\$
    – Quelklef
    Aug 14, 2020 at 20:53
  • \$\begingroup\$ Why not try to update the quine to make a competing entry? The +exit() approach seems nice, and that (rather than just making a quine) was supposed to be the main part of the challenge! \$\endgroup\$ Aug 15, 2020 at 8:44
  • \$\begingroup\$ It was because the challenge was already marked as "done" in my mind. But I've reworked it now. Thanks =] \$\endgroup\$
    – Quelklef
    Aug 15, 2020 at 17:08
2
\$\begingroup\$

Haskell, Cat + Quine = Hello World, 127 bytes

Cat, 27 bytes

o=interact id
main=o where 

Try it online!

Quine, 100 bytes

o=putStr"Hello, world!";main=putStr$(++)<*>show$"o=putStr\"Hello, world!\";main=putStr$(++)<*>show$"

Try it online!

Hello World

o=interact id
main=o where o=putStr"Hello, world!";main=putStr$(++)<*>show$"o=putStr\"Hello, world!\";main=putStr$(++)<*>show$"

Try it online!

Explanation

The main trick in this answer is scoping. In the cat we have a simple program. We have a main which is just defined to be o, which is a cat program. At the end of the program there is a where which opens a new scope. This will make our entire quine program attached to the scope of the main program. Two things are solved by doing this.

  • Since the quine program's main is not defined in the global scope we avoid the duplicate main declaration error.

  • We can declare a version of o that overrides the one in the global scope. Our quine program declares o to be a hello world program.

The overall technique is very similar to Silvio Mayolo's answer, however improves upon it in two ways.

  • Silvio Mayolo's answer declares a variable c=1, which is never used (I am not sure why this is done. Removing it doesn't break anything). This does not have this.

  • I used a shorter quine technique. I took a glance at Silvio Mayolo's quine and I don't know how it works, but it is longer than mine.

\$\endgroup\$
2
\$\begingroup\$

Python 2, Quine + Cat = Hello World, 86 bytes

Quine (35 bytes)

id='id=%r;print id%%id';print id%id

Cat (51 bytes)

+0*''and'Hello World!'
while''>id:print raw_input()

Hello World (86 bytes)

id='id=%r;print id%%id';print id%id+0*''and'Hello World!'
while''>id:print raw_input()
\$\endgroup\$
1
2
\$\begingroup\$

Pxem (esolang-box notation), Hello World: 48 bytes + Quine: 110 bytes = Cat: 158 bytes.

Unprintables are escaped.

Hello World

.f!.zHello World.p.d.a.w.c.z.w.o.i.c\001.+.a.d.a.a

Quine

!Be!?BzBc!!B+BzXXFBaBcFBzBsXXFBBaBsBtBvBmBvBcAcB-BaBsBp".e!?.z.c!!.+.zXXF.a.cF.z.sXXF..a.s.t.v.m.v.cAc.-.a.s.p

Cat

.f!.zHello World.p.d.a.w.c.z.w.o.i.c\001.+.a.d.a.a
!Be!?BzBc!!B+BzXXFBaBcFBzBsXXFBBaBsBtBvBmBvBcAcB-BaBsBp".e!?.z.c!!.+.zXXF.a.cF.z.sXXF..a.s.t.v.m.v.cAc.-.a.s.p

Try it online!

Use variable mode to switch programs.

How it works

The Hello World program consists of several parts, as in:

# branch if content begins with '!' or not
.f!.z
  # Hello World program
  # Note that '!' is recycled here
  Hello World.p.d
.a
.w.c.z
  # Cat program
  # Note that content of stack is cleared before entrying here
  .w.o.i.c\001.+.a.d
.a.a\n

Quine is recycled from here.

Cat program uses this specification:

The first line is the file name of the pxem code.

The rest is the content of the pxem code.

\$\endgroup\$
2
\$\begingroup\$

AWK, Cat + HW = Quine, 156 bytes

BEGIN{k=1}1;BEGIN{if(k){printf a="BEGIN{k=1}1;BEGIN{if(k){printf a=%c%s%c,34,a,34,34,34;exit}print%cHello World!%c}",34,a,34,34,34;exit}print"Hello World!"}

Try it online!

This is the overall algorithm:

BEGIN{k=1}1;
BEGIN{if(k){
    print"Quine";exit
    }
print"Hello, World!"
}

Cat

BEGIN{k=1}1;

Hello World

BEGIN{if(k){printf a="BEGIN{k=1}1;BEGIN{if(k){printf a=%c%s%c,34,a,34,34,34;exit}print%cHello World!%c}",34,a,34,34,34;exit}print"Hello World!"}
\$\endgroup\$
1
\$\begingroup\$

V (vim), Quine + Hello World = Cat, 32 bytes

Quine

dG2idG2i

Explanation:

  • dG: Delete the buffer (saving it to the unnamed register)
  • 2idG2i: Insert dG2i twice.

Hello World

"_dG4iHello World!
␛pH3D

With trailing newline. TryItOnline also shows a trailing space after that, but this appears to be an artifact of it's V runner.

Explanation:

  • "_dG: Delete the buffer (without saving it to a register)
  • 4iHello World!␊␛: Write "Hello World!" 4 times
  • p: Paste from the (empty) unnamed register
  • H3D: Delete the first 3 lines of the buffer

Cat

dG2idG2i"_dG4iHello World!
␛pH3D

Since all no-ops in V are automatically cat programs, the trick here is to make the combined program cancel out itself.

Explanation:

  • dG: Delete the buffer (saving it to the unnamed register)
  • 2idG2i"_dG4iHello World!␊␛: Write dG2i"_dG4iHello World! twice (trailing newline)
  • p: Paste from the unnamed register.
    • Since the motion used to delete was G, this pastes it onto the following line.
    • Therefore, the first two lines of the buffer are that crazy string, the third is an empty line, and the rest is the original buffer
  • H3D: Delete the first 3 lines of the buffer

Try it online!

\$\endgroup\$
1
\$\begingroup\$

PHP, Hello World + Quine = Cat, 117 bytes

Because of the input method this only works using the command line.

Hello world

the double die is because the php code has to get interupted earlier in order to prevent errors being printed (missing function a)

<?php if(!function_exists('a')){die('Hello world!');}die(a($argv));

Quine

without opening tag, php just outputs whatever it contains

function a($b){unset($b[0]);echo implode(' ',$b);}

Cat

Because function declations are passed first, the die() isn't called yet and therefor a() exists, and is called in order to print its arguments. The unset avoids the scriptname from being printed (which is not an input)

<?php if(!function_exists('a')){die('Hello world!');}die(a($argv));function a($b){unset($b[0]);echo implode(' ',$b);}

If only the first argument has to be printed, a shortcut can be used (101 bytes):

<?php if(!function_exists('a')){die('Hello world!');}die(a($argv));function a($b){unset($b[0]);echo implode(' ',$b);}

This however is not the full input and i consider this invalid

\$\endgroup\$
1
\$\begingroup\$

Java 10+, Cat + Quine = Hello World, 384 (135 + 249) bytes

Cat, 135 bytes

interface C{static void main(String[]a){System.out.println(Boolean.TRUE?new java.util.Scanner(System.in).nextLine():"Hello World");}}//

Quine, 249 bytes

(note: TIO doesn't let me run the code unless I rename my interface from Q to Main, but just know that it's supposed to be named the former)

interface Q{static void main(String[]a){var s="interface Q{static void main(String[]a){var s=%c%s%c;System.out.printf(s,34,s,34,10);}}%cinterface Boolean{boolean TRUE=false;}";System.out.printf(s,34,s,34,10);}}
interface Boolean{boolean TRUE=false;}

Hello World, 384 bytes

interface C{static void main(String[]a){System.out.println(Boolean.TRUE?new java.util.Scanner(System.in).nextLine():"Hello World");}}//interface Q{static void main(String[]a){var s="interface Q{static void main(String[]a){var s=%c%s%c;System.out.printf(s,34,s,34,10);}}%cinterface Boolean{boolean TRUE=false;}";System.out.printf(s,34,s,34,10);}}
interface Boolean{boolean TRUE=false;}

Again, the TIO link contains an interface called Main, but it's actually C, the cat program.

It redefines Boolean.TRUE to be false when the quine is concatenated to the cat.

\$\endgroup\$
1
\$\begingroup\$

Haskell, Cat + Quine = Hello World, 140 bytes

Cat

b=interact id
main=b where c=1;

Quine

main=putStr a>>print a;b=putStrLn "Hello world!";a="main=putStrLn a>>print a;b=putStrLn \"Hello world!\";a="

Hello World!

b=interact id
main=b where c=1;main=putStr a>>print a;b=putStrLn "Hello world!";a="main=putStrLn a>>print a;b=putStrLn \"Hello world!\";a="

We exploit the rules of variable shadowing. The cat program simply calls the global b, defined as interact id (a standard cat in Haskell). We declare a variable c that's never used, simply so we can concatenate later. The quine is pretty standard; we define a variable b that we never use, but otherwise it simply prints its payload and exits.

Here's a version of "Hello world" with better spacing.

b = interact id
main = b
  where c=1
        main=putStr a>>print a
        b=putStrLn "Hello world!"
        a="main=putStrLn a>>print a;b=putStrLn \"Hello world!\";a="

main simply calls b, but this time is calls the locally-declared b, which prints "Hello world!". All of the other variables are unused.

\$\endgroup\$
1
  • \$\begingroup\$ I've posted a shorter but similar answer. I'm not sure I understand some facets of your answer so you may be able to improve on mine. \$\endgroup\$
    – Wheat Wizard
    Nov 8, 2020 at 16:32
1
\$\begingroup\$

Klein 001, Quine + Cat = Hello World, 28 bytes

Quine, 11 bytes

This is Martin Ender's quine from here

:?\:2+@> "

Try it online!

Cat, 17 bytes

@ >"Hello world!"

Try it online!

Hello World, 28 bytes

:?\:2+@> "
@ >"Hello world!"

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, Quine + Cat = Hello World, 43 bytes

All of the complexity is jammed into making a quine that includes a variable that holds Hello World!. Cat simply outputs the default input and the Hello World merger reuses the variable from the quine.

Quine, 41 bytes

"Hello World!"             // U = "Hello World!"
"iQ ²iRiQiUiQ"iQ ²iRiQiUiQ // A bunch of messy string manipulations to make this a quine

Cat, 2 bytes


U // Output the default first input

Hello World, 43 bytes

"Hello World!"             // U = "Hello World!"
"iQ ²iRiQiUiQ"iQ ²iRiQiUiQ // Throwaway line
U                          // Output U
\$\endgroup\$
1
\$\begingroup\$

Vyxal, Cat + Quine = Hello, 16 bytes

Hello world, 13 bytes

kh\!+□⁋`I^`I^

Try it Online!

Cat, 7 bytes

kh\!+□⁋

Try it Online!qwhYOKWoeKBiyIsIiIsImFcbmJcbmNcbmRcbiJd)

Quine, 6 bytes

`I^`I^

Try it Online!

Explanation :

## Cat (10)

kh       # push 'Hello World' onto the stack
  \!+    # add '!' to the string
     □   # push the list of the inputs onto the stack
      ⁋  # join the element on top of the stack, with '\n' as separator
         # implicit output

## Quine (6)

`I^`     # push 'I^' on the stack
    I    # string -> `string`string 
     ^   # reverse the stack
         # implicit output

## Hello (16)

kh\!+          # push `Hello World!` onto the stack
     □         #  | do
      ⁋        #  | many
       `I^`    #  | useless
           I   #  | things
             ^ # reverse the stack
               # implicit output
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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