[Python 3], 9097 bytes, score 6
eEzfFzeEz=aAzcCzaAz=aAzbBz=bBzaAz=aAzcCz=eEzfFz=fFzaAz=eEzaAz=dDzaAz=exe=exc=xec=xecexec=aAz=aA=az=Az=aAz=fr='"1"#\nimport base64\n\ndef actual_source():\n\treturn open(eval("_"+"_file_"+"_") ).read()\n\ndef decode(s):\n\treturn str(base64.b64decode(s.replace("_", str() ) ), "utf-8" )\n\ndef encode(s):\n\ts=str(base64.b64encode(bytes(s, "utf-8") ),"utf-8")\n\tresult = str().join([cur if prev!=cur else "_"+cur for prev,cur in zip([None]+list(s),s)])\n\treturn result\n\ndef get_template():\n\treturn decode("aW1wb3J0IGJhc2U2NAoKZGVmIGFjdHVhbF9zb3VyY2UoKToKCXJldHVybiBvcGVuKGV2YWwoIl8iKyJfZmlsZV8iKyJfIikgKS5yZWFkKCkKCmRlZiBkZWNvZGUocyk6CglyZXR1cm4gc3RyKGJhc2U2NC5iNjRkZWNvZGUocy5yZXBsYWNlKCJfIiwgc3RyKCkgKSApLCAidXRmLTgiICkKCmRlZiBlbmNvZGUocyk6CglzPXN0cihiYXNlNjQuYjY0ZW5jb2RlKGJ5dGVzKHMsICJ1dGYtOCIpICksInV0Zi04IikKCXJlc3VsdCA9IHN0cigpLmpvaW4oW2N1ciBpZiBwcmV2IT1jdXIgZWxzZSAiXyIrY3VyIGZvciBwcmV2LGN1ciBpbiB6aXAoW05vbmVdK2xpc3QocykscyldKQoJcmV0dXJuIHJlc3VsdAoKZGVmIGdldF90ZW1wbGF0ZSgpOgoJcmV0dXJuIGRlY29kZSgiQjY0X0VOQ09ERURfUEFSVFMiKQoKZGVmIGdldF93cmFwZXIoKToKCXJldHVybiBkZWNvZGUoIldSQVAiKQoKZGVmIGdldF9wYXlsb2FkKCk6Cgl3cmFwZXIsIHRlbXBsYXRlID0gZ2V0X3dyYXBlcigpLCBnZXRfdGVtcGxhdGUoKQoJZW5fdGVtcGxhdGVfNjQgPSBlbmNvZGUodGVtcGxhdGUpCgl3cmFwZXJfNjQgPSBlbmNvZGUod3JhcGVyKQoJcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoIkI2NF9FTkMiKyJPREVEX1B_BUlRTIiwgZW5fdGVtcGxhdGVfNjQpLnJlcGxhY2UoIldSIisiQVAiLCB3cmFwZXJfNjQpCgpkZWYgZ2V0X29yaWdpbmFsKCk6CglwYXlsb2FkID0gZ2V0X3BheWxvYWQoKQoJd3JhcGVyID0gZ2V0X3dyYXBlcigpCglyZXR1cm4gd3JhcGVyLnJlcGxhY2UoIjEyMyIsIHJlcHIocGF5bG9hZClbMTotMV0gKQoKZGVmIG1haW4ocyk6Cglmb3IgaSwgKGEsIGIpIGluIGVudW1lcmF0ZSg_gemlwKGdldF9vcmlnaW5hbCgpLCBhY3R1YWxfc291cmNlKCkgKSApOgoJCWlmIGEgIT0gYjoKCQkJcmV0dXJuIHNbOmldICsgc1tpICsgMTpdCglyZXR1cm4gcwoKaWYgbm90IChldmFsKCJfIisiX25hbWVfIisiXyIpICE9ICJfIisiX21haW5fIisiXyIpOgoJcHJpbnQobWFpbihpbnB1dCgpICkgKQ=_=")\n\ndef get_wraper():\n\treturn decode("ZUV6ZkZ6ZUV6PWFBemNDemFBej1hQXpiQno9YkJ6YUF6PWFBemNDej1lRXpmRno9ZkZ6YUF6PWVFemFBej1kRHphQXo9ZXhlPWV4Yz14ZWM9eGVjZXhlYz1hQXo9YUE9YXo9QXo9YUF6PWZyPSciMSIjXG4xMjMnIycjJwoxMjsKYkJ6PWJCPWJ6PUJ6PWJCej1mcj0nIjEiI1xuMTIzJyMnIycKMTI7CmNDej1jQz1jej1Dej1jQ3o9ZnI9JyIxIiNcbjEyMycjJyMnCjEyOwpleGU9ZXhjPXhlYz1leGVjCmREej1kRD1kej1Eej1kRHo9YUF6LGJCeixhQXo7CmVFemZGemVFej1nR3plRXo9YUF6Y0N6PWFBejxjQ3o7CmVFej1lRT1lej1Fej1lRXo9YUF6PGNDejsKZkZ6PWZGPWZ6PUZ6PWZGej1hQXo+Y0N6OwplRXpmRno9ZUV6fGZGejsKZ0d6PWdHPWd6PUd6PWdHej1lRXp8ZkZ6OwpleGVjKGREeltnR3pdKQ=_=")\n\ndef get_payload():\n\twraper, template = get_wraper(), get_template()\n\ten_template_64 = encode(template)\n\twraper_64 = encode(wraper)\n\treturn template.replace("B64_ENC"+"ODED_PARTS", en_template_64).replace("WR"+"AP", wraper_64)\n\ndef get_original():\n\tpayload = get_payload()\n\twraper = get_wraper()\n\treturn wraper.replace("123", repr(payload)[1:-1] )\n\ndef main(s):\n\tfor i, (a, b) in enumerate( zip(get_original(), actual_source() ) ):\n\t\tif a != b:\n\t\t\treturn s[:i] + s[i + 1:]\n\treturn s\n\nif not (eval("_"+"_name_"+"_") != "_"+"_main_"+"_"):\n\tprint(main(input() ) )'#'#'
12;
bBz=bB=bz=Bz=bBz=fr='"1"#\nimport base64\n\ndef actual_source():\n\treturn open(eval("_"+"_file_"+"_") ).read()\n\ndef decode(s):\n\treturn str(base64.b64decode(s.replace("_", str() ) ), "utf-8" )\n\ndef encode(s):\n\ts=str(base64.b64encode(bytes(s, "utf-8") ),"utf-8")\n\tresult = str().join([cur if prev!=cur else "_"+cur for prev,cur in zip([None]+list(s),s)])\n\treturn result\n\ndef get_template():\n\treturn decode("aW1wb3J0IGJhc2U2NAoKZGVmIGFjdHVhbF9zb3VyY2UoKToKCXJldHVybiBvcGVuKGV2YWwoIl8iKyJfZmlsZV8iKyJfIikgKS5yZWFkKCkKCmRlZiBkZWNvZGUocyk6CglyZXR1cm4gc3RyKGJhc2U2NC5iNjRkZWNvZGUocy5yZXBsYWNlKCJfIiwgc3RyKCkgKSApLCAidXRmLTgiICkKCmRlZiBlbmNvZGUocyk6CglzPXN0cihiYXNlNjQuYjY0ZW5jb2RlKGJ5dGVzKHMsICJ1dGYtOCIpICksInV0Zi04IikKCXJlc3VsdCA9IHN0cigpLmpvaW4oW2N1ciBpZiBwcmV2IT1jdXIgZWxzZSAiXyIrY3VyIGZvciBwcmV2LGN1ciBpbiB6aXAoW05vbmVdK2xpc3QocykscyldKQoJcmV0dXJuIHJlc3VsdAoKZGVmIGdldF90ZW1wbGF0ZSgpOgoJcmV0dXJuIGRlY29kZSgiQjY0X0VOQ09ERURfUEFSVFMiKQoKZGVmIGdldF93cmFwZXIoKToKCXJldHVybiBkZWNvZGUoIldSQVAiKQoKZGVmIGdldF9wYXlsb2FkKCk6Cgl3cmFwZXIsIHRlbXBsYXRlID0gZ2V0X3dyYXBlcigpLCBnZXRfdGVtcGxhdGUoKQoJZW5fdGVtcGxhdGVfNjQgPSBlbmNvZGUodGVtcGxhdGUpCgl3cmFwZXJfNjQgPSBlbmNvZGUod3JhcGVyKQoJcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoIkI2NF9FTkMiKyJPREVEX1B_BUlRTIiwgZW5fdGVtcGxhdGVfNjQpLnJlcGxhY2UoIldSIisiQVAiLCB3cmFwZXJfNjQpCgpkZWYgZ2V0X29yaWdpbmFsKCk6CglwYXlsb2FkID0gZ2V0X3BheWxvYWQoKQoJd3JhcGVyID0gZ2V0X3dyYXBlcigpCglyZXR1cm4gd3JhcGVyLnJlcGxhY2UoIjEyMyIsIHJlcHIocGF5bG9hZClbMTotMV0gKQoKZGVmIG1haW4ocyk6Cglmb3IgaSwgKGEsIGIpIGluIGVudW1lcmF0ZSg_gemlwKGdldF9vcmlnaW5hbCgpLCBhY3R1YWxfc291cmNlKCkgKSApOgoJCWlmIGEgIT0gYjoKCQkJcmV0dXJuIHNbOmldICsgc1tpICsgMTpdCglyZXR1cm4gcwoKaWYgbm90IChldmFsKCJfIisiX25hbWVfIisiXyIpICE9ICJfIisiX21haW5fIisiXyIpOgoJcHJpbnQobWFpbihpbnB1dCgpICkgKQ=_=")\n\ndef get_wraper():\n\treturn decode("ZUV6ZkZ6ZUV6PWFBemNDemFBej1hQXpiQno9YkJ6YUF6PWFBemNDej1lRXpmRno9ZkZ6YUF6PWVFemFBej1kRHphQXo9ZXhlPWV4Yz14ZWM9eGVjZXhlYz1hQXo9YUE9YXo9QXo9YUF6PWZyPSciMSIjXG4xMjMnIycjJwoxMjsKYkJ6PWJCPWJ6PUJ6PWJCej1mcj0nIjEiI1xuMTIzJyMnIycKMTI7CmNDej1jQz1jej1Dej1jQ3o9ZnI9JyIxIiNcbjEyMycjJyMnCjEyOwpleGU9ZXhjPXhlYz1leGVjCmREej1kRD1kej1Eej1kRHo9YUF6LGJCeixhQXo7CmVFemZGemVFej1nR3plRXo9YUF6Y0N6PWFBejxjQ3o7CmVFej1lRT1lej1Fej1lRXo9YUF6PGNDejsKZkZ6PWZGPWZ6PUZ6PWZGej1hQXo+Y0N6OwplRXpmRno9ZUV6fGZGejsKZ0d6PWdHPWd6PUd6PWdHej1lRXp8ZkZ6OwpleGVjKGREeltnR3pdKQ=_=")\n\ndef get_payload():\n\twraper, template = get_wraper(), get_template()\n\ten_template_64 = encode(template)\n\twraper_64 = encode(wraper)\n\treturn template.replace("B64_ENC"+"ODED_PARTS", en_template_64).replace("WR"+"AP", wraper_64)\n\ndef get_original():\n\tpayload = get_payload()\n\twraper = get_wraper()\n\treturn wraper.replace("123", repr(payload)[1:-1] )\n\ndef main(s):\n\tfor i, (a, b) in enumerate( zip(get_original(), actual_source() ) ):\n\t\tif a != b:\n\t\t\treturn s[:i] + s[i + 1:]\n\treturn s\n\nif not (eval("_"+"_name_"+"_") != "_"+"_main_"+"_"):\n\tprint(main(input() ) )'#'#'
12;
cCz=cC=cz=Cz=cCz=fr='"1"#\nimport base64\n\ndef actual_source():\n\treturn open(eval("_"+"_file_"+"_") ).read()\n\ndef decode(s):\n\treturn str(base64.b64decode(s.replace("_", str() ) ), "utf-8" )\n\ndef encode(s):\n\ts=str(base64.b64encode(bytes(s, "utf-8") ),"utf-8")\n\tresult = str().join([cur if prev!=cur else "_"+cur for prev,cur in zip([None]+list(s),s)])\n\treturn result\n\ndef get_template():\n\treturn decode("aW1wb3J0IGJhc2U2NAoKZGVmIGFjdHVhbF9zb3VyY2UoKToKCXJldHVybiBvcGVuKGV2YWwoIl8iKyJfZmlsZV8iKyJfIikgKS5yZWFkKCkKCmRlZiBkZWNvZGUocyk6CglyZXR1cm4gc3RyKGJhc2U2NC5iNjRkZWNvZGUocy5yZXBsYWNlKCJfIiwgc3RyKCkgKSApLCAidXRmLTgiICkKCmRlZiBlbmNvZGUocyk6CglzPXN0cihiYXNlNjQuYjY0ZW5jb2RlKGJ5dGVzKHMsICJ1dGYtOCIpICksInV0Zi04IikKCXJlc3VsdCA9IHN0cigpLmpvaW4oW2N1ciBpZiBwcmV2IT1jdXIgZWxzZSAiXyIrY3VyIGZvciBwcmV2LGN1ciBpbiB6aXAoW05vbmVdK2xpc3QocykscyldKQoJcmV0dXJuIHJlc3VsdAoKZGVmIGdldF90ZW1wbGF0ZSgpOgoJcmV0dXJuIGRlY29kZSgiQjY0X0VOQ09ERURfUEFSVFMiKQoKZGVmIGdldF93cmFwZXIoKToKCXJldHVybiBkZWNvZGUoIldSQVAiKQoKZGVmIGdldF9wYXlsb2FkKCk6Cgl3cmFwZXIsIHRlbXBsYXRlID0gZ2V0X3dyYXBlcigpLCBnZXRfdGVtcGxhdGUoKQoJZW5fdGVtcGxhdGVfNjQgPSBlbmNvZGUodGVtcGxhdGUpCgl3cmFwZXJfNjQgPSBlbmNvZGUod3JhcGVyKQoJcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoIkI2NF9FTkMiKyJPREVEX1B_BUlRTIiwgZW5fdGVtcGxhdGVfNjQpLnJlcGxhY2UoIldSIisiQVAiLCB3cmFwZXJfNjQpCgpkZWYgZ2V0X29yaWdpbmFsKCk6CglwYXlsb2FkID0gZ2V0X3BheWxvYWQoKQoJd3JhcGVyID0gZ2V0X3dyYXBlcigpCglyZXR1cm4gd3JhcGVyLnJlcGxhY2UoIjEyMyIsIHJlcHIocGF5bG9hZClbMTotMV0gKQoKZGVmIG1haW4ocyk6Cglmb3IgaSwgKGEsIGIpIGluIGVudW1lcmF0ZSg_gemlwKGdldF9vcmlnaW5hbCgpLCBhY3R1YWxfc291cmNlKCkgKSApOgoJCWlmIGEgIT0gYjoKCQkJcmV0dXJuIHNbOmldICsgc1tpICsgMTpdCglyZXR1cm4gcwoKaWYgbm90IChldmFsKCJfIisiX25hbWVfIisiXyIpICE9ICJfIisiX21haW5fIisiXyIpOgoJcHJpbnQobWFpbihpbnB1dCgpICkgKQ=_=")\n\ndef get_wraper():\n\treturn decode("ZUV6ZkZ6ZUV6PWFBemNDemFBej1hQXpiQno9YkJ6YUF6PWFBemNDej1lRXpmRno9ZkZ6YUF6PWVFemFBej1kRHphQXo9ZXhlPWV4Yz14ZWM9eGVjZXhlYz1hQXo9YUE9YXo9QXo9YUF6PWZyPSciMSIjXG4xMjMnIycjJwoxMjsKYkJ6PWJCPWJ6PUJ6PWJCej1mcj0nIjEiI1xuMTIzJyMnIycKMTI7CmNDej1jQz1jej1Dej1jQ3o9ZnI9JyIxIiNcbjEyMycjJyMnCjEyOwpleGU9ZXhjPXhlYz1leGVjCmREej1kRD1kej1Eej1kRHo9YUF6LGJCeixhQXo7CmVFemZGemVFej1nR3plRXo9YUF6Y0N6PWFBejxjQ3o7CmVFej1lRT1lej1Fej1lRXo9YUF6PGNDejsKZkZ6PWZGPWZ6PUZ6PWZGej1hQXo+Y0N6OwplRXpmRno9ZUV6fGZGejsKZ0d6PWdHPWd6PUd6PWdHej1lRXp8ZkZ6OwpleGVjKGREeltnR3pdKQ=_=")\n\ndef get_payload():\n\twraper, template = get_wraper(), get_template()\n\ten_template_64 = encode(template)\n\twraper_64 = encode(wraper)\n\treturn template.replace("B64_ENC"+"ODED_PARTS", en_template_64).replace("WR"+"AP", wraper_64)\n\ndef get_original():\n\tpayload = get_payload()\n\twraper = get_wraper()\n\treturn wraper.replace("123", repr(payload)[1:-1] )\n\ndef main(s):\n\tfor i, (a, b) in enumerate( zip(get_original(), actual_source() ) ):\n\t\tif a != b:\n\t\t\treturn s[:i] + s[i + 1:]\n\treturn s\n\nif not (eval("_"+"_name_"+"_") != "_"+"_main_"+"_"):\n\tprint(main(input() ) )'#'#'
12;
exe=exc=xec=exec
dDz=dD=dz=Dz=dDz=aAz,bBz,aAz;
eEzfFzeEz=gGzeEz=aAzcCz=aAz<cCz;
eEz=eE=ez=Ez=eEz=aAz<cCz;
fFz=fF=fz=Fz=fFz=aAz>cCz;
eEzfFz=eEz|fFz;
gGz=gG=gz=Gz=gGz=eEz|fFz;
exec(dDz[gGz])
This program has the general structure
a="payload"
b="payload"
c="payload"
exec([a,b][b==c])
where "payload" is the program we want to execute. The comparison in the exec
call makes sure that we run an unmodified copy of the payload.
Within the payload, we open the source of __file__
and compare it to the unmodified source (which is determined using a quine). This gives us the information we need to delete the correct character from the output.
The base64 encoded segments are the inputs used when making the quine. They are base64 encoded to avoid needing to escape nested quotes. The program is written so that it has no repeating characters, allowing almost any deletion to be detected.
The 6 characters that can't be deleted are:
- The parentheses and brackets in the last line (
([])
), as deleting them will cause a syntax error.
- The
x
in both instances of exec
, as this produces the variable eec
which is not defined.
If I did define eec
, I would introduce a pair of duplicated characters, and would not be able to distinguish between those deletions. If the challenge cared about deletions of characters instead of bytes then I could define eᵉc
in the appropriate places to reduce the score to 4.
Radiation Resistance tricks
eEzfFzeEz=aAzcCzaAz=...
This line defines all the variables that the program could later try to read, to avoid crashing with a NameError.
bBz=bB=bz=Bz=bBz=
when I want to be able to read a value, I define it (bBz
) twice, and also define the mangled versions of it once each. When the variable is later accessed, at least one of the original definitions was undamaged, and damaging the later access will result in reading one of the shortened versions of the variable. No variable shorter than 2 characters is used as deleting a single variable would cause
bBz=fr='"1"#\n
This acts as a no-op when the payload is executed, and results in any radiation to the start of the string merely storing a bad value in bBz
.
- If the single quote is deleted,
"1"
is assigned, and the rest of the string is commented out.
- If the last
=
is deleted, the string becomes a raw format string, but is still valid syntax.
- Other deletions mangle some variable names, but redundant assignment fixes this.
At the end of the strings '#'#'
is used. As written this is the end of one string followed by a comment. If the first '
is removed, it the next #'
become part of the string, and the remaining 2 characters become a comment. If the first #
is removed, then the program has 2 strings in a row, so they are concatenated. Damage to the last 2 characters is just a change to the comment text.
12;
and ;
are added to allow the deletion of newlines to join statements without issue.
dDz=aAz,bBz,aAz;
This line stores the A and B in a tuple. If either comma is deleted, we still store a tuple of size two. The 3rd tuple element will never be accessed. Deleting the =
has no effect, as dDzaAz
was initialized to the same value as aAz
.
a != c
is converted to e = a<c; f = a>c; g = e|f
so that characters in the comparison operator can be deleted without crashing the program. Then redundant comparisons are added so that damaging any one of the comparisons produces the right result.
exec(dDz[gGz])
we can execute a known-good payload by indexing into a tuple.
u='az'
and depending on those characters the input gets trimmed, so instead of using characters can we use index like 2,3 etc...? \$\endgroup\$u=8
, but I'm not sure why you would want to, if either the8
or theu
is removed then the program will error. \$\endgroup\$