Java 11 (Oracle JDK)
Just curious about how it runs.
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import static java.nio.charset.StandardCharsets.US_ASCII;
public class Main {
public static void main(String[] args) throws IOException {
var stateMachine = new int[6 * 256];
var response = "bang!".getBytes(US_ASCII);
Arrays.fill(stateMachine, 5 * 256);
stateMachine[5 * 256 + 'd'] = stateMachine[4 * 256 + 'd'] = stateMachine[3 * 256 + 'd'] = stateMachine[2 * 256 + 'd'] = stateMachine[1 * 256 + 'd'] = 4 * 256;
stateMachine[4 * 256 + 'r'] = 3 * 256;
stateMachine[3 * 256 + 'a'] = 2 * 256;
stateMachine[2 * 256 + 'w'] = 256;
stateMachine[256 + '!'] = 0;
var in = new FileInputStream(FileDescriptor.in);
var out = new FileOutputStream(FileDescriptor.out);
for (var state = 5 * 256; state != 0; ) {
state = stateMachine[state | in.read()];
}
out.write(response, 0, 5);
System.exit(0);
}
}
Compile to bytecode with
javac Main.java
Run with
java -Xbatch Main
Note the -Xbatch
is important as it will further precompile the bytecode to machine code. It's also important to run with Oracle JDK because it has the best machine compiler.
It will reach the read method in around 200-300 ms after start, after taking time to compile to machine code in memory. So I didn't optimize until there. Hence the reason why I let multiplications as is. However, after the first read, no instruction is superfluous.
I used a state machine to remove all the jumps, similar to Bubbler' submission, because if you thought that if
s are slow, wait until you see if
s in Java!
Also I optimized the reading and writing by creating my own non buffered streams (I used new File{Input,Output}Stream(FileDescriptor.{in,out})
instead of the slower, buffered System.{in,out}
).
Implementation note: if EOF is found before the expected trigger, it will crash.
But while I hope this code can compete, I wouldn't be surprised at all if it ends last.