Error-detecting Self-repairing Program

14

3

Your task is to create a program where if any one character is deleted, it will detect which character was deleted and then re-insert the deleted character in its own source file.

For instance, if your program is RadiationHardened and it is modified to RadiaionHardened, then your program must output that the 5th byte (0-indexed) was modified and then the program source must be RadiationHardened immediately after execution.

Notes and rules

  • You may assume that exactly one character was deleted in the source code before execution. Behavior for the unmodified program is undefined.
  • You may assume the changed byte will be deleted, not transposed, inserted, or replaced.
  • In the case of a run of multiple of the same character, you may report either the first or the last index of the run, but be consistent about which you use. For example baaad being deleted to baad can report either 1 or 3 (zero indexed), but must be the same throughout the entire program.
  • You do not need to write out the entire source to its own file. You need only re-insert the deleted byte.
  • Unlike the typical rules for radiation-hardened quines, detecting the changed byte from reading the program's own source code is fair game.
  • You can output the changed byte index through any reasonable format. Be consistent about whether it is 0-indexed or 1-indexed or any other notation. You may even output a number within a template string.

This is so the shortest program wins.

Good luck!

EDIT1: changed requirement from replacement to deletion

EDIT2: added rule for runs of duplicates

Beefster

Posted 2019-02-22T19:21:36.510

Reputation: 6 651

4

This is a lot harder than handling arbitrary deletions. Most non-esolangs are obviously out (it's usually impossible to write any program that remains syntactially valid under any one-byte modification). Even Fungeoids are mostly thwarted (they can't do anything if the 0th byte is changed into a quit program command). I thought maybe one of two IPs could survive in something like Fission but its * command kills all of the IPs. Cardinal can't do it either, because of @.

– Lynn – 2019-02-23T19:50:58.940

This might be turned into a code-challenge where each program is allowed to declare a list of bytes that are protected against radiation (but no more than -- say -- 50% of the total size). A simple scoring system could be to count each radiation-protected byte as 10 bytes, or something like that. – Arnauld – 2019-02-23T22:48:36.330

(But that may lead to some trivial and not very interesting answers.) – Arnauld – 2019-02-23T22:54:01.850

This sounds impossible in most, if not all, languages. – MilkyWay90 – 2019-02-24T05:40:20.477

I'm considering switching this to deletions. Arnauld's suggestion is also viable. – Beefster – 2019-02-24T06:02:00.807

One trivial way would be to wrap the code in a try-except, where only those keywords cannot be mutated... – agtoever – 2019-02-24T11:35:04.710

1@JoKing, reporting either as missing is fine, as long as it's consistent. – Beefster – 2019-02-25T16:56:30.743

@Lynn (Under the original modification version). In theory Runic could survive, as there's no equivalent command to Fission's *, but Runic is terrible at reading its own source (I have yet to work out a single-IP multi-line quine, which would need to be the basis). I'm also not sure how the program is supposed to both output the changed index and the altered character's index. (Runic has no file io). – Draco18s no longer trusts SE – 2019-02-25T21:24:06.530

i am assuming we cannot consider machines with error-correcting memory built in, otherwise it seems like the single byte program '0' would be valid in 05ab1e – don bright – 2019-02-26T03:24:30.987

@donbright I don't think that would fulfil the repairing the source code part of the challenge – Jo King – 2019-02-26T04:59:38.850

2"You may require the file to be named a certain name and be run from a specific directory" - be careful, someone can just require that the filename be the correct program... – ASCII-only – 2019-02-28T22:55:33.453

Answers

9

Befunge-98 (FBBI), 344 296 248 bytes

20020xxnngg33%%!!2200gg''00--3300gg33%%!!4400gg55%%!!22kk++55##rr55kk::00gg\\11pp00gg\\11++11pp22++00::pp00gg\\11++00gg--!!zz!!22**++00::gg00gg8844**--!!55++jj..''gg::00rr00::gg\\--..''220011''0011::''002211''223311''00441144kkppgg11001100::99oo@@

Try it online!

Verification!

Befunge-98 is the first esoteric language that I could find that was both 2D and had file output. This is a full solution (with a trailing newline) stored in a file named as a tab character. It outputs as 0-indexed, and outputs the first index in a run of characters (though there's only ever pairs).

There's a few golfs to be made, especially as there are 15 no-ops in the code, now just one no-op! I will be working on making this shorter, with the goal of getting to or below 200 bytes.

Jo King

Posted 2019-02-22T19:21:36.510

Reputation: 38 234

Oh wow! I didn't think this was possible – MilkyWay90 – 2019-03-01T02:36:58.573

3

Unefunge-98 (PyFunge), 118 bytes

22xx00##rr33kk::gg\\11--pp22++00ppgg\\11++gg--!!zz!!22**--00gg::gg8844**--!!22++jj##''rr++..gg''2200pp0011--00::99oo@@

Try it online!

Verification!

While golfing my Befunge-98 answer, I realised I could save some bytes by porting it over to Unefunge, since I would only have to worry about the one dimension rather than the two. This also opened up a lot of possible shortcuts and golfs, which made the new solution much much smaller.

Explanation (de-duplicated):

2x        Set the delta of the movement to 2
          This means the pointer moves 2 cells every step
          This will also initialise a counter as 2 (unless a 2 has been removed)
  0       Create the cell counter  (This will be stored at cell 0)
   #r     Enter the loop
     3k:                 Create 3 more copies of the counter
        g                Get the cell at the counter's position
         \1-p            Put it in the cell before that position
             2+0p        Add 2 to the counter and put it in cell 0
                 g       Get the cell at the counter's position
                  \1+g   Get the next cell
                      -!z!2*      If they are identical, push two, else 0
                            --    Subtract it from the total counter
                              0g:g84*-!   If the next character is a space
                                       2+j  r   Exit loop
                                         j#'    Else jump back to the start

Once the loop is over
+      Add the negative counter to the total counter
 .     And print
   '20p          Replace the 2 in cell 0 that was overwritten
             o   Write to a file named
            9    Tab
       01-       The cells from -1 to
  g              The total number of cells
              @  And exit the program

Jo King

Posted 2019-02-22T19:21:36.510

Reputation: 38 234