32
\$\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\$
  • \$\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 at 16:15
  • 3
    \$\begingroup\$ Can we assume that no input is given for the quine and hello world programs? \$\endgroup\$ – fireflame241 Aug 3 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 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 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 at 22:57

21 Answers 21

21
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice approach! Suggestion for -1 byte: tio.run/… \$\endgroup\$ – fireflame241 Aug 3 at 21:25
  • 5
    \$\begingroup\$ def print(_):p(input());os._exit(0) saves two more. \$\endgroup\$ – Jonathan Allan Aug 4 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 at 17:13
  • \$\begingroup\$ Oh, I see, you noted that it doesn't work on TIO. \$\endgroup\$ – Quelklef Aug 15 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

| improve this answer | |
\$\endgroup\$
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`"
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 25 bytes \$\endgroup\$ – Jonathan Allan Aug 4 at 23:25
  • \$\begingroup\$ We should probably use ƈȮ¤L¿ rather than ³, since arguments to a program are evaluated if possible TIO \$\endgroup\$ – Jonathan Allan Aug 5 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\$ – Jonathan Allan Aug 6 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\$ – fireflame241 Aug 6 at 22:14
8
\$\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.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Good to see the nontrivial quine. But it looks like it outputs an extra semicolon at the end? \$\endgroup\$ – Dingus Aug 3 at 18:25
  • \$\begingroup\$ Thanks! I left it in from a previous version! You've saved me a byte! \$\endgroup\$ – Dominic van Essen Aug 3 at 18:29
  • \$\begingroup\$ All three programs output an extraneous [1] . \$\endgroup\$ – Robin Ryder Aug 4 at 5:32
  • \$\begingroup\$ @Robin Ryder - I thought it was Ok to output by return value, rather than strictly by what is dispayed on the console. Do you think this is not Ok? It would be 104 bytes to wrap all the output into cat() to format the console display... \$\endgroup\$ – Dominic van Essen Aug 4 at 6:56
  • 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\$ – Dominic van Essen Aug 4 at 8:01
7
\$\begingroup\$

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

3 functions.

Quine

ToString[#0] & 

Try it online!

Cat

1/.{1->#,_->"Hello World!"}&

Try it online!

Hello World

ToString[#0] & 1/.{1->#,_->"Hello World!"}&

Try it online!

Cat and Hello World can be interchanged by swapping the # and "Hello World!" in the replacement. This works because x 1=x for all expressions, so the 1 disappears when multiplied with the quine.


Hello World + Quine = Cat, 46 + 58 = 104 bytes, 3 full programs

Hello World Try it online!

a="Hello World!"
b=!$ScriptInputString
Print@a

Quine Try it online!

b="b="*ToString[#0, InputForm]*"[];Print@@b" & [];Print@@b

Cat Try it online!

a="Hello World!"
b=!$ScriptInputString
Print@ab="b="*ToString[#0, InputForm]*"[];Print@@b" & [];Print@@b

Attempting to assign to Print@ab is a no-op.

| improve this answer | |
\$\endgroup\$
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

| improve this answer | |
\$\endgroup\$
6
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\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 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 at 20:16
  • \$\begingroup\$ @Beefster I'll update my code and the link in that case. \$\endgroup\$ – TehPers Aug 3 at 20:45
  • \$\begingroup\$ I'll look for another quine that doesn't include itself then. \$\endgroup\$ – TehPers Aug 3 at 21:01
  • 1
    \$\begingroup\$ yeah, it was the quine. Reading your own source code is a banned loophole. \$\endgroup\$ – Beefster Aug 3 at 21:37
6
\$\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.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I'll upvote this tomorrow \$\endgroup\$ – null Aug 4 at 1:15
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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Save a character with putchar(s) --> putc(s,1). \$\endgroup\$ – bta Aug 6 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 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.

| improve this answer | |
\$\endgroup\$
  • 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 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\$ – SE - stop firing the good guys Aug 5 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 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.

| improve this answer | |
\$\endgroup\$
  • 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 at 17:27
  • \$\begingroup\$ @Zgarb Correction, fixed at the cost of 2 bytes.. \$\endgroup\$ – Kevin Cruijssen Aug 4 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!).

| improve this answer | |
\$\endgroup\$
  • 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\$ – Kevin Cruijssen Aug 6 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\$ – Jonathan Allan Aug 6 at 16:54
3
\$\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!

| improve this answer | |
\$\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)

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Note that a quine must not access its own source, directly or indirectly. See also the Wikipedia entry for cheating quines \$\endgroup\$ – Dominic van Essen Aug 14 at 15:40
  • \$\begingroup\$ Thanks for the info. I'll mark my submission as non-competing \$\endgroup\$ – Quelklef Aug 14 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\$ – Dominic van Essen Aug 15 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 at 17:08
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 it 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.

| improve this answer | |
\$\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!

| improve this answer | |
\$\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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ruby, Cat + Quine = Hello World!, 100 97 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 quinehood

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.

| improve this answer | |
\$\endgroup\$
0
\$\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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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