23
\$\begingroup\$

Your boss has recently learned of this interesting programming language called English. He has had this "revolutionary" idea, he wants to code with you to double code production rates! Since he is not a tech savvy, he wants you to write a compiler for it so that he can code too!

Now, you are an evil lazy programmer and obviously will not write a program to compile this ridiculously complex language. Instead, you are going to make sure there is always an error in your boss's code, so that he never gets to the actual compilation and is stuck fixing grammar errors instead of coding.

The challenge is to write a program that can be run from the terminal, and accepts a file path as an argument. The program has to:

  1. modify the file input by introducing a typo.
  2. Pretend to fail compilation due to encountering the typo you introduced.
  3. Running the program on copies of the same file should not introduce the same typo twice in a row.

To illustrate the challenge, running your program on this file:

Take an array as input.
Sort the array.
Output the array.

should output something along the lines of

Error on line 1:
'Take an arqay as input.'
         ^
arqay is not a valid identifier.

and the file that you told the program to compile should now look like:

Take an arqay as input.
Sort the array.
Output the array.

Here are some more details on the specs of the program:

Your program is allowed to assume that swapping any character in the program your boss inputs for a different random character will cause a grammar error. Your program should not use non alphabetical characters to create errors in your bosses code. Your boss would never use a number or symbol, and he would find out that something is afoot. Your program should only introduce errors to the words in your boss's program. Do not change the spaces in the sentences, or the punctuation. Your program should not alter the case of the program your boss tries to compile, meaning errors like arQay are invalid. This prevents errors like take instead of Take happening, or Array instead of array. Your program should output the error by first stating what line the error is at:

Error on line <insert line number here>:

It should then print out the line with the error inside ' symbols. On the next line it should place a ^ symbol under the word with the error, and finally it should have some text describing the error (this part is up to you, you can say whatever you want there as long as it describes an error).

You can assume that the input file exists and it is not empty. You can also assume the input file has no grammatical errors before you add one.

Bonuses:

-60 bytes if the errors your code introduces are not completely random, but typo-based as in this question.

-60 bytes for at least 5 different error messages, randomly alternating.

-60 bytes if your program has a 1 in 100 chance or less to output some demotivational message to your boss.

EDIT: The byte count of the messages do not count towards your score. (Thanks to Martin Büttner for this good idea)

This is code-golf, shortest byte count wins. Please do not golf the error message content, your boss wont be happy if he can't understand the error messages, and will ask you to fix them for him.

\$\endgroup\$
4
  • \$\begingroup\$ Do I have to deal with lines that don't contain letters? \$\endgroup\$
    – Οurous
    Nov 1 '14 at 6:45
  • \$\begingroup\$ You can only create a typo in alphabet characters, and you can assume the input file is a valid non-empty file that exists. \$\endgroup\$
    – rodolphito
    Nov 1 '14 at 7:08
  • 8
    \$\begingroup\$ I'm not a fan of leaving the error messages up to us. Even if we "don't golf the error message" they could still make a difference of a handful of bytes, of probably even two dozen if we're going for the second bonus. That can be quite a lot. I think for a fair golfing contest you should specify 5 error messages and a demotivational message, or let us subtract their string length's from the byte count. \$\endgroup\$ Nov 1 '14 at 11:10
  • \$\begingroup\$ Thanks for the tip, i had thought about having predefined messages, but i wanted to give a little more freedom with that. Substracting the message byte counts from the score is a great idea. \$\endgroup\$
    – rodolphito
    Nov 1 '14 at 19:13
3
\$\begingroup\$

TI-BASIC, 77 - 34 (error text) = 43

In case he wants to do in on his TI-83/84 calculator ;)

As standard for functions, file string should be in Ans so it can return and display the output.

