Java 8
1. Relaxed version (301 283 280 277 275 bytes)
Golfed as this:
class C{static int i,j,x,b[]=new int[256];public static void main(String[]z){Runnable[]r=new Runnable[26];r[20]=()->b[i]=-~x;r[9]=()->i++;r[6]=()->i--;r[13]=()->System.out.print(x);r[1]=()->j+=x;r[22]=()->j-=3*x;for(;;){x=b[i];r[z[j].charAt(3)-99].run();i*=~(i>>8)&1;j++;}}}
Somewhat ungolfed version (whitespaces and comments added):
class C {
// Declared as static so they may be changed inside the lambdas without the compiler complaining about that.
// i is the bit index and j is the instruction pointer.
// x is just to avoid refering to b[i] in order to save 3 bytes.
// b is our array. Uses ints instead of booleans to save bytes and use some clever math tricks.
static int i, j, x, b[] = new int[256];
public static void main(String[] z) {
// An array of lambdas. The index is the ascii code of 4th letter of the command name subtracted from 99.
// Thanks for CatsAreFluffy for telling about the 4th letter trick.
Runnable[] r = new Runnable[26];
r[20] = () -> b[i] = -~x; // chew
r[9] = () -> i++; // swallow
r[6] = () -> i--; // vomit
r[13] = () -> System.out.print(x); // complain
r[1] = () -> j += x; // feedtodog. It is 1 or 0 instead of 2 and 1 due to the j++ down there.
r[22] = () -> j -= 3 * x; // playwithfood. It is -3 or 0 instead of -2 and +1 due to the j++ down there.
// This is the interpreter itself. Runs forever (or until an exception is raised).
for (;;) {
x = b[i];
// Fetch an instruction and runs it. May throw an exception or execute some arbitrary instruction if the instruction name is unknown or was mistyped.
r[z[j].charAt(3) - 99].run();
// Resets the bit index if out of range.
i *= ~(i >> 8) & 1;
// Next instruction. No special treatment for branching needed because they already considers this.
j++;
}
}
}
We surely should have testcases. I am not sure if there is some bug hiding out there.
Anyway I run it with that (input is given as command line arguments):
chew complain swallow chew complain swallow chew complain swallow complain
And here is the output:
1110
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at C.main(C.java:1)
The ArrayIndexOutOfBoundsException
is the standard way to finish the program, it is not a bug!
BTW, this answer abuses the fact that the 4th char of each command is different than each other (thanks CatsAreFluffy). This means that whew
is interpreted as chew
and that yellow
is interpreted as swallow
.
2. Strict version (354 337 334 331 329 bytes)
If strict conformance to command names are required (and just looking for the 4th letter in command's name is not enough), then I have this alternative similar answer with 329 bytes:
import java.util.*;class C{static int i,j,x,b[]=new int[256];public static void main(String[]z){List o=Arrays.asList("chew","swallow","vomit","complain","feedtodog","playwithfood");Runnable[]r={()->b[i]=-~x,()->i++,()->i--,()->System.out.print(x),()->j+=x,()->j-=3*x};for(;;){x=b[i];r[o.indexOf(z[j])].run();i*=~(i>>8)&1;j++;}}}
Somewhat ungolfed version (whitespaces and comments added):
// Needed for java.util.List and java.util.Arrays.
import java.util.*;
class C {
// Declared as static so they may be changed inside the lambdas without the compiler complaining about that.
// i is the bit index and j is the instruction pointer.
// x is just to avoid refering to b[i] in order to save 3 bytes.
// b is our array. Uses ints instead of booleans to save bytes and use some clever math tricks.
static int i, j, x, b[] = new int[256];
public static void main(String[] z) {
// Declared as a list so we can use the indexOf method further down. Screw up the generics.
List o = Arrays.asList("chew", "swallow", "vomit", "complain", "feedtodog", "playwithfood");
// An array of lambdas.
Runnable[] r = {
() -> b[i] = -~x, // chew
() -> i++, // swallow
() -> i--, // vomit
() -> System.out.print(x), // complain
() -> j += x, // feedtodog. It is 1 and 0 instead of 2 and 1 due to the j++ down there.
() -> j -= 3 * x // playwithfood. It is -3 and 0 instead of -2 and +1 due to the j++ down there.
};
// This is the interpreter itself. Runs forever (or until an exception is raised).
for (;;) {
x = b[i];
// Fetch an instruction and runs it. Throws an exception on unknown or mistyped instructions.
r[o.indexOf(z[j])].run();
// Resets the bit index if out of range.
i *= ~(i >> 8) & 1;
// Next instruction. No special treatment for branching needed because the branching instructions already considers this.
j++;
}
}
}