Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Numberwang Interpreter -- written by JungHwan Min
- **/
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.ArrayList;
- import java.util.List;
- public class Numberwang {
- private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
- public enum Error {
- EMPTY_CODE(0, "Empty code."),
- BRACKET_MISMATCH(1, "Brackets (4 and 7) do not match."),
- INVALID_CHARACTER(2, "Invalid character in input."),
- NO_CODE(3, "Usage: java Numberwang \"path/to/your/code\""),
- CODE_READ_ERR(4, "Reading code failed.");
- private final int code;
- private final String message;
- private Error(int code, String message) {
- this.code = code;
- this.message = message;
- }
- private void throwError() {
- System.err.println("Error: "+message);
- System.exit(code);
- }
- }
- public static void main(String[] args) {
- if (args.length == 0)
- Error.NO_CODE.throwError();
- String code;
- try {
- code = new String(Files.readAllBytes(Paths.get(args[0])));
- } catch (IOException e) {
- Error.CODE_READ_ERR.throwError();
- code = "";
- }
- List<Byte> commands = new ArrayList<Byte>();
- List<Integer> coeffs = new ArrayList<Integer>();
- optimize(code, commands, coeffs);
- run(commands, coeffs);
- }
- // Delete 5, 6, and non-digit characters
- private static String del56(String code) {
- // Strip non-digits
- StringBuilder codeDigits = new StringBuilder();
- for (int i = 0; i < code.length(); i++) {
- char ch = code.charAt(i);
- if (ch >= '0' && ch <= '9')
- codeDigits.append(ch);
- }
- // Stop running if the code is empty.
- if (codeDigits.length() == 0) {
- Error.EMPTY_CODE.throwError();
- }
- // Check if last char is 5 or 6 and append 0 if it is (harmless even when the code ends in 55, 56, etc.)
- char last = codeDigits.charAt(codeDigits.length() - 1);
- if (last == '5' || last == '6')
- codeDigits.append('0');
- int bracketMatch = 0;
- char[] codeArr = codeDigits.toString().toCharArray();
- StringBuilder codeFinal = new StringBuilder();
- for (int i = 0; i <= codeArr.length - 1; i++) {
- switch (codeArr[i]) {
- case '0' :
- codeFinal.append('0');
- break;
- case '1' :
- codeFinal.append('1');
- break;
- case '2' :
- codeFinal.append('2');
- break;
- case '3' :
- codeFinal.append('3');
- break;
- case '4' :
- codeFinal.append('4');
- bracketMatch += 1;
- break;
- case '5' :
- for(int j = 0; j < codeArr[i+1] - '0'; j++)
- codeFinal.append('2');
- i++;
- break;
- case '6' :
- for(int j = 0; j < codeArr[i+1] - '0'; j++)
- codeFinal.append('9');
- i++;
- break;
- case '7' :
- codeFinal.append('7');
- bracketMatch -= 1;
- break;
- case '8' :
- codeFinal.append('8');
- break;
- case '9' :
- codeFinal.append('9');
- break;
- default :
- break;
- }
- if (bracketMatch < 0)
- Error.BRACKET_MISMATCH.throwError();
- }
- if (bracketMatch != 0)
- Error.BRACKET_MISMATCH.throwError();
- return codeFinal.toString();
- }
- // Optimize -- delete irrelevant characters, use byte array, run-length encode
- private static void optimize(String code, List<Byte> commands, List<Integer> coeffs) {
- runLengthEncode(toByteArray(del56(code)), commands, coeffs);
- }
- // Convert string to byte array
- private static byte[] toByteArray(String code) {
- byte[] arr = code.getBytes();
- for (int i = 0; i < arr.length; i++)
- arr[i] -= '0';
- return arr;
- }
- // Run-length encode
- private static void runLengthEncode(byte[] code, List<Byte> commands, List<Integer> coeffs) {
- byte[] codeNew = new byte[code.length + 1];
- System.arraycopy(code, 0, codeNew, 0, code.length);
- codeNew[codeNew.length - 1] = 10; // Append a 10 to make sure the run-length encoding includes the last command.
- int runLength = 1;
- byte run = codeNew[0];
- List<Integer> brackets = new ArrayList<Integer>();
- for (int i = 1; i < codeNew.length; i++) {
- if (run == 4) {
- commands.add(run);
- coeffs.add(0); // Placeholder
- brackets.add(coeffs.size() - 1);
- run = codeNew[i];
- } else if (run == 7) {
- commands.add(run);
- int lastIndex = brackets.size() - 1;
- int lBracket = brackets.get(lastIndex);
- coeffs.add(lBracket);
- coeffs.set(lBracket, coeffs.size() - 1);
- brackets.remove(lastIndex);
- run = codeNew[i];
- } else if (run == 3 || run == 8) {
- commands.add(run);
- coeffs.add(0); // Placeholder
- run = codeNew[i];
- } else if (run == codeNew[i]) {
- runLength++;
- } else {
- commands.add(run);
- coeffs.add(runLength);
- run = codeNew[i];
- runLength = 1;
- }
- }
- }
- private static void run(List<Byte> commands, List<Integer> coeffs) {
- byte[] cells = new byte[65536];
- short loc = 0;
- for(int i = 0; i < commands.size(); i++) {
- switch (commands.get(i)) {
- case 0: loc += coeffs.get(i);
- break;
- case 1: loc -= coeffs.get(i);
- break;
- case 9: cells[loc & 0xffff] += coeffs.get(i);
- break;
- case 2: cells[loc & 0xffff] -= coeffs.get(i);
- break;
- case 3: System.out.print((char) (cells[loc & 0xffff] & 0xff));
- break;
- case 8: cells[loc] = getInput();
- break;
- case 4: if(cells[loc & 0xffff] == 0)
- i = coeffs.get(i) - 1;
- break;
- case 7: if(cells[loc & 0xffff] != 0)
- i = coeffs.get(i) - 1;
- break;
- default: break;
- }
- }
- }
- private static byte getInput() {
- try {
- int i = in.read();
- if (i == -1)
- i = 0;
- else if (i > 256)
- Error.INVALID_CHARACTER.throwError();
- return (byte) i;
- } catch (IOException e) {
- System.out.println("Error from user input");
- Error.INVALID_CHARACTER.throwError();
- return (byte) 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment