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++;
}
}
}
2How do we get the input? Can we take it as a list? – Rɪᴋᴇʀ – 2016-04-01T22:40:38.463
2And do all the bits start at 0 or 1? – Rɪᴋᴇʀ – 2016-04-01T22:42:16.537
10If those are the only options for interacting with Brussels sprouts, clearly you haven't had them roasted with olive oil, salt, and pepper. – Alex A. – 2016-04-01T22:45:38.567
9
Hey Mason! It is nice that you want to contribute to this site, but writing a good challenge is not easy and also requires some experience. 2 of your 3 challenges got closed so far and this one might be put on hold for being unclear as well. I would really recommend that you use the sandbox in the future, so you can get feedback and work potential flaws out before you post your challenge to the main site. However, I hope you stick around and have a great time here!
– Denker – 2016-04-01T22:46:32.8074Also you should really add some testscases, since this is not a very trivial task to solve and it's hard to say if a potential solution works correctly. But please note that testcases are not a replacement for a clear specification of the I/O formats which is definitely missing here. – Denker – 2016-04-01T22:48:47.927
2@AlexA. Mmmm. Fried in coconut oil with garlic, a bit of ginger, and a dash of Tabasco. – James – 2016-04-02T00:13:21.783
You should specify what happens if unknown instructions are provided. My answer quits the program when they are found. CatsAreFluffy's answer may execute arbitrary existing instructions or just quit the program. – Victor Stafusa – 2016-04-02T01:08:27.443
Why is this closed? – CalculatorFeline – 2016-04-02T01:42:12.183
1@CatsAreFluffy Probably because it is underspecified, which is sad but true. It doesn't says for example, what would happen if it branches to outside the instruction array (something that we both exploited for halting) nor it specified what would happen if an invalid instruction is given (a hole that both your answer and my new answer exploits for golfing). Also, it lacks test cases, which are very important to give confindence against possibly buggy interpreters. – Victor Stafusa – 2016-04-02T01:59:50.823
A few test cases and some specification. – CalculatorFeline – 2016-04-02T02:27:19.053
1@CatsAreFluffy I think that
chew swallow chew swallow vomit complain playwithfood
is an infinite loop, becauseplaywithfood
would go back two instructions tovomit
. And this would loop the sequencevomit complain playwithfood
forever. Thevomit
instruction will keep decrementing the bit index forever, but it would be kept resetted to zero everytime that it tries to go to -1 (which is outside the bounds of the array). My interpreter loops forever on that keeping outputting1
s continuously forever. – Victor Stafusa – 2016-04-02T03:55:57.3231Oops, please
swallow
once before running that program. Butundefinedbehavior
should not be in a testcase. – CalculatorFeline – 2016-04-02T13:10:05.2701Is this reopenable now? – CalculatorFeline – 2016-04-02T15:01:54.447