24
\$\begingroup\$

Your challenge is to write a program that is a quine, meaning it prints out its own source code.

For at least one individual character, when it is removed from the program's source, a single different character is removed from the output.

By different, I mean that the character removed from the code is distinct from the character removed from the output - not just in a different place, but a different character altogether.

Your program, modified or unmodified, may output to stderr as long as it also outputs the correct text to stdout.

Scoring

Your score is the number of character this doesn't work for, with lower being better.

For example, if the program abc is a quine in your language, and the program ac prints ab, your score is 2, because removing one of the chars works and removing the other two doesn't.

I have a 200-point bounty for anyone who gets score = 0. This may be increased, depending on how hard it appears to be. Bounty has been awarded to Jo King's answer.

IMPORTANT

I updated the criterion to reflect the fact that scores can converge to 1 by adding a large amount of characters.

\$\endgroup\$
6
  • \$\begingroup\$ Is it alright if after removing a different character, the order of output is not intact? For example if abc is quine and the program ac prints ba? \$\endgroup\$ Jul 31, 2021 at 8:52
  • \$\begingroup\$ @ManishKundu Sorry, but no. Remember, you don't have to get score=1 - some characters' removal don't have to work, and that's ok. \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 8:56
  • 1
    \$\begingroup\$ Ok now my question is what does it mean to remove a character? are we removing all occurrences of that character? Or just any individual character. The word "single" is used in the question which sort of implies the latter, but it is still quite ambiguous. For example if my program is aba, do I need to check the programs b and aa or the programs ab, aa and ba? \$\endgroup\$
    – Wheat Wizard
    Jul 31, 2021 at 12:19
  • \$\begingroup\$ Is it Ok if one or more of the 1-character-removed versions of the program generate output to stderr, as long as they also output the intended 1-character-removed source to stdout (or whatever the intended output is)? \$\endgroup\$ Jul 31, 2021 at 17:13
  • \$\begingroup\$ @WheatWizard An individual character, so the second lot. \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 20:05

4 Answers 4

31
+200
\$\begingroup\$

Backhand, Score 0, 137 bytes

""###:::[[[:::::::::)))))))))888999***EEE666***333+++ssscccjjjlll222%%%]]]333***xxx(((sss~~~rrr~~~'''   sss---***333aaa000~~~rrr:::rrrHHH

Try it online!

I've included the interpreter here because the version on TIO is a bit out of date (in this case missing the instructions Equal and skip). E could be compensated for with -!, but you'd need to do a lot of fiddling around with jump to replace skip.

This code outputs itself if no changes are made, the original code missing a trailing H if any character other than H is removed, and if the H is removed, it removes the leading " instead.

Explanation

Basically, each instruction is duplicated three times (except for the leading ", which is only doubled). This is used as a form of radiation hardening, so that even if one instruction is removed, it can still regenerate it from the others. Backhand is especially good at this, since by default it executes every third instruction. Removing the duplicates, we get:

"#:[:::)))89*E6*3+scjl2%]3*x(s~r~' s-*3a0~r:rH
"       Push the rest of the code, forwards then backwards
 #      No-op
  :[    Dupe the # and decrement it to get "
Start loop
    :::               Make three copies of the top of stack
       )))            Push those to the other stack
          89*E        Is the value a `H`?
              3+scj   If not, jump back to the start of the loop
