Skip to main content
added 277 characters in body
Source Link
Olivier Grégoire
  • 14.4k
  • 3
  • 32
  • 56

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);
  }
}

Try it online!

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 ifs are slow, wait until you see ifs 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.

Java 11

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);
  }
}

Try it online!

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 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.

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}).

But while I hope this code can compete, I wouldn't be surprised at all if it ends last.

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);
  }
}

Try it online!

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 ifs are slow, wait until you see ifs 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.

added 4 characters in body
Source Link
Olivier Grégoire
  • 14.4k
  • 3
  • 32
  • 56

Java 11

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);
  }
}

Try it online!

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, taking somewhere between.

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.

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 allowed 500 msslower, buffered System.{in,out}).

But while I hope this code can compete, I wouldn't be surprised at all if it ends last.

Java 11

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);
  }
}

Try it online!

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, taking somewhere between 200-300 ms of the allowed 500 ms.

Java 11

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);
  }
}

Try it online!

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 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.

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}).

But while I hope this code can compete, I wouldn't be surprised at all if it ends last.

added 4 characters in body
Source Link
Olivier Grégoire
  • 14.4k
  • 3
  • 32
  • 56

Java 11

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);
  }
}

Try it online!

Compile to bytecode with

javac Main.java

Run with

java -Xbatch Main

Note the -Xbatch is important as it will further precompile the codebytecode to machine code, taking somewhere between 200-300 ms of the allowed 500 ms.

Java 11

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);
  }
}

Try it online!

Compile with

javac Main.java

Run with

java -Xbatch Main

Note the -Xbatch is important as it will precompile the code to machine code, taking somewhere between 200-300 ms of the allowed 500 ms.

Java 11

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);
  }
}

Try it online!

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, taking somewhere between 200-300 ms of the allowed 500 ms.

Source Link
Olivier Grégoire
  • 14.4k
  • 3
  • 32
  • 56
Loading