I'm creating a program for an assignment which takes an input from System.in in the following format:
Inky Pinky Blinky Clyde Luigi Mario Bowser
0 2
1 2
5 6
3 5
2 4
4 5
2 3
1 4
closefriends 1 2 4
where the first line is persons, the numbers are friendships.
The program checks whether or not the people listed in the last line are in a "close friendship", where they're all friends.
I represent the network as an incident matrix, and it passes every test on the test site we use, except one, which fails with a "Runtime Error". I know it's not an exception, because catching all exceptions does nothing to the error, while catching all errors does.
Here's the code:
public class CloseFriends {
// Contains edges represented as an incident matrix
private static boolean edges[][];
// Adds a directed edge between v1 and v2
// The method sorts the edges to reduce space used
public static void addEdge(int v1, int v2) {
if (v1 > v2) {
edges[v1][v2] = true;
}
else {
edges[v2][v1] = true;
}
}
// Creates a graph with V vertices
public static void createVertices(int V) {
edges = new boolean[V][V];
}
// Checks if an edge exists between v1 and v2
public static boolean isFriends(int v1, int v2) {
if (v1 > v2) {
return edges[v1][v2];
}
else {
return edges[v2][v1];
}
}
// Checks if an ArrayList of vertices is close friends
public static void closeFriends(ArrayList<Integer> vertices) {
int count = 0;
int size = vertices.size();
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (isFriends(vertices.get(i), vertices.get(j))) {
count++;
}
}
}
// The clique should contain n*(n-1)/2 edges for everyone to be connected
if (count == (size * (size - 1) / 2)) {
System.out.println("yes");
}
else {
System.out.println("no");
}
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
// Count vertices, and create that amount
int V = 0;
while (st.hasMoreTokens()) {
st.nextToken();
V++;
}
createVertices(V);
ArrayList<Integer> friends = new ArrayList<Integer>();
// While System.in has something to be read
while (in.ready()) {
// Read the line and add edges based on input, or run the algorithm
String edge = "";
edge = in.readLine();
if (edge != null) {
st = new StringTokenizer(edge);
if (!edge.startsWith("closefriends")) {
addEdge(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
else {
st.nextToken();
while (st.hasMoreTokens()) {
friends.add(Integer.parseInt(st.nextToken()));
}
}
}
}
closeFriends(friends);
}
}
Thanks!
Related
I am making 3D-Objects made of Triangles. These Triangles have 3 Vectors.
Now I have a file with alot of numbers... If a line starts with "v" the line has x-, y-, and z-coordinates of a Vector.
If a line starts with "f" the line has the line of the Vector in the .txt file that I need for my Triangle.
The file starts with all "v"s first and then continues with the "f"s.
Example: (the number at the beginning is just the line)
21 v 1.2000 0.20000 -1.0000 -> Vector1(1.2, 0.2, -1)
22 v 1.2000 0.20000 1.00000 -> Vector2(1.2, 0.2, 1)
23 v -1.200 -0.2000 1.00000 -> Vector3(-1.2, -0.2, 1)
...
71 f 21 23 22 -> Triangle(Vector1, Vector3, Vector2)
And this is what i tried, which obviously did not work since I am a Java newbie :P
public static ArrayList<Triangle> mesh = new ArrayList<>();
public static void loadObject(String fileName) {
try {
Scanner scan = new Scanner(fileName);
ArrayList<Vector> vectors = new ArrayList<>();
while (scan.hasNextLine()) {
if (scan.equals("v")) {
Vector v = new Vector();
int i = 0;
while (scan.hasNextDouble() && i < 3) {
if (i == 0) {
v.setX(scan.nextDouble());
}
if (i == 1) {
v.setY(scan.nextDouble());
}
if (i == 2) {
v.setZ(scan.nextDouble());
}
i++;
}
vectors.add(v);
}
if (scan.equals("f")) {
Triangle t = new Triangle();
int j = 0;
while (scan.hasNextInt() && j < 3) {
if (j == 0) {
t.setVec1(vectors.get(scan.nextInt() - 1));
}
if (j == 1) {
t.setVec2(vectors.get(scan.nextInt() - 1));
}
if (j == 2) {
t.setVec3(vectors.get(scan.nextInt() - 1));
}
j++;
}
mesh.add(t);
}
}
} catch (Exception e) {
}
}
Thanks for the help
You are describing the Wavefron OBJ file format for which many loaders already exist. You should consider using an existing loader instead of rolling your own.
Googling for it I find three Java .obj loaders on Github right away:
javagl/Obj
seanrowens/oObjLoader
Blunderchips/LWJGL-OBJ-Loader
I have not used any of these so you would need to try them out yourself and see if they provide the right API for you and solve your concrete problem.
How about something like this:
static List<Triangle> parse(String fileName)
{
List<Triangle> mesh = new ArrayList<>();
Map<String, Vector> vm = new HashMap<>();
try (Scanner scan = new Scanner(new FileReader(fileName)))
{
while(scan.hasNextLine())
{
String[] p = scan.nextLine().split("\\s");
if("v".equals(p[1]))
{
vm.put(p[0], new Vector(Double.parseDouble(p[2]), Double.parseDouble(p[3]), Double.parseDouble(p[4])));
}
else if("f".equals(p[1]))
{
mesh.add(new Triangle(vm.get(p[2]), vm.get(p[3]), vm.get(p[4])));
}
}
}
catch(IOException e)
{
e.printStackTrace();
}
return mesh;
}
The user will be asked what path and what distance. Then it'll compute the shortest distance using Dijkstra's algorithm. The problem is some distance and paths are wrong. There are distances that has 2147483647 and its path is null. The algo works perfectly with zero as a starting point. How do i fix it?
If the user inputs
Enter first path: 0
Enter second path: 1
Enter distance: 1
Do you want to add path again? y
Enter first path: 1
Enter second path: 3
Enter distance: 2
Do you want to add path again? y
Enter first path: 3
Enter second path: 5
Enter distance: 4
Do you want to add path again? y
Enter first path: 1
Enter second path: 2
Enter distance: 3
Do you want to add path again? y
Enter first path: 0
Enter second path: 2
Enter distance: 8
Do you want to add path again? y
Enter first path: 0
Enter second path: 4
Enter distance: 9
Do you want to add path again? n
V D P
0 2147483647null //this part should be 1 and the path is 1-0
1 0null
2 31 - 2
3 21 - 3
4 2147483647null // this part should be 10 and the path is 0-4
5 63 - 5
=========================================================================
import java.util.*;
public class DijkstraAlgo {
final static int VERTICES = 6;
public static int minDistance(int distance[], Boolean shortestPath[]){
int minDist = Integer.MAX_VALUE;
int minIndex = -1;
for(int i = 0;i < VERTICES;i++){
if(shortestPath[i] == false && distance[i] <= minDist){
minDist = distance[i];
minIndex = i;
}
}
return minIndex;
}
public static void dijkstra(int path[][], int startingPoint){
int shortestDist[] = new int[VERTICES];
Boolean shortestPath[] = new Boolean[VERTICES];
String paths[] = new String[VERTICES];
for(int i = 0;i < VERTICES;i++){
shortestDist[i] = Integer.MAX_VALUE;
shortestPath[i] = false;
}
shortestDist[startingPoint] = 0;
for(int ctr = 0;ctr < VERTICES - 1;ctr++){
int index = minDistance(shortestDist, shortestPath);
shortestPath[index] = true;
for(int j = 0;j < VERTICES;j++){
if(!shortestPath[j] && path[index][j] != 0 && shortestDist[index] != Integer.MAX_VALUE && shortestDist[index] + path[index][j] < shortestDist[j]){
shortestDist[j] = shortestDist[index] + path[index][j];
paths[j] = Integer.toString(index) + " - " + " " + Integer.toString(j);
System.out.println(shortestDist[j]);
}
}
}
printAnswer(shortestDist, VERTICES, paths);
}
public static void printAnswer(int distance[], int vertices, String paths[]){
System.out.println("V D P");
for(int i = 0; i < VERTICES; i++)
System.out.println(i + " " + distance[i] + paths[i]);
}
public static void main(String args[]){
int start;
int end;
int path[][] = new int[6][6];
int distance;
Scanner input = new Scanner(System.in);
String choose;
boolean ans = true;
while(ans == true){
System.out.print("Enter first path: ");
start = input.nextInt();
System.out.print("Enter second path: ");
end = input.nextInt();
System.out.print("Enter distance: ");
distance = input.nextInt();
path[start][end] = distance;
System.out.print("Do you want to add path again? ");
choose = input.next();
if(choose.equals("y") || choose.equals("Y"))
ans = true;
else if(choose.equals("n") || choose.equals("N"))
ans = false;
else
System.out.println("Invalid input!");
}
dijkstra(path, 1);
}
}
I don't know what's wrong with your code, being honest. I don't plan to go through and try to debug it either; Eclipse can do that for you (as I linked in the comment).
What I will provide is a better means of approaching this, IMO. Storing your data in arrays of integers is a convoluted approach that's going to lead to confusion (as is evident here). One of the main benefits of using an object-oriented language like Java is that you can form your data in a coherent manner relevant to the context.
Consider creating two classes:
public class DijkstraNode {
private int label;
private List<DijkstraLink> links;
public DijkstraNode(int label) {
this.label = label;
links = new ArrayList<DijkstraLink>();
}
public int getLabel() {
return label;
}
public void addLink(DijkstraLink link) {
links.add(link);
}
public List<DijkstraLink> getLinks() {
return links;
}
}
...
public class DijkstraLink {
private DijkstraNode node;
private int distance;
public DijkstraLink(DijkstraNode node, int distance) {
this.node = node;
this.distance = distance;
}
public DijkstraNode getLinkedNode() {
return node;
}
public int getDistance() {
return distance;
}
}
Whenever you create a bi-directional link between nodes:
public void createTwoWayLink(DijkstraNode first, DijkstraNode second, int distance) {
first.addLink(new DijkstraLink(second, distance));
second.addLink(new DijkstraLink(first, distance));
}
Then evaluating Dijkstra's becomes a much simplier task:
public void computeDijkstras(DijkstraNode startNode, List<DijkstraNode> nodes) {
Map<DijkstraNode, Integer> distances = new HashMap<DijkstraNode, Integer>();
for (DijkstraNode node : nodes) {
if (node != startNode) {
distances.put(node, Integer.MAX_VALUE);
}
else {
distances.put(node, 0);
}
}
List<DijkstraNode> computedNodes = new ArrayList<DijkstraNode>();
DijkstraNode toEval = computeSmallestUncomputedNode(distances, computedNodes); // TODO
while (toEval != null) {
for (DijkstraLink link : toEval.getLinks()) {
if (computedNodes.contains(link.getLinkedNode()) {
continue;
}
int evalDist = link.getDistance() + distances.get(toEval);
if (evalDist < distances.get(link.getLinkedNode())) {
distances.put(link.getLinkedNode(), evalDist);
}
}
computedNodes.add(toEval);
toEval = computeSmallestUncomputedNode(distances, computedNodes);
}
// distances computed; do whatever.
}
This isn't a complete implementation. I didn't want to do your homework for you. However, I did want to include enough of an example of how capitalizing on object-oriented design and internal Java data structures (such as the List and Map objects used) make execution much more coherent, and, thus, easier to work with. Hope this helps.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need to calculate the minimum number of jumps to reach the end of an Array with dice throw Array Value may be negative/positive value:
when positive----> Move Forward
when negative ------> go back
The Array may also contain R value, which means that the player have to throw the dice again
The start position is marked on our Array with S and End position with E The Start Position is not always the first element of the Array and End position is not always at the end, it can even be before S
Example: Array = {4, S, -2,1, R, 4,3,4,3,-5,2,-4, E}
the player start on S position the fastest way to reach E:
Throwing the dice to have 3 and reach the R case (first move)
throwing the dice again and having 6 to reach the 2 Case (second movement)
Jumping 2 cases to reach E (third move)
so the best solution for this example is: 3 moves
Lets give you a hint: the key thing to learn here: sometimes you have to transform your input data in order to find a good way to solve your problem.
In your case; consider turning your array into a graph:
Each array index is a node within that graph
The value of each array position tells you something about edges to other nodes. For example, if a(0) is R; then a(0) would be connected to a(1), a(2) .. a(6) - because you can reach the next 6 elements.
For starters; I would suggest to do that manually; just draw the graph for example array.
So, the steps to solve your problem:
Transform your array into a graph
Search the net for algorithms to find minimum length paths in graphs
Print out that path; resulting in the minimal list from S to E
Implementation is left as exercise to the reader.
I wrote this working solution i share it for anyone interested , but when it comes to deal with big Array (3000 for example) it throws a java heap space error as the code will consume huge amount of memory , any help or advice will be appreciated
public class Solution {
static int startPosition;
public static int compute(BufferedReader br) throws IOException {
final int totalNodeCount = getTotalNodeNumber(br);
final String caseArray[] = new String[totalNodeCount];
bufferToArray(br, caseArray);
startPosition = getStartPosition(caseArray);
final boolean visited[] = new boolean[caseArray.length];
int minimumNumberOfMove = 0;
final List<Integer> reachableList = new ArrayList<Integer>();
for (int i = 1; i <= 6; i++)
{
visitedInitilise(visited);
if (((startPosition + i) < totalNodeCount) && ((startPosition + i) > 0))
getMinimumNumberOfMoves(caseArray, visited, startPosition + i, 0, reachableList);
}
// Retriving Minimum number of move from all reachble route
if (reachableList.isEmpty())
minimumNumberOfMove = Constants.IMPOSSIBLE;
else
{
minimumNumberOfMove = reachableList.get(0);
for (int i = 0; i < reachableList.size(); i++)
if (reachableList.get(i) < minimumNumberOfMove)
minimumNumberOfMove = reachableList.get(i);
}
return minimumNumberOfMove;
}
static int getStartPosition(String[] plateau){
int startIndex = 0;
for (int i = 0; i <= (plateau.length - 1); i++)
if (plateau[i].equals("S"))
{
startIndex = i;
break;
}
return startIndex;
}
static void bufferToArray(BufferedReader br, String[] plateau) {
String line;
int i = 0;
try
{
while ((line = br.readLine()) != null)
{
plateau[i] = line;
i++;
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static int getTotalNodeNumber(BufferedReader br) {
int i = 0;
try
{
i = Integer.parseInt(br.readLine());
} catch (NumberFormatException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return i;
}
static List<Integer> getMinimumNumberOfMoves(String[] plateau, boolean[] visited, final int currentIndex,
int currentNumberOfMoves, List<Integer> list) {
Boolean endIsReached = false;
Boolean impossible = false;
visited[startPosition] = true;
// Checking if the current index index is negativ
if (currentIndex < 0)
impossible = true;
while ((endIsReached == false) && (impossible == false) && (visited[currentIndex] == false)
&& (currentIndex < plateau.length))
{
try
{
switch (plateau[currentIndex]) {
case "E": {
// if end is reached , pushing number of move into our list
endIsReached = true;
list.add(currentNumberOfMoves + 1);
break;
}
case "R": {
// Marking node as visited
visited[currentIndex] = true;
for (int i = 1; i <= 6; i++)
{
// Marking all case after R case as non visited
for (int j = currentIndex + 1; j < visited.length; j++)
visited[j] = false;
// Calculating number of move after R case
if (((currentIndex + i) < plateau.length) && (currentIndex > 0))
getMinimumNumberOfMoves(plateau, visited, currentIndex + i, currentNumberOfMoves + 1, list);
}
break;
}
default: {
// Cheking if node was already visited
if (visited[currentIndex] == true)
{
// Marking all node as non visited
visitedInitilise(visited);
impossible = true;
break;
}
else
{
// when the node was not visited before , catch the jump
// value
int jumpValue = Integer.parseInt(plateau[currentIndex]);
// cheking that the next node is not bigger than node
// number and not negativ
if (((currentIndex + jumpValue) > plateau.length) || (currentIndex < 0))
{
impossible = true;
break;
}
else
{
// Marking node as visited
visited[currentIndex] = true;
// calculating minimum number of move starting from
// this node
getMinimumNumberOfMoves(plateau, visited, currentIndex + jumpValue,
currentNumberOfMoves + 1, list);
break;
}
}
}
}
}
catch (NumberFormatException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
if (impossible == true)
currentNumberOfMoves = 0;
return list;
}
static void visitedInitilise(boolean visited[]) {
for (int i = 0; i <= (visited.length - 1); i++)
visited[i] = false;
}
public static void main(String args[]){
String testCaseID = "15"; // Write a test file number from 1 to 15, or
// ALL
TestCases.test(testCaseID);
}
}
I am making a robot maze where the robot reaches a target automatically without crashing into walls. I want the robot to do the maze once, learn the correct route and then the second time be able to get there straight away without going to any deadends. I thought I could do this by making three arraylists.
One for all the squares the robot visits.
Two for all the squares that lead to a deadend.
Three for all the directions the robot goes.
If the squares that lead to a dead end are found in the first arraylist then i can delete the same indexes in the third arraylist. That way, the second time, i can just iterate the third Arraylist.
My full code is below:
import java.util.ArrayList;
import java.util.*;
import java.util.Iterator;
import java.util.stream.IntStream;
public class Explorer {
private int pollRun = 0; // Incremented after each pass.
private RobotData robotData; // Data store for junctions.
private ArrayList<Integer> nonWallDirections;
private ArrayList<Integer> passageDirections;
private ArrayList<Integer> beenbeforeDirections;
private Random random = new Random();
int [] directions = {IRobot.AHEAD, IRobot.LEFT, IRobot.RIGHT, IRobot.BEHIND};
private ArrayList<Square> correctSquares;
private ArrayList<Square> wrongSquares;
private ArrayList<Integer> correctDirections;
public void controlRobot (IRobot robot) {
// On the first move of the first run of a new maze.
if ((robot.getRuns() == 0) && (pollRun ==0))
robotData = new RobotData();
pollRun++; /* Increment poll run so that the data is not reset
each time the robot moves. */
int exits = nonwallExits(robot);
int direction;
if ((robot.getRuns() != 0))
direction = grandfinale(robot);
nonWallDirections = new ArrayList<Integer>();
passageDirections = new ArrayList<Integer>();
beenbeforeDirections = new ArrayList<Integer>();
correctSquares = new ArrayList<Square>();
correctDirections = new ArrayList<Integer>();
// Adding each direction to the appropriate state ArrayList.
for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonWallDirections.add(item);
}
}
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageDirections.add(item);
}
}
for(int item : directions) {
if(robot.look(item) == IRobot.BEENBEFORE) {
beenbeforeDirections.add(item);
}
}
// Calling the appropriate method depending on the number of exits.
if (exits < 2) {
direction = deadEnd(robot);
} else if (exits == 2) {
direction = corridor(robot);
} else {
direction = junction(robot);
robotData.addJunction(robot);
robotData.printJunction(robot);
}
robot.face(direction);
addcorrectSquares(robot);
correctDirections.add(direction);
}
/* The specification advised to have to seperate controls: Explorer and Backtrack
and a variable explorerMode to switch between them.
Instead, whenever needed I shall call this backtrack method.
If at a junction, the robot will head back the junction as to when it first approached it.
When at a deadend or corridor, it will follow the beenbefore squares until it
reaches an unexplored path. */
public int backtrack (IRobot robot) {
if (nonwallExits(robot) > 2) {
addwrongSquares(robot);
return robotData.reverseHeading(robot);
} else {
do {
addwrongSquares(robot);
return nonWallDirections.get(0);
} while (nonwallExits(robot) == 1);
}
}
// Deadend method makes the robot follow the only nonwall exit.
public int deadEnd (IRobot robot) {
return backtrack(robot);
}
/* Corridor method will make the robot follow the one and only passage.
The exception is at the start. Sometimes, the robot will start with
two passages available to it in which case it will choose one randomly.
If there is no passage, it will follow the beenbefore squares
until it reaches an unexplored path.*/
public int corridor (IRobot robot) {
if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) == 2) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}
}
/* Junction method states if there is more than one passage, it will randomly select one.
This applies to crossroads as well as essentially they are the same.
If there is no passage, it will follow the beenbefore squares until it reaches an unexplored
path. */
public int junction(IRobot robot) {
if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) > 1) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}
}
// Calculates number of exits.
private int nonwallExits (IRobot robot) {
int nonwallExits = 0;
for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonwallExits++;
}
}
return nonwallExits;
}
// Calculates number of passages.
private int passageExits (IRobot robot) {
int passageExits = 0;
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageExits++;
}
}
return passageExits;
}
// Calculates number of beenbefores.
private int beenbeforeExits (IRobot robot) {
int beenbeforeExits = 0;
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
beenbeforeExits++;
}
}
return beenbeforeExits;
}
// Resets Junction Counter in RobotData class.
public int reset() {
return robotData.resetJunctionCounter();
}
public void addcorrectSquares(IRobot robot) {
Square newSquare = new Square(robot.getLocation().x, robot.getLocation().y);
correctSquares.add(newSquare);
}
public void addwrongSquares(IRobot robot) {
Square badSquare = new Square(robot.getLocation().x, robot.getLocation().y);
wrongSquares.add(badSquare);
}
public int grandfinale (IRobot robot) {
IntStream.range(0, correctSquares.size())
.map(index -> correctSquares.size() - index - 1)
.filter(index -> (((wrongSquares.x).contains(correctSquares.x)) && ((wrongSquares.y).contains(correctSquares.y))).get(index))
.forEach(index -> correctDirections.remove(index));
Iterator<Integer> routeIterator = correctDirections.iterator();
while (routeIterator.hasNext()) {
break;
}
return (routeIterator.next());
}
}
class RobotData {
/* It was advised in the specification to include the variable:
private static int maxJunctions = 10000;
However, as I am not using arrays, but ArrayLists, I do not
need this. */
private static int junctionCounter = 0;
private ArrayList<Junction> junctionList = new ArrayList<Junction>();
// Resets the Junction counter.
public int resetJunctionCounter() {
return junctionCounter = 0;
}
// Adds the current junction to the list of arrays.
public void addJunction(IRobot robot) {
Junction newJunction = new Junction(robot.getLocation().x, robot.getLocation().y, robot.getHeading());
junctionList.add(newJunction);
junctionCounter++;
}
// Gets the junction counter for Junction info method in Junction class.
public int getJunctionCounter (IRobot robot) {
return junctionCounter;
}
// Prints Junction info.
public void printJunction(IRobot robot) {
String course = "";
switch (robot.getHeading()) {
case IRobot.NORTH:
course = "NORTH";
break;
case IRobot.EAST:
course = "EAST";
break;
case IRobot.SOUTH:
course = "SOUTH";
break;
case IRobot.WEST:
course = "WEST";
break;
}
System.out.println("Junction " + junctionCounter + " (x=" + robot.getLocation().x + ", y=" + robot.getLocation().y +") heading " + course);
}
/* Iterates through the junction arrayList to find the
heading of the robot when it first approached the junction.
It does this by finding the first junction in the ArrayList
that has the same x and y coordinates as the robot.*/
public int searchJunction(IRobot robot) {
Junction currentJunction = null;
Iterator<Junction> junctionIterator = junctionList.iterator();
while (junctionIterator.hasNext()) {
currentJunction = junctionIterator.next();
if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
break;
}
return currentJunction.arrived;
}
// Returns the reverse of the heading the robot had when first approaching the junction.
public int reverseHeading(IRobot robot) {
int firstHeading = searchJunction(robot);
int reverseHeading = 1; // Random integer to Iniitalise variable.
switch (firstHeading) {
case IRobot.NORTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.AHEAD;
else
reverseHeading = IRobot.LEFT;
break;
case IRobot.EAST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.RIGHT;
else
reverseHeading = IRobot.AHEAD;
break;
case IRobot.SOUTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.BEHIND;
else
reverseHeading = IRobot.RIGHT;
break;
case IRobot.WEST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.LEFT;
else
reverseHeading = IRobot.BEHIND;
break;
}
return reverseHeading;
}
}
class Junction {
int x;
int y;
int arrived;
public Junction(int xcoord, int ycoord, int course) {
x = xcoord;
y = ycoord;
arrived = course;
}
}
class Square {
int x;
int y;
public Square(int cordx, int cordy){
x = cordx;
y = cordy;
}
}
IntStream.range(0, al1.length)
.filter(index -> al2.contains(al1.get(index)))
.forEach(index -> al3.remove(index));
Slightly more complex than this if removing elements from al3 shifts them left but in that case just reverse the stream before the .filter- then it will delete from the end. The easiest way to do that is:
.map(index -> al1.length - index - 1)
Without Streams the equivalent would be
for (int i = 0; i < al1.length; i++) {
if (al2.contains(al1.get(i))) {
al3.remove(i);
}
}
Similarly, if you need to delete from the right then the for loop would need to count down rather than up.
Without further details on arraylist structure it's hard to give any more hints.
I have a .txt file with following format data(co-ordinates)
0 1 12.56
2 0 -56.2
1 2 78.2
0 -56.2 2
-2 8 0
I imported this data into using the following code.
public ArrayList<Point3d> loadFile(String filename) {
ArrayList<Point3d> words = new ArrayList<Point3d>();
try {
Scanner chopper = new Scanner(new File(filename));
while (chopper.hasNext()) {
double x=chopper.nextDouble();
double y=chopper.nextDouble();
double z=chopper.nextDouble();
Point3d p=new Point3d(x, y, z);
words.add(p);
// just calling nextLine will cause an exception at the end of the file unless you have an blank line there on purpose, so this makes sure it does
}
chopper.close();
} catch (Exception e) {
System.out.println(e);
}
return words;
}
importing is working fine.Know I want to separate negative, positive coordinates also I want to append their corresponding index values.
Finally I want result in the following way.
Result :
positiveList= {{0,0,1,12.56},{2,1,2,78.2}}
negativeList={{1,2,0,-56.2},{3,0,-56.2,2},{4,-2,8,0}}
How can I do this.
My solution here uses the Map data structure, but you can create 2 Lists of Lists if you wish.
Outside the while loop add:
Map<Integer, Point3D> negativeCoord = new HashMap<>();
Map<Integer, Point3D> positivetiveCoord = new HashMap<>();
int currentIndex = 0;
and inside it:
Point3d p = new Point3d(x, y, z);
if(x < 0 || y < 0 || z < 0) {
negativeCoord.put(currentIndex, p);
} else {
positiveCoord.put(currentIndex, p);
}
currentIndex++;
You could do this after loading the file, like so:
Map<Integer, Point3d> positiveList = new java.util.HashMap<Integer, Point3d>();
Map<Integer, Point3d> negativeList = new java.util.HashMap<Integer, Point3d>();
for (int i = 0; i < words.size(); i++) {
Point3d p = words.get(i);
if (p.x < 0 || p.y < 0 || p.z < 0) {
negativeList.put(i + 1, p);
} else {
positiveList.put(i + 1, p);
}
}
or integrate the above in your while-loop, what saves you from iterating over all the words twice.
This would be the solution to just have the positives and negatives, without knowing their order.
public ArrayList<Point3D> getPositives(ArrayList<Point3D> points) {
ArrayList<Point3D> positives = new ArrayList<>();
for(Point3D next : points) {
if(next.getX() >= 0 && next.getY() >= 0 && next.getZ() >= 0)
posivites.add(next);
}
return positives.
}
public ArrayList<Point3D> getNegatives(ArrayList<Point3D> points) {
ArrayList<Point3D> negatives = new ArrayList<>();
for(Point3D next : points) {
if(next.getX() < 0 || next.getY() < 0 || next.getZ() < 0)
negatives.add(next);
}
return negatives.
}
Depending on your scenario it could be wise to have an own container class for the information.
public class PointContainer {
public final Point3D point;
public final int order;
public PointCoordinates (Point3D p, int order) {
this.point = p;
this.order = order;
}
public boolean isNegative() {
return point.getX() < 0 || point.getY() < 0 || point.getZ() < 0;
}
}
and then populate your list with it.
public ArrayList<Point3d> loadFile(String filename) {
ArrayList<PointContainer> words = new ArrayList<PointContainer>();
try {
Scanner chopper = new Scanner(new File(filename));
for (int line = 0; chopper.hasNext(); line ++) {
double x=chopper.nextDouble();
double y=chopper.nextDouble();
double z=chopper.nextDouble();
Point3d p=new Point3d(x, y, z);
PointCoordinates pc = new PointCoordinates(p, line);
words.add(pc);
// just calling nextLine will cause an exception at the end of the file unless you have an blank line there on purpose, so this makes sure it does
}
chopper.close();
} catch (Exception e) {
System.out.println(e);
}
return words;
}
That way you have that information ready to use for everything you want to do.