15
\$\begingroup\$

For this challenge, you will be required to write 3 programs:

  1. The first program should be a quine, i.e, it should print it's own source code.
  2. The second program should read the input and print all of it.
  3. The third program should simply print the string "Hello, Permutations!", with or without quotes.

In addition to that, all the three programs should be permutations, i.e, starting from any of the three programs, you should be able to obtain the other by re-arranging it's characters. So all programs will have the same byte count and frequency of characters. For example: abcd, dbca and adbc are permutations.

Rules

  • You may choose to write functions instead of programs.

  • For the first program, you are not allowed to read the source file and print it.

  • You only need to read the input for the second program. No input will be provided to the other two programs.

  • Standard loopholes are forbidden.

  • This is , so the shortest code (in bytes) wins.

\$\endgroup\$
5
  • \$\begingroup\$ Sandbox \$\endgroup\$ – Manish Kundu Mar 14 at 7:31
  • \$\begingroup\$ Sorry if this should be obvious, but should the quine, if we choose to define a function, print only the body of the function, or the entire definition? \$\endgroup\$ – Zaelin Goodman Mar 15 at 12:26
  • \$\begingroup\$ @ZaelinGoodman the entire definition. Check out the current answers, some of them use functions. \$\endgroup\$ – Manish Kundu Mar 15 at 12:52
  • \$\begingroup\$ Are we allowed to have one program and two functions or two programs and one function? \$\endgroup\$ – 79037662 Mar 15 at 13:49
  • \$\begingroup\$ @79037662 Yes.. \$\endgroup\$ – Manish Kundu Mar 15 at 14:30

13 Answers 13

13
\$\begingroup\$

Underload (stringie), 33 bytes each

((aS(:^):SHello, Permuttions!):^)
(S(Hello, Permutations!)(:::^^S))
((Hello, Permutations!)S(:::^^S))

Try it online!

These are function submissions that input via the argument stack, but output to standard output. (The functions also produce garbage output using the more normal mechanism for function output, but according to our normal I/O rules, we only look in one place.)

Explanations

(aS(:^):SHello, Permuttions!):^
(aS(:^):SHello, Permuttions!)     string literal
                             :    non-destructive
                              ^     eval
 a                                enclose {the string literal} in parens
  S                               print it
   (:^)                           string literal
        S                         print that too
       :                          retaining a copy
         Hello, Permuttions       no-ops
                           !      discard the retained copy

S(Hello, Permutations!)(:::^^S)
S                                 print {function input}
 (Hello, Permutations!)           string literal {2nd return value}
                       (:::^^S)   string literal {1st return value}

(Hello, Permutations!)S(:::^^S)
(Hello, Permutations!)            string literal
                      S           print it
                       (:::^^S)   string literal {return value}

If we weren't exploiting this site's I/O rules, it'd cost one extra byte (along with a little code rearrangement) to output the output we wanted (either to standard output or as the function return value), and delete the output we didn't want. But just leaving the extra characters that we're forced to use in order to make a permutation on the argument stack is very slightly shorter.

