Radiation softened quine

38

1

It's simple: Make a proper quine where if you remove any character, it's still a quine.

The difference between this and a radiation hardened quine is that if your program is AB, in a radiation hardened quine A would output AB, but here, A would output A.

Code golf, all standard rules, standard loopholes apply, no cheating.

CalculatorFeline

Posted 2016-02-20T03:41:54.417

Reputation: 2 608

Is an empty program valid? – Loovjo – 2016-02-20T07:06:43.570

4

@Loovjo No.

– Martin Ender – 2016-02-20T09:55:36.107

Does the original program need to be a quine? I.e. in the example, is it enough that A outputs A and B outputs B, or is it also necessary that AB outputs AB? – feersum – 2016-02-21T04:26:50.233

3@feersum The challenge states "Make a quine where...", so AB should output AB. – Mego – 2016-02-21T04:54:27.037

1@Mego I know it says that, but specifications are not always so precise, and it is not indicated in the examples. – feersum – 2016-02-21T05:20:54.637

4@feersum "Make a quine" means make a quine. "The difference between this and a radiation-hardened quine..." means that the only difference is that the program with any one byte removed results in a quine, not a program that prints the original program's source. There is no ambiguity here. – Mego – 2016-02-21T05:24:34.063

Answers

22

><> (Fish), 145 107 bytes

This answer uses ><>'s jumping instruction to fix the problem.