Ans->Str1:If 1=inString(Ans,"A
Then:"B
Else:"A
End:Disp "ERROR ON LINE 1","'"+Ans+sub(Str1,2,-1+length(Str1))+"'"," ^ INVALID

Note that many tokens are one byte.

\$\endgroup\$
13
  • \$\begingroup\$ Where could I run this code? \$\endgroup\$
    – rodolphito
    Nov 1 '14 at 22:54
  • \$\begingroup\$ TI-83/84 calculator or an emulator for one. \$\endgroup\$
    – Timtech
    Nov 2 '14 at 12:27
  • \$\begingroup\$ inString, Ans, sub, Else, Then, End, Disp , Str1... Aren't those all 1 byte for the calculator? \$\endgroup\$ Nov 2 '14 at 15:30
  • 4
    \$\begingroup\$ WHAT????????????????? That's like saying that 8 bits isn't 1 byte!!!!!!!!! If I present a code in assembly, using binary form, will they also count the bytes as 1 macro of 5+ bytes? That is plainly stupid! (sorry the strong words, but it IS REALLY STUPID!) This doesn't represent your code. I mean Ans isn't the same as the byte represented by Ans. One is A*n*s which produces any result the calculator wants, the other returns the value of the last arithmetic expression. Taking this into account, I think that not accepting the REAL count makes this a wrong representation of the code. \$\endgroup\$ Nov 2 '14 at 21:11
  • 7
    \$\begingroup\$ It doesn't seem to randomly modify the file, it looks as if it always displays a change in line 1, and changes the first letter to B if its A, or to A if not. \$\endgroup\$
    – rodolphito
    Nov 3 '14 at 4:51
2
\$\begingroup\$

JavaScript, 484 458 bytes

F=process.argv[2]
C=console.log
r=require('fs')
l=r.readFileSync(F,'utf-8').replace(/\r/g,'').split`
`
S=b=>b[H=Math.random()*b.length|0]
L=S(l)
y=H
C(`Error on line ${y+1}:`);
while(/[^a-z]/.test(S(R=L.split` `)));
Y=H
R[Y]=R[Y].replace(t=S(R[Y]),(J=_=>(Z=S('abcdefghijklmnopqrstuvwxyz'))==t?J():Z)(t))
j=R.join` `
C(`'${j}'`)
C(' '.repeat(1+R.reduce((a,e,i)=>a+=i<Y&&e.length,Y))+'^')
C('Unexpected '+R[Y])
r.writeFileSync(F,l.map((e,i)=>i==y?j:e).join`
`)

No TIO link, but it takes in a path like ./test.txt as input via command line arguments and outputs the error like so:

Error on line 1:
'Take an mrray as input.'
         ^
Unexpected mrray

I'm a little unsure about how to count the error message length. Is it the length of Unexpected (with the space)?

Anyway, this took a while. Basically selects a line at random, then a word at random, replaces a random letter of that word with another random letter that is not the same, then outputs line number, modified line, then the caret after a number of spaces. Then outputs Unexpected <word> where is the aforementioned word.

Then uses writeFileSync to replace the content.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 245 239 bytes

import sys,time
t=time.time
p=sys.argv[1]
f=open(p).read()
a=f[0]
f=chr(ord(a)+int(-t()if a in"yzYZ"else t())%2+1)+f[1:]
open(p,"w").write(f)
n="\n"
s=f.split
print(f"Error on line 1:\n'{s(n)[0]}'\n ^\n{s()[0]} is not a valid identifier.")

Slightly bending the rules in a few ways:

  • It always makes the error on the first character, which it assumes to be a valid character, since otherwise it would be an English syntax error
  • It only ever outputs two different typos for any given input: for A-X it shifts either +1 or +2, for Y-Z it shifts either -1 or -2.
  • It uses int(time.time()) as its PRNG, so running the program several times within a second will output the same typo.

Output on the sample input:

Error on line 1:
'Uake an array as input.'
 ^
Uake is not a valid identifier.

I'm unsure about how long the error message is, anyone have any ideas?

\$\endgroup\$

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.