Pass on your radiation

24

1

The task here is pretty simple. You should write a program that takes a string as input and outputs it (that is a cat program).

Additionally when the \$n\$th byte of your program is removed (without replacement) the augmented program should take a string as input and remove the \$n\$th character. If the input to your augmented program is less than \$n\$ characters long it should return it as is. For example the python program

x = input()
if "y" == "y":
  print(x)
else:
  print(x[:16] + x[17:])

Try it online!

will remove the \$17\$th character if its \$17\$th byte is removed (the first y).

Scoring

Your answer's score will be the number of bytes for which removal does not cause the program to remove the corresponding byte. With better score being lower.

In our example above the total length is 68 bytes, with one byte (the \$16\$th one) augmenting the program correctly. That leaves a score of 67 bytes.

If the program were modfied to work in two places like so:

x=input()
u="az"
if u!="az":x=x[:13+(u<"c")]+x[14+(u<"c"):]
print(x)

Try it online!

Where removing the \$14\$th and \$15\$th characters (a and z) work properly. The score is 66 bytes or 68 - 2, since the program is 68 bytes long but two of those bytes work properly.

Rules and clarifications

  • There must be at least one byte which can be removed that causes the program to remove the corresponding character in the input. This means a cat program on its own is not a valid submission.

  • Only one byte will be removed at a time. You do not have to worry about what happens when multiple bytes are removed from your program at the same time.

  • You should support strings using printable ascii characters in addition to all characters that appear in your program itself. Input containing anything else is undefined behavior.

Post Rock Garf Hunter

Posted 2019-12-14T15:43:51.687

Reputation: 55 382

May we work on arrays of characters instead of strings? (For languages for which it's not the same thing.) – Arnauld – 2019-12-14T16:33:25.810

2@Arnauld This challenge asks for a complete program, I chose this because I feel that source layout doesn't play very nicely with functions. As a result I am pretty sure that input will have to be taken as a string. – Post Rock Garf Hunter – 2019-12-14T16:35:00.010

@game0ver I'm not sure what you mean by variable here. Could you clarify the question. – Post Rock Garf Hunter – 2019-12-14T16:35:23.863

@game0ver I am still unsure of what you mean. What is a here, is the referencing a specific example? – Post Rock Garf Hunter – 2019-12-14T16:41:51.433

@game0ver I still do not known what is meant by u. – Post Rock Garf Hunter – 2019-12-14T16:45:44.790

In your example you set u='az' and depending on those characters the input gets trimmed, so instead of using characters can we use index like 2,3 etc...? – game0ver – 2019-12-14T16:45:58.797

@game0ver Your code can be any sequence of bytes, the process is agnostic to what the code is doing. You could set u=8, but I'm not sure why you would want to, if either the 8 or the u is removed then the program will error. – Post Rock Garf Hunter – 2019-12-14T16:48:32.853

Is it OK if the output includes extra non-printable characters (e.g. null bytes)? – Robin Ryder – 2019-12-15T20:49:02.143

@RobinRyder An extra newline at the end is ok. – Post Rock Garf Hunter – 2019-12-15T21:01:03.690

@WheatWizard But non-printable characters are not? – Robin Ryder – 2019-12-15T21:07:04.887

@RobinRyder I would consider the newline to be a non-printable characters,but I don't think extra null bytes are acceptable. – Post Rock Garf Hunter – 2019-12-15T21:19:00.693

One more complicated scoring formula that could have worked pretty well is n+(n-r)*100/n, with n = size in bytes and r = number of removable characters. – Arnauld – 2019-12-17T17:04:36.000

@Arnauld I'm pretty happy with the current scoring formula as it is. – Post Rock Garf Hunter – 2019-12-17T17:14:16.583

Answers

19

Python 2, score:  56 50  48 bytes - 6 = 42

This is more an attempt to allow to remove more than 1 or 2 characters than to achieve the lowest possible score. Given the scoring scheme, allowing one more byte to be removed this way would cost at least one extra byte, leaving the score unchanged at best.

You may remove the 3rd to the 8th character, i.e. any digit of \$545454\$.

n=545454;x=input();print x[:n%11]+x[n%11+n%9/4:]

Try it online!

How?

Removing the \$n\$th digit from \$545454\$ and applying a modulo \$11\$ results in \$n+1\$. Applying a modulo \$9\$ instead allows to figure out whether the number was changed or not.

 pattern |    x   | x mod 9 | x mod 11
---------+--------+---------+----------
  545454 | 545454 |    0    |   (8)
  _45454 |  45454 |    4    |    2
  5_5454 |  55454 |    5    |    3
  54_454 |  54454 |    4    |    4
  545_54 |  54554 |    5    |    5
  5454_4 |  54544 |    4    |    6
  54545_ |  54545 |    5    |    7

Arnauld

Posted 2019-12-14T15:43:51.687

Reputation: 111 334

12

sed, Perl 5 -p, Perl 6 -p, 6 bytes, score 5

#s/.//

Try it online!

Works as sed, Perl 5 and Perl 6 program. The 1st byte is removable.

nwellnhof

Posted 2019-12-14T15:43:51.687

Reputation: 10 037

10

><>, 584 bytes, score 0

<|0!o? !@ !: !@ !: !- !1$ !i|!? !: !+ !@ !@ !- !) !* !e !e$ !* !+1+ !@ !( !3 !@ !* !* !d !f !: !+ !* !2 !$ != !g !2 !$ !@ != !g !1 !$ !@ !: !g !0 !: !: !: !: !:<0~!?g1*e e-10 ~!?g0-$0:-*e e0 0</
<|0!o? !@ !: !@ !: !- !1$ !i|!? !: !+ !@ !@ !- !) !* !e !e$ !* !+1+ !@ !( !3 !@ !* !* !d !f !: !+ !* !2 !$ != !g !2 !$ !@ != !g !1 !$ !@ !: !g !0 !: !: !: !: !:<0~!?g1*e e-10 ~!?g0-$0:-*e e0 0</
<|0!o? !@ !: !@ !: !- !1$ !i|!? !: !+ !@ !@ !- !) !* !e !e$ !* !+1+ !@ !( !3 !@ !* !* !d !f !: !+ !* !2 !$ != !g !2 !$ !@ != !g !1 !$ !@ !: !g !0 !: !: !: !: !:<0~!?g1*e e-10 ~!?g0-$0:-*e e0 0</

Try it online! Verification of perfect score (note times out)

The first zero score program. This is achieved by having three copies of the program on separate lines, with only non-irradiated versions being executed. The program checks for outliers (like newlines being removed), then checks each character to see if it is the same for all three lines. If one is different, we determine which line it is and offset the current index by a multiple of 195 (the length of each line). After determining which byte is irradiated (with no byte being -1 and the first byte being 1), we enter the output loop, decrementing the counter each time we output a character. When the counter hits zero, we skip that character, but don't reset the counter so it can be proven that only one byte of input is removed when the program is irradiated, and none when it is not.

The TIO link above has the program itself in the input, so it is easy to fiddle about in yourself. Simply try removing a byte from the program itself and the same byte will be removed from the output.

It shouldn't be too hard to golf, especially the loop in the middle that's just 60% no-ops, though I just want to post it since it is actually working and this isn't actually .

Jo King

Posted 2019-12-14T15:43:51.687

Reputation: 38 234

7

Jelly, 2 bytes, score = 1

ḷḊ

Try it online!

A full program that takes a string and prints a string. When the first byte is removed, removes the first byte of the input.

Achieving a lower score would mean finding a solution where removing any byte leads to the corresponding byte being removed from the string, which I think will be chalenging.

Explanation

ḷ  | Left argument of input string and:
 Ḋ | - Input string with first byte removed

With first byte removed:

Ḋ | Remove first byte

Nick Kennedy

Posted 2019-12-14T15:43:51.687

Reputation: 11 829

6

Brainfuck, 11 bytes, score = 10

-+[,>],[.,]

Try it online!

Explanation

-+[,>]   This does nothing.
,[.,]    This reads and outputs the user's input until the program ends.

With first byte removed:

+[,>]    Reads the first character of user input, then 'discards' it by moving to a different cell.
,[.,]    This reads and outputs the user's input until the program ends.

Madison Silver

Posted 2019-12-14T15:43:51.687

Reputation: 139

@JoKing Whoops, I missed that! Updating now. – Madison Silver – 2019-12-20T01:22:48.280

Forgot to remove it when I updated the program. Should be fixed now, unless there's something else I missed... – Madison Silver – 2019-12-20T01:28:10.743

5

R, 93 bytes, score=87

T<-3.5->T;s=utf8ToInt(scan(,""));if(i<-match(2*T,c(0,-5,2,1,70,6,0,5),0))s=s[-i];intToUtf8(s)

Try it online!

Like Arnauld, I tried to get a few deletable bytes rather than optimize the score, and also to use different tricks depending on the byte removed. Characters 2, 3, 4, 5, 6 and 8 can be removed.

In the unaltered version, the code makes two attempts to assign a value to T, using both leftwards <- and rightwards -> assignment. Since T is initialized as 1 (when coerced to integer), it can be assigned 7 different values, depending on the byte removed:

  • T<-3.5->T leads to T=3.5
  • T-3.5->T leads to T=1-3.5=2.5
  • T<3.5->T leads to T=1, since 1<3.5 is true (the same would occur if we removed byte 7 - I searched for a way to have different behaviours when removing bytes 3 and 7 but couldn't manage)
  • T<-.5->T leads to T=.5
  • T<-35->T leads to T=35
  • T<-3.->T leads to T=3.
  • T<-3.5-T leads to T=3.5-1=2.5

The statement with if and match then removes the relevant character. The rest is the usual fluff required whenever R has to handle strings.


It is obviously possible to make the number 3.5 longer (e.g. 43.5) and be allowed to remove the corresponding characters. For the sake of it, here is a different way of getting more removable characters:

R, 120 bytes, score=112

T<-3.5->T;s=utf8ToInt(scan(,""));if(i<-match(T+T,c(0,-5,2,1,70,6,0,5,rep(0,37),3.5,rep(0,47),-7),0))s=s[-i];intToUtf8(s)

Try it online!

In addition to the characters listed above, bytes 46 and 94 can be removed:

  • byte 46: the first T in T+T becomes +T, which matches 3.5
  • byte 94: -7 becomes 7, which then matches T+T=7.

Robin Ryder

Posted 2019-12-14T15:43:51.687

Reputation: 6 625

4

05AB1E, score 2, 3 bytes

D¦r

Look ma, (sort of) no unicode!

The character to remove is the first one.

Try it online

Explanation:

D  push two copies of the input onto the stack
¦  remove the first character from the string on top of the stack. Alternatively, if D is removed, push the input with its first character removed onto the stack.
r  reverse the stack
implicitly, output the top of the stack

acupoftea

Posted 2019-12-14T15:43:51.687

Reputation: 101

4The language's name is 05AB1E, not O5AB1E. Also, the second character is ¦, not ASCII |, so it's not really "no unicode". – Grimmy – 2019-12-16T12:42:55.890

@Grimmy thanks, I didn't notice. Since broken pipe is in many of the small extended ascii encodings, I think it sorta counts as "no unicode", maybe? – acupoftea – 2019-12-16T17:25:23.347

1Technically every golfing language with a SBCS is "no unicode", since they have their own encodings. – Jo King – 2019-12-18T09:38:25.150

Technically the 05AB1E codepage is a subtle extension of extended ASCII. – None – 2019-12-18T10:56:11.070

4

Haskell, 31 - 1 = 30

Removing the first byte works

ss(x:b)=b
s x=x
main=interact s

Try it online!

Explanation

In its default state this program defines two functions ss which is unused, and s which is the identity. It then declares that interaction is handled by s, making it a cat.

When we remove the first byte ss is renamed to s. Making it a special case of our function s, since this is the first declaration it takes highest precedence. So now s is defined such that if it can remove the first character it does so otherwise it falls back onto our old definition of s1 and becomes the identity. We still interact with s (although now modifed) so the entire program has the behavior of removing the first character if there is one.


1 This is important in the case of the empty string.

Post Rock Garf Hunter

Posted 2019-12-14T15:43:51.687

Reputation: 55 382

3

Python 3, 33 - 1 = 32 bytes

The removable byte is the 23rd one (~).

x=input();print(x[:22-~0]+x[23:])

Try it online!

This sort of evolved out of Arnauld's answer, but only seeks to get one removable character.

Explanation

In python ~ is a "bitwise not", which basically subtracts the value from 1. So ~0 is equivalent to -1. This makes 22-~0 the same as 23. So normally our program takes everything up to the 23rd character and then adds everything after. However when we remove the ~ 22-~0 becomes 22-0 equivalent to 22. This makes us take the first 22 characters and everything after the 23rd, skipping the 23rd character.

Post Rock Garf Hunter

Posted 2019-12-14T15:43:51.687

Reputation: 55 382

3

Keg -ir, 3 bytes, score: 2

#_^

Try it online!

Explanation

#_^ # A line comment
    # Copies the input to the output straightforwardly
    # Implicit reversed input
_   # Discard the first character in the string
 ^  # Reverse the stack

user85052

Posted 2019-12-14T15:43:51.687

Reputation:

Even better: ^_^ – connectyourcharger – 2019-12-16T17:13:26.523

@connectyourcharger You know, one of my eyes are sore... – None – 2019-12-16T23:16:20.880

@connectyourcharger ugh. Now I can't not see it as a face. :P – Lyxal – 2019-12-18T00:43:50.417

3

05AB1E, score 1, 2 bytes

Try it online!

First byte is removable.

Grimmy

Posted 2019-12-14T15:43:51.687

Reputation: 12 521

2

Charcoal, 6 bytes, score 5

ΦS⁻κ±⁴

Try it online! Explanation:

 S      Input string
Φ       Filtered
   κ    Current index
  ⁻     Subtract
     ⁴  Literal `4`
    ±   Negated

Since adding 4 to the index is always a truthy result, this is a cat program. Removing the ± at index 4 results in the following program:

ΦS⁻κ⁴

Try it online! It deletes the character at index 4 (0-indexed).

Neil

Posted 2019-12-14T15:43:51.687

Reputation: 95 035

2

C (gcc), 54 53 bytes, score 52 51

Bytes 27 or 28 (from the first ++c), or both, may be removed.

Explanation:

There is a counter that increments by 2 each iteration (one in the loop condition, one in the body) in the unmodified program, but removing one of the +s turns the first increment into a no-op. As the only way to get an odd number is in the modified program, only it will remove the 27th byte. Both bytes can be removed because +c is the same as c.

c;main(a){for(;a=~getchar(++c);)++c-27&&putchar(~a);}

Try it online!

ErikF

Posted 2019-12-14T15:43:51.687

Reputation: 2 149

2

Shakespeare Programming Language, 236 bytes, score 235

-16 bytes thanks to Jo King.

New lines added for readability. Byte 196 can be removed. Exits with error but the output is correct.

,.Ajax,.Page,.
Act I:.Scene I:.
[Exeunt][Enter Ajax and Page]
Ajax:Open mind.
Page:You be the sum ofyou a cat.
     Be you as big as the square ofthe sum ofa big big big big cat a big pig?
     If soLet usScene VI.

Scene VI:.
Ajax:Speak mind.Let usAct I.

Try it online!

Page reads bytes from input and outputs them, one at a time. Ajax is a counter indicating how many bytes have been read. Page's if statement tests Ajax == 196. In the basic version, the if statement is useless: in all cases, we proceed to Scene VI. If byte 196 has been removed, the statement becomes If soLet usScene I. so we skip Scene VI and the corresponding input does not get output.

This uses the fact that SPL doesn't require scenes to use consecutive numbers.

Looking for other strategies, I checked all the words allowed in SPL: the only useful pair of words which are one deletion apart is Helen/Helena, which are both legal characters. I might try to use this to get a solution where two different bytes can be removed.

Robin Ryder

Posted 2019-12-14T15:43:51.687

Reputation: 6 625

@JoKing Thanks! – Robin Ryder – 2019-12-18T18:06:07.843

1

GNU Sed 7 bytes, score=6

Full program

b;s/.//

Program with first byte removed

;s/.//

Input is a printable ASCII string, with no newlines.

zeppelin

Posted 2019-12-14T15:43:51.687

Reputation: 7 884

Strange that s/.^// interprets ^ as non-special whereas s/^// doesn't – user41805 – 2019-12-18T18:23:20.853

1

JavaScript, 52 bytes, score 51

The 37th byte, 1, is removable.

s=prompt()
console.log(s.slice(0,36+01)+s.slice(37))


JavaScript, 56 bytes, score 55

The 24th byte, 1, is removable.

s=prompt()
console.log(01?s:s.replace(/^(.{24})./,'$1'))

darrylyeo

Posted 2019-12-14T15:43:51.687

Reputation: 6 214

For the first one, 1+33 saves a byte, as you can remove the 1 to leave +33. – Neil – 2019-12-20T15:58:40.383

0

Symbolic Python, 11 bytes, score 10

__=_[_==_:]

Try it online!

The first _ is removable. Basically, the program sets __ to the input without the first character, which doesn't affect the IO variable _, so it outputs what is inputted. If you remove the _. it does set the variable, so the first character is removed. Try it online!

Jo King

Posted 2019-12-14T15:43:51.687

Reputation: 38 234