Problem Statement
You're running a special TopCoder competition where all programs are written in a derivative of a restrictive language called Unefunge, and all programs must complete in under 80,000 cycles. Furthermore, all programs are required to be Quines. For the purpose of this problem, a Quine is a special type of program that prints out its own source code before it prints anything else. Thus, in order for the Unefunge program ":,:9#@_1+" to be a legal program it would first have to print the string ":,:9#@_1+".
The language Unefunge works like this: a program is just a single line of characters of length N, where N is between 1 and 50 inclusive. The program never changes. An instruction pointer starts with the value 0 (called the IP), a delta is given the value 1 (called D), and an empty stack is created. The stack will store integer values during program execution in a first-in-last-out manner; if a number is pushed, it is placed in the stack, and if a value is popped, the last number pushed is removed (or a 0 is popped if the stack is empty). During each cycle, the IPth character in the program is read, the instruction corresponding to that character is executed, and then IP is incremented to the new value (3*N+IP+D)%N. The instructions are as follows:
- '0'-'9': pushes the number represented by that digit onto the stack.
- '$' : pops a value off the stack, and discards it.
- ':' : pops a value off the stack, then pushes that same value onto the stack twice.
- 'W' : Pops a value A, then pops a value B, then pushes A, then pushes B.
- ',' : pops a value X off of the stack, and prints the (absolute value of X)%Nth character in the source code.
- '+' : pops two values, adds them, and pushes the result back onto the stack.
- '-' : pops two values, subtracts the second popped value from the first, and pushes the result back onto the stack.
- '#' : multiplies D by 2 for this cycle only.
- 'R' : multiplies D by -1.
- 'S' : pops a value, and if positive pushes a 1, else pushes a -1.
- '_' : pops a value X, and sets D to that value X%N.
- 'J' : pops a value X, and sets IP to the (absolute value of X)%N. (IP is not incremented after this step)
- '@' : stops the program
You have to write a program that takes a
- If the program ends before printing out its source, return the string "BADEND X".
- If a number less than -1000000000 or a number greater than 1000000000 is pushed onto the stack, return "OVERFLOW X".
- If the result of an instruction makes it impossible for the output to match the source code, return "MISMATCH X".
- If the result of an instruction makes the output match the source code, return "QUINES X".
Definition
- Class:
- QuiningTopCoder
- Method:
- testCode
- Parameters:
- String
- Returns:
- String
- Method signature:
- String testCode(String source)
- (be sure your method is public)
Notes
- Start counting cycles at cycle 0. This should be obvious from the first example.
- Note that digits are not grouped, but pushed on in order: the code "3004" pushes a 3, then a 0, then another 0, then finally a 4, so the stack would contain the four numbers [3,0,0,4] and not the single number [3004].
Constraints
- source will contain between 1 and 50 characters inclusive.
- source will only consist of characters contained in "0123456789:$W,+-#RS_J@" (quotes included for clarity).
Examples
","
Returns: "QUINES 0"
The shortest quine.
"_"
Returns: "TIMEOUT"
This pops a 0 from the stack and places it into delta, freezing the code where it stands.
"1:+:1J"
Returns: "OVERFLOW 147"
This Unefunge code creates a stack of the powers of 2, until it overflows 1000000000.
"0,1+:#@:$1J"
Returns: "QUINES 91"
Note the irrelevant commands in the center of this quine. If code starts with "0,1+:", ends with "1J", and the middle preserves the first two elements on the stack, then the code is a quine.
"0,1+::9W-9W-S1W1W:+2_J_@_@"
Returns: "BADEND 437"
This code prints the first 18 characters of its code before halting.
"#R,#:+1+:#,R#"
Returns: "QUINES 97"
This non-trivial code is both a quine and a palindrome. :)
",1+:"
Returns: "QUINES 12"
Testing wraparound.
"0,1+:199+_@@@@@@@@@@@@@@@@@_#"
Returns: "QUINES 309"
Jumping the @-infested waters.
"R,#1+1:"
Returns: "MISMATCH 7"
",555"
Returns: "QUINES 12"
"#-:,7+"
Returns: "QUINES 27"
"W+#3:,1"
Returns: "QUINES 40"
"S6S+:43-W,J@,067S5#:_,:#W-2_4,SSW01+R3_SS,$,,W"
Returns: "QUINES 459"
"W:8W++"
Returns: "OVERFLOW 317"
"$:R+4"
Returns: "OVERFLOW 278"
"--R+9:"
Returns: "OVERFLOW 345"
"+2:-+R"
Returns: "OVERFLOW 348"
"+:+7R_"
Returns: "OVERFLOW 353"
"#:1163280$0S_SR_80#3,"
Returns: "MISMATCH 107"
"99WW+R1,#8+1"
Returns: "MISMATCH 62"
"77W_,-#-R#2"
Returns: "MISMATCH 59"
"091_1W-:S0-:+:+:+:+5W-1W_##########_$:,1+1J"
Returns: "QUINES 8940"
"099+:+:+1_1W-:S0-:+:+:+:+5W-1W_##########_$:,1+1J"
Returns: "QUINES 78396"
"55+:+5+::+:++::+:++,"
Returns: "MISMATCH 59"
"5:::+++:+:+:+:+:+:+:+:+:+:+:+:+:+:+:++1000000_"
Returns: "OVERFLOW 79337"
",S"
Returns: "QUINES 2"
"221,"
Returns: "MISMATCH 11"
",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
Returns: "QUINES 31"
"W687++_,"
Returns: "MISMATCH 25"
",7"
Returns: "QUINES 2"
"#,RS#5+9"
Returns: "MISMATCH 26"
"0,1+::9W-9W-S1W1W:+2_J_@_@"
Returns: "BADEND 437"
"1:+:1J"
Returns: "OVERFLOW 147"
"40WJ@"
Returns: "BADEND 4"
":"
Returns: "TIMEOUT"
"21-:+:3J"
Returns: "OVERFLOW 149"
"1W,0000"
Returns: "MISMATCH 9"
",@"
Returns: "BADEND 1"
"111112-,1111"
Returns: "MISMATCH 67"
",2,@"
Returns: "MISMATCH 2"
"72-J,@,777:J"
Returns: "BADEND 4"
"21-:+::+:++3J"
Returns: "OVERFLOW 94"