From e05246048c60a6156cf89fe931b7271d34165500 Mon Sep 17 00:00:00 2001 From: aspwil Date: Fri, 6 Nov 2020 18:48:48 -0700 Subject: [PATCH] Instruction list output by parser is now sorted based on highest Dimension Added hash-map that maps the highest dimension to the position of the first occurrence of an instruction with that highest dimension Replaced full instruction list search with search based on hash map to immediately jump to position in instruction list that contains instructions sharing the same highest dimension Leave search when we no longer have same highest dimension as ball Insane efficiency improvement: Now a program with 78048 instructions spread across 19574 dimensions compiles and runs in 19 seconds instead of 61 minutes --- src/ndballsim/Instr.java | 11 +++++++- src/ndballsim/Main.java | 1 - src/ndballsim/Parser.java | 3 +++ src/ndballsim/Pos.java | 4 +++ src/ndballsim/Simulator.java | 52 ++++++++++++++++++++++-------------- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/ndballsim/Instr.java b/src/ndballsim/Instr.java index ce783cd..15384c8 100644 --- a/src/ndballsim/Instr.java +++ b/src/ndballsim/Instr.java @@ -7,7 +7,7 @@ import java.util.Arrays; -public class Instr { +public class Instr implements Comparable { //pos the position of the instruction in n-dim space public Pos pos; //the name of the instruction, this will be used to indentify what the instruction does during simlation @@ -22,9 +22,18 @@ public Instr(Pos pos,String name, Object... inputs){ this.info = inputs; } + public Pos getPos(){ + return pos; + } + @Override public String toString(){ return "Instr: "+name+", "+pos+", "+Arrays.toString(info); } + //this allows us to call collections.sort and sort by highest dim in an array list + @Override + public int compareTo(Instr instr) { + return ((Integer)pos.getHighestDim()).compareTo(((Integer)instr.pos.getHighestDim())); + } } \ No newline at end of file diff --git a/src/ndballsim/Main.java b/src/ndballsim/Main.java index 23eb07a..ce2a353 100644 --- a/src/ndballsim/Main.java +++ b/src/ndballsim/Main.java @@ -2,7 +2,6 @@ * NDBall Simulator by Aspen Wilson is licensed under CC0 1.0. To view a copy of this license, visit https://creativecommons.org/publicdomain/zero/1.0 */ package ndballsim; -import ndballsim.Pos.Vector; //this is the calss is run with the jar file, it will handle the command line input public class Main { diff --git a/src/ndballsim/Parser.java b/src/ndballsim/Parser.java index ac58824..32c323d 100644 --- a/src/ndballsim/Parser.java +++ b/src/ndballsim/Parser.java @@ -6,6 +6,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; +import java.util.Collections; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -262,6 +263,8 @@ public static Instr[] parse(String file) { } } + //sort the array list based on the highest dimention + Collections.sort(list); //return a list of all the instruction we parsed return list.toArray(new Instr[list.size()]); } diff --git a/src/ndballsim/Pos.java b/src/ndballsim/Pos.java index 8a9b7b9..9970dbe 100644 --- a/src/ndballsim/Pos.java +++ b/src/ndballsim/Pos.java @@ -90,6 +90,10 @@ public void setLength(int dim, int length) { } list.add(new Vector(dim, length)); } + + public int getHighestDim(){ + return highestDim; + } //this tells if the position are the same as each other @Override diff --git a/src/ndballsim/Simulator.java b/src/ndballsim/Simulator.java index 2105c29..db5b889 100644 --- a/src/ndballsim/Simulator.java +++ b/src/ndballsim/Simulator.java @@ -4,8 +4,8 @@ //this class simulates the ball in n-dim space and run ther program based on a list if instructions package ndballsim; -import java.util.Arrays; import java.util.Scanner; +import java.util.HashMap; public class Simulator { @@ -17,10 +17,19 @@ public class Simulator { public static void run(String file, int max, boolean doLog, boolean step, boolean infoTag) { long parseStartTime = System.nanoTime();//start measuring parcer time - Instr[] instrs = Parser.parse(file);//this is the list of instructions + Instr[] instrs = Parser.parse(file);//this is the sorted list of instructions parseTime = System.nanoTime() - parseStartTime;//stop measuring parcer time //begine messuring Sim time startTime = System.nanoTime(); + //this hash map maps the highest dimention to the position of the first ocourance of that dmention in the instr list + HashMap startPos = new HashMap<>(); + //assemble the hash map + for(int i = 0; i < instrs.length; i++){ + if(!startPos.containsKey(instrs[i].pos.getHighestDim())){ + startPos.put(instrs[i].pos.getHighestDim(), i); + } + } + log = doLog; Scanner in = new Scanner(System.in); //the scanner used for input from console String input; // this will be used to hold the input @@ -47,20 +56,23 @@ public static void run(String file, int max, boolean doLog, boolean step, boolea } //check if there is instruction at balls position - for (Instr instr : instrs) { + for (int i = startPos.get(ball.getHighestDim()); i < instrs.length; i++) { + if(ball.getHighestDim() != instrs[i].pos.getHighestDim()){ + break; + } //we found a matching instruction - if (ball.equals(instr.pos)) { + if (ball.equals(instrs[i].pos)) { //what instruction is it? - switch (instr.name) { + switch (instrs[i].name) { //change the balls movment to forward in the dimention in info 0 case ">": - movement[0] = (Integer) instr.info[0]; + movement[0] = (Integer) instrs[i].info[0]; movement[1] = 1; log("Movement changed to [" + movement[0] + "," + movement[1] + "]"); break; //change the balls movment to backward in the dimention in info 0 case "<": - movement[0] = (Integer) instr.info[0]; + movement[0] = (Integer) instrs[i].info[0]; movement[1] = -1; log("Movement changed to [" + movement[0] + "," + movement[1] + "]"); break; @@ -94,30 +106,30 @@ public static void run(String file, int max, boolean doLog, boolean step, boolea //Y logic case case "Y": //if ballVal is less then info 0 we want to send the ball along dimention info 2 - if (ballVal < (int) instr.info[0]) { - switch ((String) instr.info[1]) { + if (ballVal < (int) instrs[i].info[0]) { + switch ((String) instrs[i].info[1]) { //foward movement case ">": - movement[0] = (Integer) instr.info[2]; + movement[0] = (Integer) instrs[i].info[2]; movement[1] = 1; break; //backward moevment case "<": - movement[0] = (Integer) instr.info[2]; + movement[0] = (Integer) instrs[i].info[2]; movement[1] = -1; break; } //otherwise we want to send the ball along dimention info 4 } else { - switch ((String) instr.info[3]) { + switch ((String) instrs[i].info[3]) { //forward mevemnt case ">": - movement[0] = (Integer) instr.info[4]; + movement[0] = (Integer) instrs[i].info[4]; movement[1] = 1; break; //backwards movement case "<": - movement[0] = (Integer) instr.info[4]; + movement[0] = (Integer) instrs[i].info[4]; movement[1] = -1; break; } @@ -144,14 +156,14 @@ public static void run(String file, int max, boolean doLog, boolean step, boolea //data cell case "#": //check if the balls movement matches the memeory cells writing direction - if ((int) instr.info[2] == movement[0] && (((String) instr.info[1]).equals(">") && movement[1] == 1 || (((String) instr.info[1]).equals("<") && movement[1] == -1))) { + if ((int) instrs[i].info[2] == movement[0] && (((String) instrs[i].info[1]).equals(">") && movement[1] == 1 || (((String) instrs[i].info[1]).equals("<") && movement[1] == -1))) { //write to the cell - instr.info[0] = ballVal; - log("MEM CELL WRITTEN Val:" + ballVal + " Pos:" + instr.pos); + instrs[i].info[0] = ballVal; + log("MEM CELL WRITTEN Val:" + ballVal + " Pos:" + instrs[i].pos); } else { //read from the cell - ballVal = (int) instr.info[0]; - log("MEM CELL READ Val:" + ballVal + " Pos:" + instr.pos); + ballVal = (int) instrs[i].info[0]; + log("MEM CELL READ Val:" + ballVal + " Pos:" + instrs[i].pos); } break; //input a char @@ -185,7 +197,7 @@ public static void run(String file, int max, boolean doLog, boolean step, boolea + "if you see this please open an issue on the Github page\n" + "include a copy of your code, what version of the NDBallSim this error occured on" + "and the name of the instruction given on the next line " - + "Instruction name:\"" + instr.name + "\""); + + "Instruction name:\"" + instrs[i].name + "\""); } }