The quine is an eval quine: we write most of the program in a string literal and eval it, but we still have the original string literal available (because we made the eval non-destructive) and can print it in addition to running it. (This isn't code reading itself, rather the :^ reads one string and uses it for two different purposes.)

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Why was this made community wiki? \$\endgroup\$ – Jonah Mar 14 at 17:17
  • \$\begingroup\$ @Jonah I think it's because ais523 doesn't want to take more rep. Look at all their other answers. \$\endgroup\$ – user Mar 14 at 19:59
  • \$\begingroup\$ Yeah I noticed that after I posted. Maybe ais523 doesn't like the whole idea of rep. \$\endgroup\$ – Jonah Mar 14 at 20:38
  • 1
    \$\begingroup\$ @Jonah: there's normally no real connection between the sorts of answers that get you lots of reputation and the sorts of answers that actually make the site better. I'd much rather be posting the latter than the former, and CWing all my posts helps to avoid any incentive to post answers purely to get upvotes. (It also makes my posts easier to edit – I think people should be editing posts more often, although I don't do it myself because there's an unavoidable +2 reputation gain for low-reputation post editors.) \$\endgroup\$ – ais523 Mar 15 at 23:00
  • 3
    \$\begingroup\$ Yeah, I understand the argument and respect the decision. There's real purity to it. The silly points, despite their gamability and imperfect connection to quality, still give me some motivation though. \$\endgroup\$ – Jonah Mar 15 at 23:24
10
\$\begingroup\$

7, 58 characters, 22 bytes each

7000000000000011111111224444444444555565713432233713432233

Try it online!

7131313130000000022344444444444455557211172000060322351311

Try it online!

7765325101303040432051043451011444112403241040200543217403

Try it online!

No cheating with I/O this time: these are all full programs which output to standard output, and (in the case of the second program) input from standard input. The cat program was the hardest of the three to write by far, because it's the only program that requires a loop.

7's character encoding (which is just octal) encodes eight characters per three bytes; the 22nd byte here thus contains 2⅔ characters. In order to handle this sort of fractional byte at the end of the program, 7 implicitly imagines 1 bits beyond the end of the program; and in order to handle programs where the program doesn't fully fill the last byte, it removes 7 characters from the end of the program. As a consequence, for each program to be interpreted as exactly 58 characters long by the interpreter, I had to sequence the programs in such a way that each program ends with an odd command that isn't 7, i.e. 1, 3 or 5.

Having a very small character set is a benefit for this challenge, because it makes it much easier to reuse the same characters in multiple program (there aren't many to choose from).

Explanations

My usual reminder: 7 has 12 commands, but only 8 of them have names. I use the notation 0, 1, 2, 3, 4, 5 for the commands that append 6, 7, 2, 3, 4, 5 respectively to the top stack element (the last four of these commands cannot appear literally in a program and can only be created at runtime by using them to create a program on the stack).

Quine

765713432233713432233
765                     A literal (and somewhat arbitrary) data structure
    7                    Separator between elements of the initial stack
     13432233            Literal representation of string 73432233
             7           Separator between elements of the initial stack
              13432233   Literal representation of program 73432233

The first pass through a 7 program can't do anything more than push literals to the stack (the rightmost goes towards the top of the stack). However, after doing that, the top stack element is implicitly executed (non-destructively; it remains on top of the stack, and a copy is executed). It does the following:

73432233
73         Pop top of stack (thus deleting the running program)
  43       Pop and output second stack element, preserving top element
    2      Duplicate top of stack (our literal data that copies it)
     23    Pop and output top of stack
       3   Output top of stack, popping it and the element below

That seems simple enough, but there's something that might strike you as a little odd: what happened to the escaping steps that you normally see in quines? Well, remember that 7 has 12 commands and only 8 of them have names. If 7 sees an anonymous command in a data structure it's trying to output, it doesn't output the data structure in question directly; rather, it reconstructs some source code that is capable of producing the data structure in question and outputs that. Our 5 in the original program (just after the 6) is outside the 76 escaped region, so produces the anonymous command 5 inside the resulting data structure, and likewise the second stack element is full of anonymous commands. Additionally, when this sort of reconstruction is used, the output is formatted as though it were a program (putting 7s in the right place to separate stack elements, encoding the output in the same encoding as the source, etc.). You can probably guess that 7 was intended for writing quines!

Data structures which were created using 7 and 6 aren't as reliably reconstructed into the source code that produced them as data structures that were created purely using 05 (because there's more than one way to produce the same structure), but I picked one that round-trips correctly (and contains the right characters to make this program a permutation of the others); the structure in question is arbitrary anyway and only exists to obey the source layout requirements (whilst being actual data so that it can be used as part of a quine payload).

The program exits cleanly because we end up cleaning the entire stack, popping everything.

Cat program

I actually hadn't written a cat program in 7 before, and it's not as trivial a task as it looks.

713131313…7211172000060322351311
7                                  Empty padding element on initial stack
 13131313…                         Literal representation of program 73737373…
          7                        Separator between elements of initial stack
           211172000060322351311   Literal representation of program 277720000632…

Two programs, here, which run in (7's usual reverse) sequence.

The program on the left (which runs last) pops the stack (73) four times. It won't have four elements on it at that point, and a pop on an empty stack is defined to exit the program (stack underflow is normally an error, but this is a special case). So the rest of that program never runs, and it gives us a place to put all the digits we have to include (due to the permutation restriction) but aren't using for anything.

The program on the right is more interesting, and implements the cat behaviour. It assumes that a copy of itself will exist on the top of the stack when it starts running (this will always be the case on the first iteration, because 7 leaves the top of stack in place when it starts running it).

The program on the right is also a silly sort of polyglot. The numerical value of a string in 7 is defined as the total number of 1 and 7 characters in it, minus the total number of 0 and 6 characters; other characters are ignored. With six 7s, four 0s and a 6, this string has a numerical value of +1. This is intentional and required for the program to work, because the string in question is used interchangeably as an implementation of the cat program, and a representation of the integer 1, while the program is running. (This sort of polyglotting is pretty unusual, but helped me save the need for a second 6 character, which would have hurt the byte count because the hello program (the longest) doesn't have any natural reason to use one and so we can't just borrow one from its string literal.)

The string literal 20000 is also a polyglot. This is used only as an I/O control string. The numerical value of -4 means "input a character", when we try to interpret it as a character code (input is done by outputting otherwise impossible/illegal values, like negative character codes); the leading 2 means "output character codes as characters". The default character set for character I/O is 8-bit SBCS. So on the first iteration, we configure I/O for byte-at-a-time operation, and reinterpret the same value that does that as -4 and thus input a character in the process. In the subsequent iterations, I/O is already configured as byte-at-a-time, so only the numerical value of -4 matters.

Bearing those factors in mind, we can now look at how the program works:

2777200006322357377
2                          Duplicate top of stack
  77200006                 Escaped literal 20000 (non-bolded)
 7        3                Output literal (actually takes input)

Input is implemented by duplicating the top of stack a number of times equal to the input, off-by-one (so that EOF can be 0, NUL is 1, SOH is 2, etc.). The same off-by-one applies on output. So the stack is now our 1/cat polyglot, below an integer (which is repeated copies of the cat program) representing our input. We can output it immediately to implement cat behaviour.

2777200006322357377
           223             Non-destructive output of top of stack
              5            Pop and eval top of stack
               73          Pop top of stack
                 77        Push two empty stack elements

After producing our output, we loop by executing ourself again. Or do we?

The program has to halt on EOF. If you look carefully, you'll note that we aren't executing the original cat program (the one with an integer value of 1); that's on the stack just below the element we eval'ed. The stack element actually being executed is the one we just output: the character code that was read in from the user. Remember that this is made up of a number of copies of the cat program, so in most cases we can simply just execute it and it'll work the same way as the original program. However, if the character code we read in is EOF, it'll consist of no copies of the cat program, so there will be nothing to run. We then pop the remaining cat program from the stack, and there are no printing or looping commands left in the program, so it must eventually end up exiting naturally. This gives us a clean exit at EOF, whilst being very very esoteric. (The two 7 commands at the end are clearly pointless, of course; they exist purely to get the numerical value of the cat program right, and don't cost any bytes because they're needed to maintain the permutation property anyway, as they're generated from 1s and we have plenty of those in the hello string literal.)

Hello program

77653…17403
7                Empty padding element on initial stack
 76              No-op (I had to fit a 6 in somewhere)
   53…1          Literal representation of string 53…7
       7         Separator between elements of the initial stack
        403      Standard "print a literal" program

Just a tiny modification of the standard 7 hello world program; it's printing a different string, and there's an entirely useless 776 at the start (the other programs need more 6s and 7s than this program does, but this program is the main user of all the 0-5s and the main thing determining the length of the three programs). Most of the other programs could be written almost entirely with characters stolen from the string literal here, so it's only the bolded commands that make this any longer than a regular string-printer would be.

As usual for literal string-printers in 7, the program reconstructs the source code of the first part of the program by looking at the stack element that was pushed as a consequence of running it. So although there are plenty of bolded commands in the data structure created, that doesn't matter when trying to work out what string is being printed, as the program works backwards from it to the original source and prints that.

The literal is, as usual for 7, encoded in a domain-specific language intended for encoding strings; the 5 at the start of the long literal selects this. It contains four different sets of 32 characters (uppercase letters, lowercase letters, digits and common symbols, and rare symbols), with shift codes to switch between them; and within each set, each character is encoded as two octal digits in the 0-5 range (because 6 and 7 are needed as delimiters). Apart from the reinterpretation of 5 bits as two base-6 digits, this encoding wasn't invented for 7; it is in fact the US-TTY encoding (a variant of Baudot), which was commonly used before ASCII was invented, and which is often a little shorter for commonly used strings than ASCII would be, despite containing all the same characters.

Hello, Permutations! requires five shift codes (which can be visualised as HłelloØ, ŁPłermutationsØ!), so it's 20 + 6 = 25 characters long, thus 50 octal digits when encoded as a 7 literal (51 total when allowing for the 5 to select the encoding). This comes to 18¾ bytes, just slightly shorter than the string would be in ASCII.

\$\endgroup\$
9
\$\begingroup\$

Ruby, 43 37 bytes each

Saved 5 bytes thanks to @Sisyphus, plus another with further golfing.

Quine

eval o="print'eval o=%p'%o#g,tHumPs!"

Try it online!

Cat

print gets#="'=%'%um,Halve ovalPoop!"

Try it online!

Print

p"Hello, Permutations!"#v='va =%p'%og

Try it online!

Verify that the three programs are permutations of each other here.

\$\endgroup\$
3
  • \$\begingroup\$ 38 bytes each \$\endgroup\$ – Sisyphus Mar 15 at 3:14
  • \$\begingroup\$ @Sisyphus Thanks - I hadn't come across %p before. That saves me 5 bytes on two older answers as well! \$\endgroup\$ – Dingus Mar 15 at 4:24
  • \$\begingroup\$ ... actually, make that four. \$\endgroup\$ – Dingus Mar 15 at 5:16
8
\$\begingroup\$

JavaScript (V8), 31 bytes

t=>//==+
'Hello, Permutations!'
t=l=>//Helo, Permuaions!
't='+t
t=l=>//Heo, Permutations!=+''
l

Try it online!

The comment is placed in the middle of the function to appear in the stringified output.

Alternatively for 30 bytes, but only works in Firefox 86- due to a bug where the trailing comment is included in the stringified output:

t=>'Hello, Permutations!'//==+
t=l=>'t='+t//Helo, Permuaions!
t=l=>l//Heo, Permutations!=+''

Try it online!

Or for 32 bytes it can be done without using comments:

(t='=+')=>'Hello, Permutations!'
t=l=>('Helo Permuaions!','t='+t)
t=(l='Heo, Permutations!'+'')=>l
\$\endgroup\$
5
  • 1
    \$\begingroup\$ This is genius! \$\endgroup\$ – ophact Mar 14 at 13:34
  • 1
    \$\begingroup\$ As we define languages here by their implementation, the 30 byte version is a valid submission. \$\endgroup\$ – Shaggy Mar 14 at 18:10
  • \$\begingroup\$ I first discovered this firefox feature when i'm writing codes on this site. And it is reported by others later the day. But I still cannot understand why it considered as a bug. I felt it would more or less a bug of ES specification. \$\endgroup\$ – tsh Mar 15 at 9:59
  • \$\begingroup\$ You can get the 30 byte solution works on tio by select JavaScript (SpiderMonkey) like this \$\endgroup\$ – tsh Mar 15 at 10:09
  • \$\begingroup\$ Thanks @tsh, I found this trick from one of your recent answers :) \$\endgroup\$ – user81655 Mar 17 at 7:39
4
\$\begingroup\$

Python 2, 55 bytes each

Each is a lambda function which performs the specified task.

lambda t='lambda t=%r:t%%t#Helo,Puins!':t%t#Helo,Puins!
lambda s:s ##!!%%%%'',,:==HHPPaabdeeiilllmnnoorttttttuu
lambda:'Hello, Permutations!'## !%%%%,:==HPabdilnsttttu

Quine it online!, Cat it online!, Print it online!

\$\endgroup\$
3
\$\begingroup\$

Functions:

Haskell, 61 bytes (quine)

--dHel,Prmuta!
i=c++show c;c="--dHel,Prmuta!\ni=c++show c;c="

Try it online!

Not sure what the rules are for a "function quine" in Haskell. This code defines i to be a string containing the given source code.

Haskell, 61 bytes (cat)

--dHel,Prmuta!c++show c;c="--Hel,Prmuta!\n=c++show c;c="
i=id

Try it online!

Haskell, 61 bytes (print)

--d,Prmua!c++hw c;c=--dH\=c++shwc;c=
i="Hello, Permutations!"

Try it online!

Verify they're anagrams


Full programs:

Haskell, 75 bytes (quine)

--lid,HelP!
main=putStr$c++show c;c="--lid,HelP!\nmain=putStr$c++show c;c="

Try it online!

Haskell, 75 bytes (cat)

-- !!""$$++++,,--;;===HHPPSS\cccccdehhillllmnoopprssttuuww
main=interact id

Try it online!

Haskell, 75 bytes (print)

-- !$$++++,--;;===HPS\ccccccddhhiillnpsww
main=putStr"Hello, Permutations!"

Try it online!

Verify they're anagrams

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

PHP, 71 69 67 bytes (quine)

eval($o='!Printf ("eval(\$o=%c%s%c);//gHemut",39,$o,39);');//gHemut

Try it online!

PHP, 67 bytes (cat)

!list(, $o)=$argv;ecHo($o);//'Pnf"eval(\=%%%cemut"39,,39)';//gHemut

Try it online!

PHP, 67 bytes (Hello, Permutations!)

ecHo('Hello, Permutations!');//v$=tf("va(\$=%%%cg"39,$,39););//gemu

Try it online!

This is the best I've got so far.. still searching

EDIT: I could get rid of the d with list(,$o)=$argv; instead of end($argv)

EDIT 2: saved 2 bytes by moving the space and the ! inside the part of the quine that doesn't have to be repeated

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

PHP, 33 bytes

 !""$,1;;<=?HP[]aeegillmnoorsttuv

Try first

<?=$argv[1];"Hello, Pemuttions!";

Try second

<?="Hello, Permutations!";$gv[1];

Try third

Verify

\$\endgroup\$
3
  • \$\begingroup\$ Strictly following the rules, the first one is not a valid PHP quine because you are allowed to omit the PHP tags only if the code can run in -r mode, which is not the case. But if you want to keep this answer, why not improve it by using $argn in -F mode? You can then get rid of v, [, 1 and ] \$\endgroup\$ – Kaddath Mar 16 at 14:05
  • \$\begingroup\$ Since i'm not trying to evaluate it as a script the -r option is not needed. \$\endgroup\$ – Cray Mar 16 at 14:26
  • \$\begingroup\$ Well it's rather that since you don't want to evaluate it as a script, it's not PHP... as simple as that. The rules for golfing of PHP are not that complex. You can rename a text file .php and pretend it's php code, but you should be conscious that everything that is outside of PHP tags is not PHP \$\endgroup\$ – Kaddath Mar 16 at 14:53
2
\$\begingroup\$

05AB1E, 38 32 bytes each

-6 bytes thanks to @Kevin Cruijssen

0"”Ÿ™,„œmu¦–!”„ SK"0"D34çý"D34çý
,0"”Ÿ™„œmu¦–!”„ SK"0"D34çý"D34çý
0""0"D34çý"D34çý”Ÿ™,„œmu¦–!”„ SK

Try it online quine

Try it online cat

Try it online Hello, Permutations!

\$\endgroup\$
1
  • \$\begingroup\$ 32 bytes: quine; cat; Hello, Permutations!. It looks very different, but I simply made the Hello, Permutations! literal shorter with ”Ÿ™,„œmu¦–!”„ SK (push dictionary string "Hello, Permu Stations!", and then remove " S"), and I've removed the redundant qs. \$\endgroup\$ – Kevin Cruijssen Mar 30 at 17:27
1
\$\begingroup\$

><>, 37 bytes each

"""r00g::ol?!;80.sniotatumeP ,olleH><
>io00.::ol?;80gsntatumreP ,olleH<"""!
"!snoitatumreP ,olleH">o<00.::l?;80g"

Quine: Try it online!

Cat: Try it online

Hello Permutation: Try it online!

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

R console, 35 bytes

Uses comments in a similar way to most of the other approaches.

function(at){'readle(Hlo, Pmts!#)'}
cat(readline())#futton{'Hlo, Pms!'}
cat('Hello, Permutations!')#dnf(){}

Character breakdown:

'   ! # ( ) , { } a c d e f H i l m n o P r s t u 
2 1 1 1 2 2 1 1 1 2 1 1 2 1 1 1 2 1 2 2 1 1 1 3 1
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I don't understand how the first one is a quine; could you explain? \$\endgroup\$ – Robin Ryder Mar 15 at 14:28
  • 1
    \$\begingroup\$ In TIO the first one doesn't output exactly the same code, is it specific to TIO? Or else you may need to add new lines, indenting and replace the single quotes by double quotes \$\endgroup\$ – Kaddath Mar 15 at 14:44
  • \$\begingroup\$ You are right, this only works in the R console, where there are many "quines" such as NULL. It is still an interesting challenge to find the one which has the most overlap with the required cat and hello programs. \$\endgroup\$ – Flounderer Mar 16 at 0:47
1
\$\begingroup\$

Befunge-98 (FBBI), 31 bytes each

"mHello Peruttions!j~@,k'-a,'
~,'!jHello, Permutations"'-k@
"'k,@-'j~!snoitatumreP ,olleH

There are two unprintable bytes: RS (ASCII 30) before the first ' in the first program, DC3 (ASCII 19) after the first ' in the third program, and the same bytes in the unused areas of each other program. To represent these characters in the explanations, I have used <30> and <19> respectively.

Quine

Try it online!

"mHello Peruttions!<19>j~@,k<30>^S'-a,'
"                                        Begin string mode
 mHello Peruttions!<19>j~@,k<30>'-a,'    Push the rest of the code as a string
"                                        End string mode
 m                                       Not defined in Befunge: reverse direction
"                                        Begin string mode
 mHello Peruttions!<19>j~@,k<30>'-a,'    Push the rest of the code backwards
"                                        End string mode
                                 -       Subtract
                                  a               10 from
                                   ,'                     44, leaving 34 (the quote character) on top
                           k             Repeat     
                            <30>'               31 times:
                          ,                               print the top character
                         @               End the program

Mostly a standard quine, but reuses the a and , characters from Hello, Permutations! to help construct a 34, and the m to reverse direction.

Cat

Try it online!

~,'!jHello, Permutations<19><30>"'-k@
~                                        Get a character from input
 ,                                       Print the character
    j                                    Jump forward 
  '!                                                  33 spaces, going back to the start
                                         On EOF:
~                                        Reverse direction
                                    @    End the program

A standard cat program, using j to skip over the unused section.

Hello, Permutations!

Try it online!

"'<19>k,@<30>-'j~!snoitatumreP ,olleH
"                                       Begin string mode
 '<19>k,@<30>-'j~!snoitatumreP ,olleH   Push this string, ending in "Hello, Permutations!" backwards
"                                       End string mode
      k                                 Repeat
 '<19>                                         20 times:
       ,                                                 print the top character
        @                               End the program

Relies on the FBBI-specific behavior that no spaces are pushed when wrapping in string mode.

\$\endgroup\$
0
\$\begingroup\$

Python 3.8 (pre-release), 50 bytes each

Pretty straight forward solution

  1. Quine
exec(l:="input('exec(l:=%r)'%l)#Ho, Pmutationsp!")

Try it online!

  1. Print the input
input(input())#()::==''""%%Hello, Permatos!cceelxx

Try it online!

  1. Print "Hello, Permutations!"
input("Hello, Permutations!")#()()::==''%%cceelxxp

Try it online!

New contributor
Jakque is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\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.