38
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Is an empty program valid? \$\endgroup\$ – Loovjo Feb 20 '16 at 7:06
  • 4
    \$\begingroup\$ @Loovjo No. \$\endgroup\$ – Martin Ender Feb 20 '16 at 9:55
  • 3
    \$\begingroup\$ @feersum The challenge states "Make a quine where...", so AB should output AB. \$\endgroup\$ – Mego Feb 21 '16 at 4:54
  • 1
    \$\begingroup\$ @Mego I know it says that, but specifications are not always so precise, and it is not indicated in the examples. \$\endgroup\$ – feersum Feb 21 '16 at 5:20
  • 4
    \$\begingroup\$ @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. \$\endgroup\$ – Mego Feb 21 '16 at 5:24
22
\$\begingroup\$

><> (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.
\$\endgroup\$
  • \$\begingroup\$ Explanation please. \$\endgroup\$ – CalculatorFeline Jun 12 '17 at 19:49
  • \$\begingroup\$ Reiterating above. \$\endgroup\$ – CalculatorFeline Jun 22 '17 at 3:53
  • 1
    \$\begingroup\$ Is this clear enough? \$\endgroup\$ – Thijs ter Haar Jun 22 '17 at 8:09
36
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ How did you manage to find that fixed point? (Or alternatively, how does the Brainfuck code work?) \$\endgroup\$ – Martin Ender Feb 21 '16 at 9:54
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – jimmy23013 Feb 21 '16 at 11:11
  • \$\begingroup\$ Oh right, so it's just like a plain Brainfuck quine, but with a different decoding function? \$\endgroup\$ – Martin Ender Feb 21 '16 at 11:13
  • \$\begingroup\$ @MartinBüttner Somewhat. But half of the program is the "decoding function". \$\endgroup\$ – jimmy23013 Feb 21 '16 at 11:17
  • \$\begingroup\$ It seems you could use a similar technique to construct answers of arbitrary score for codegolf.stackexchange.com/q/57257/8478 (although how exactly that works would depend on the answer to my latest comment). \$\endgroup\$ – Martin Ender Feb 21 '16 at 17:03

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.