End loop
                   l2%]3*           If the length of the pushed code is odd (i.e. a character is missing)
                         x(         Flip to the other stack
                           s~       and pop the H if so
                             r~     Reverse the stack and pop the extra "
                               ' s  Skip forwards 32 spaces, i.e. the instruction three from the end
                                    This is the H if all Hs are still present, so it halts and outputs
                                         :r   Otherwise, reverse and duplicate the H
                                       ~r     And pop the "
                                 s-*3a0       And skip back to the H to halt and output
\$\endgroup\$
1
  • 7
    \$\begingroup\$ Give me two days to start a bounty. \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 8:42
10
\$\begingroup\$

Python 2, 338 bytes, score = 16 11

exec"aabb==''''''iimmppoorrtt  ssyyss;;dd==cchhrr((3399))**33;;ssyyss..ssttddoouutt..wwrriittee((''eexxeecc''''%%cc''%%3344++''''..jjooiinn((ii**22ffoorr  ii  iinn''aabb==''++dd++aabb++dd++'';;aa==aabb[[::4466]]++aabb[[5533::]];;eexxeecc  aa''))++''bb%%cc[[::::22]]''%%3344))'''''';;aa==aabb[[::4466]]++aabb[[5533::]];;eexxeecc  aab"[::2]

Try it online!

when any of the char of inside the string is removed, then the first " is removed

How it works :

  • for a string like "aabbccddee", when we take one char every two char, we get "abcde" even if it has a missing char.

I then applied this principle on the quine a="print('a=%r;exec(a)'%a)";exec(a)

  • if the code has a deletion: the end of the string will be exec a instead of exec ab which result of the deletion of the first ".

Note: I could reduce the number of byte by using input instead of sys.stdout.write to print without a newline but it would throws an error (still valid but uglyer)

Python 3.8 (pre-release), 187 bytes, score = 16

exec(a:="pprriinntt((eenndd==''eexxeecc((aa::==''++((''%%rr[[::::22]]))''%%((''''..jjooiinn((ii**22ffoorr  ii  iinn  aa  iiff''##''!!==ii))++''##''))))[[aa[[--11]]====''))''::]]))#"[::2])

Try it online!

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

Python 2, score: 206 - 178 = 28

If you remove any single character in the two long strings, the first " in the output is omitted.

a="print('a=%r,%r;exec max(a,key=len)'%((max(a,key=len),)*2)).replace(chr(34),'',a[0]!=a[1])","print('a=%r,%r;exec max(a,key=len)'%((max(a,key=len),)*2)).replace(chr(34),'',a[0]!=a[1])";exec max(a,key=len)

Try it online!

Based on this quine, this executes the longer, and therefore unmodified, string of a.

\$\endgroup\$
3
  • \$\begingroup\$ @Ausername Changed the solution and adopted the new scoring system \$\endgroup\$
    – ovs
    Jul 31, 2021 at 11:32
  • \$\begingroup\$ Ok, cool ;) Wish I'd fixed the winning criterion in the sandbox :p \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 11:32
  • \$\begingroup\$ -30 bytes, score 28 : Try it online!, changed the heavy replace by print'a='+'...'[a[0]!=a[1]:] \$\endgroup\$
    – Jakque
    Jul 31, 2021 at 14:28
6
\$\begingroup\$

R, 58 bytes; score = 58-2 = 56

'->a;cat(sQuote(a),a,2*11)#' ->a;cat(sQuote(a),a,2*11)# 22

Try it online!

Pretty boring, but now scores better than my original version (below).
Either of the 1 characters near the end of the code can be deleted, resulting in deletion of one of teh two 2 characters at the end of the output.


R, 271 253 bytes; score = 101 253-160 = 93

(Previous solution, better optimized for the initial 'code length divided by changeable characters' scoring method)

a=';`+`=nchar;`!`=sQuote;cat("a=",!(c<-`if`(+a>+b,a,b)),";b=",!c,c,"#"[a==b],sep="")';b=';`+`=nchar;`!`=sQuote;cat("a=",!(c<-`if`(+a>+b,a,b)),";b=",!c,c,"#"[a==b],sep="")';`+`=nchar;`!`=sQuote;cat("a=",!(c<-`if`(+a>+b,a,b)),";b=",!c,c,"#"[a==b],sep="")#

Try it online!

If any of the two sets of 80 single-quoted non-# characters are removed from the code, the final # character is removed from the output.

\$\endgroup\$
3
  • \$\begingroup\$ When scoring, did you account for the fact that the # in the quoted strings are the same as the final # which is removed? \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 8:58
  • \$\begingroup\$ The scoring criterion has been updated. Please update your answer. \$\endgroup\$
    – emanresu A
    Jul 31, 2021 at 11:12
  • \$\begingroup\$ @Ausername (1) I didn't understand the 'different character' meaning in the challenge, I think the scoring now matches what you intended, but please check; (2) score updated, although the new scoring criterion substantially changes the challenge, so I may re-think and submit a better-optimized version now... \$\endgroup\$ Jul 31, 2021 at 14:03

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.