!<0078*+00~..>0[!."r43a*+8a+&{ee+00&1-:&(?.~~ol?!;4b*0.0f<>0['r3d*159*+&}7a*00&1-:&(?.~~ol?!;68a*+0.0+*a58 

This quine actually contains two different quine generators. It starts with some jumping logic and by default uses the left quine. If a character is removed from the jumping logic or from the left quine, the program jumps to the right quine.

You can try it here

Explanation

The code can be dissected into a few parts:

A: !<0078*+00~..>0[!. 
B:              >0[!."r43a*+8a+&{ee+00&1-:&(?.~~ol?!;4b*0.
C:                                                    .0f<
D:                                                        >0['r3d*159*+&}7a*00&1-:&(?.~~ol?!;68a*+0.
E:                                                                                                 .0+*a58 

Explanation of the different parts:

  • A: Jumps to the right of C. If any character is deleted from from A, this jumps to the left of D or the right of E, triggering the second quine. If any character is deleted from B or C, the code is shifted 1 character to the left, causing this to jump to the left of D.
  • C: This code jumps to the left of B.
  • B: Quine #1
  • D: Quine #2
  • E: Jumps to the left of D

Explanation of the quine (with #1 as example):

Once the instruction pointer reaches either of the quines, you're certain that that quine is completely intact.

>0[!.                                       //Fix the instruction pointer's direction and empty the stack (The '!.' is a leftover from codepart A)
     "r43a*+                                //Start reading all of the code and add the '"' character to the stack
            8a+&                            //Because the quine started reading at the 19th character instead of the first, the stack has to move 18 characters. 
                                            //This part saves the number 18 to the register.
                {ee+00&1-:&(?.              //Move the stack one to the left, decrease the stack by 1. If the stack is not empty yet, jump back to the start of this section.
                              ~~              //Clean the temporary variables from the stack. It should now contain the whole quine.
                                ol?!;4b*0.  //Print the first character from the stack. As long as the stack isn't empty, jump back to the start of this section.

Thijs ter Haar

Posted 2016-02-20T03:41:54.417

Reputation: 752

Explanation please. – CalculatorFeline – 2017-06-12T19:49:33.547

Reiterating above. – CalculatorFeline – 2017-06-22T03:53:42.373

1Is this clear enough? – Thijs ter Haar – 2017-06-22T08:09:13.873

36

Lenguage, 4.54×10761 bytes

It has this number of null characters:

453997365974271498471447945720930600149036031871190716908688344432973027776681259141680552038829875159204621651993092104775733418288411812715164994750890484868305218411129600012389568016974351721147925344946382782884546247102886167837964612372737300786173159265347137401863281368021545169383664534228503236761742285358985343373496184959796553930661837467682191561275123057706776367104142995491262443697167483190110516522677811931124842961701222425076750211774387637740969301686178545299089832300154448308384461700726890067468872402133010536518468336342175124002115991866466700174974019423711837589532744970385003356612639263433822126850314801275940879069069974437167102618471264140597777702065896715558989678487253830854848740247786166790545462769498303055791292

Seeing how the criterion in this challenge conflicts with the definition of a "proper quine", seriously, I think an Unary variant is going to win.

Expanded Brainfuck code:

>>+++>++++++++>+++>+++>+>+>+>+>+>+>+>+++>+>+>+>+>+>+>+>+>+++>+>+>+>+>+>+>+>+>++++++++>++++>++++++++>++++>+++++++>++>+++>+>+++>++>+++>+++>+>+>+>+>+>+>+>+>++++>++++>+++++++>+>++++>++++++++>++>+++++++>+++>++++++++>++>+++++++>+++>++++++++>++>+++++++>+++>++++++++>++>+++++++>+++>+++++>++++++++>++++>+++++++>+++++++>+>+>+++>+>+>+>++++++++>+++>+++++++>+>+++>+>+++>+>+++>+>++++++++>++++>++++++++>++++>++++++++>++++>++++>+>+++>+++>++>+++++++>+++++++>+>+>+>++++++++>+++>+>++++++++>++++>+>+++>++>+++++++>++>+++++++>++++>++++>++++++++>+++>++++++++>+++>+++>+>++++>++++>++>+++++++>+++>+++>++++++++>++++>+>+++>++>+++++++>++++>++++>+++++++>+++>+++>+++>+++>++++++++>++++>++++>+>+++>+>+++>++>+++++++>+++++++
[
    [->+>+<<]
    >>>>[<<[->+<]>>[-<<+>>]>]
    <<[-[->+<]+>]+++
    [[->>+<<]<]<
]
+>+>+>+
[>]+++>++
[
    [<].
    >[-]>[-]>[-]>[-]
    <+[<<++++++++>>->+>-[<]<]
    ++++++++>++++++++>+++++++>>
]
.

If one character is removed from the Lenguage program, the last character becomes a <, which causes the program to print exactly one less character.

jimmy23013

Posted 2016-02-20T03:41:54.417

Reputation: 34 042

1How did you manage to find that fixed point? (Or alternatively, how does the Brainfuck code work?) – Martin Ender – 2016-02-21T09:54:38.097

1@MartinBüttner The first big loop copies and encodes the data in the form of ">+++..." (and reverses it). The other big loop print the data as an integer in unary. It's not that complicated but is long only because it's Brainfuck. – jimmy23013 – 2016-02-21T11:11:56.923

Oh right, so it's just like a plain Brainfuck quine, but with a different decoding function? – Martin Ender – 2016-02-21T11:13:16.610

@MartinBüttner Somewhat. But half of the program is the "decoding function". – jimmy23013 – 2016-02-21T11:17:08.993

It seems you could use a similar technique to construct answers of arbitrary score for http://codegolf.stackexchange.com/q/57257/8478 (although how exactly that works would depend on the answer to my latest comment).

– Martin Ender – 2016-02-21T17:03:22.000

@lirtosiast It is a true quine. The first line in the Brainfuck code encodes the rest. (Or the number of whole segments consisting of 8^155 null characters encodes other null characters, if you prefer that.) – jimmy23013 – 2016-02-21T22:00:52.857

@MartinBüttner Technically, it says the program should work only when exactly n characters are removed, but not less, so you can get an arbitrary n. But still, it says least program_length^2/n wins, where a long program like this doesn't have much advantage. – jimmy23013 – 2016-02-21T22:12:21.473

@jimmy23013 yeah, the scoring was changed after my comment. – Martin Ender – 2016-02-21T22:14:05.223

@MartinBüttner Last time I checked it I believed that it must also work if less than n characters are removed. In that case it can only get a score of 3, or the final character would become an unmatched ], making the program invalid. – jimmy23013 – 2016-02-21T22:21:12.370

How would one include a payload on this quine? – lirtosiast – 2016-02-21T22:58:21.953

@lirtosiast Insert code before the second loop in the Brainfuck code. The memory is the Brainfuck code with the instructions represented by 1 to 8, with some delimiters. – jimmy23013 – 2016-02-21T23:06:08.973