I have implemented AdjacencyMatrix in java, but I am having hard time implementing the distance() method to be able to find the distance between two nodes.
Any idea how I an do that?
I have tried a lot of things but I don't seem to be able to get right answer.
Here's my implementation
public class AdjacencyMatrix implements Representation {
private Node[] nodes;
private int[][] adjacencyMatrix;
private int numberOfNodes =0;
public AdjacencyMatrix(File file) {
Scanner inFile;
int numNodes;
try {
inFile = new Scanner(file);
numNodes = Integer.parseInt(inFile.nextLine());
adjacencyMatrix = new int[20][20];
nodes = new Node[20];
String[] line;
while (inFile.hasNextLine()) {
line = inFile.nextLine().split(":");
Node from = new Node(Integer.parseInt(line[0]));
Node to = new Node(Integer.parseInt(line[1]));
int value = Integer.parseInt(line[2]);
if(!Arrays.asList(nodes).contains(from))
addNode(from);
if(!Arrays.asList(nodes).contains(to))
addNode(to);
addEdge(new Edge(from, to, value));
}
} catch (FileNotFoundException e) {
System.out.print(e.getCause());
}
}
public AdjacencyMatrix() {
}
#Override
public boolean adjacent(Node x, Node y) {
int fromIndex = findIndex(x);
int toIndex = findIndex(y);
if(adjacencyMatrix[fromIndex][toIndex] == 1 || adjacencyMatrix[toIndex][fromIndex] ==1){
return true;
}
return false;
}
#Override
public List<Node> neighbors(Node x) {
ArrayList<Node> neighbors = new ArrayList<>();
int fromIndex = findIndex(x);
if(x.getData().toString().equals("4")) {
System.out.println("FromIndex is: " + fromIndex);
}
if(x.getData().toString().equals("4")){
for(int i =0; i < nodes.length; ++i){
System.out.println(nodes[i] + " ");
}
}
for (int i = 0; i <= numberOfNodes; i++){
if(adjacencyMatrix[fromIndex][i] == 1){
neighbors.add(nodes[i]);
if(x.getData().toString().equals("4")) {
System.out.println("Match!: " + i);
System.out.println("Adding NODE: " + nodes[i]);
}
}
}
int [] nums = new int[neighbors.size()];
for(int i =0; i < nums.length; ++i){
nums[i] = Integer.parseInt(neighbors.get(i).getData().toString());
}
Arrays.sort(nums);
ArrayList<Node> newNeighbors = new ArrayList<>();
for(int i =0; i < nums.length; ++i){
newNeighbors.add(new Node(nums[i]));
}
return newNeighbors;
}
#Override
public boolean addNode(Node x) {
if(Arrays.asList(nodes).contains(x)){
return false;
}
nodes[numberOfNodes] = x;
for (int i = 0; i <= numberOfNodes; i++){
adjacencyMatrix[numberOfNodes][i] = 0;
adjacencyMatrix[i][numberOfNodes] = 0;
}
numberOfNodes++;
return true;
}
#Override
public boolean removeNode(Node x) {
if (!Arrays.asList(nodes).contains(x)) {
return false;
}
for (int k = 0; k < numberOfNodes; k++) {
if (x.equals(nodes[k])) {
//decrement the number of nodes
numberOfNodes--;
for (int i = k; i < numberOfNodes; i++) {
nodes[i] = nodes[i + 1];
}
for (int i = k; i < numberOfNodes; i++) {
for (int j = 0; j <= numberOfNodes; j++) {
adjacencyMatrix[i][j] = adjacencyMatrix[i + 1][j];
}
}
for (int i = k; i < numberOfNodes; i++) {
for (int j = 0; j < numberOfNodes; j++) {
adjacencyMatrix[j][i] = adjacencyMatrix[j][i + 1];
}
}
}
//
}
return true;
}
#Override
public boolean addEdge(Edge x){
int from = Integer.parseInt(x.getFrom().getData().toString());
int to = Integer.parseInt(x.getTo().getData().toString());
int fromIndex = findIndex(x.getFrom());
int toIndex = findIndex(x.getTo());
if(from == 4){
System.out.println("Adding adjecent to 4 -> " + to);
}
if(adjacencyMatrix[fromIndex][toIndex] == 1 ){
return false;
}
adjacencyMatrix[fromIndex][toIndex] = 1;
return true;
}
#Override
public boolean removeEdge(Edge x) {
int from = Integer.parseInt(x.getFrom().getData().toString());
int to = Integer.parseInt(x.getTo().getData().toString());
int fromIndex = findIndex(x.getFrom());
int toIndex = findIndex(x.getTo());
if(adjacencyMatrix[fromIndex][toIndex] == 0 && adjacencyMatrix[toIndex][fromIndex] ==0){
return false;
}
adjacencyMatrix[fromIndex][toIndex] = 0;
return true;
}
#Override
public int distance(Node from, Node to) {
return 0;
}
#Override
public Optional<Node> getNode(int index) {
return null;
}
#Override
public Collection<Node> getNodes() {
return Arrays.asList(nodes);
}
public int findIndex(Node node)
{
for (int i = 0; i < numberOfNodes; ++i)
if (nodes[i].equals(node))
return i;
return -1;
}}
All my methods are working except distance().
I am returning 0 in the distance() method since I don't know how to implement it correctly.
Any help would be greatly appreciated.
I figured it out.
Basically I made an array to keep track of my Edges:
private Edge [] edges;
Then I populated the array with my graph edges.
Now, in my distance method I just find the edge with the give To and From Nodes, and extract it's value which is the distance I'm looking for :)
public int distance(Node from, Node to) {
for(Edge edge: edges){
if(edge.getFrom().equals(from) && edge.getTo().equals(to)){
return edge.getValue();
}
}
return 1;
}
I must have thought about this simple solution earlier!
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 days ago.
Improve this question
I'm trying to implement the A* algorithm in Java in order to solve the 15-Puzzle, but I get an infinite loop and I don't understand why.
I tried with the removal of the openList.clear(); statement, but in this way I get another problem: the tiles begin to do some erroneous movements.
Here is the code of the Board:
public class BoardPrototype implements Prototype, Cloneable {
public Box[][] board;
public int manhattanDistance = 0;
public int g_n = 0;
public final List<Integer> finalList = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0);
#Override
public Object clone() {
try {
BoardPrototype cloned = (BoardPrototype) super.clone();
cloned.board = new Box[board.length][board[0].length];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
cloned.board[i][j] = new BoxBuilder()
.setX(board[i][j].getX())
.setY(board[i][j].getY())
.setValue(board[i][j].getValue())
.setG_n(board[i][j].getG_n())
.setInitialX(board[i][j].getInitialX())
.setInitialY(board[i][j].getInitialY())
.setManhattanDistance(board[i][j].getManhattanDistance())
.build();
}
}
return cloned;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public boolean equals(Object o) {
if (o instanceof BoardPrototype that) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (board[i][j].getValue() != that.board[i][j].getValue())
return false;
}
}
return true;
} else {
return false;
}
}
#Override
public int hashCode() {
int result = Arrays.hashCode(board[0]);
for (int i = 1; i < board.length; i++) {
result = 31 * result + Arrays.hashCode(board[i]);
}
return result;
}
public void setBoard(Box[][] board) {
this.board = board;
}
public void setManhattanDistance(int manhattanDistance) {
this.manhattanDistance = manhattanDistance;
}
public int getManhattanDistance() {
manhattanDistance = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
manhattanDistance += board[i][j].getManhattanDistance();
}
}
return manhattanDistance;
}
public void setG_n(int g_n) {
this.g_n = g_n;
}
public int getG_n() {
return this.g_n;
}
public BoardPrototype swap(int index1, int index2) {
BoardPrototype copy = (BoardPrototype) this.clone();
int row1 = index1 / 4;
int col1 = index1 % 4;
int row2 = index2 / 4;
int col2 = index2 % 4;
copy.board[row1][col1].setManhattanDistance(copy.board[row1][col1].getManhattan(index2, copy.board[row1][col1].getValue()));
copy.board[row2][col2].setManhattanDistance(copy.board[row2][col2].getManhattan(index1, copy.board[row2][col2].getValue()));
copy.board[row1][col1].setValue(copy.board[row2][col2].getValue());
copy.board[row2][col2].setValue(0);
copy.board[row1][col1].setInitialX(copy.board[row2][col2].getInitialX());
copy.board[row2][col2].setInitialX(copy.board[row1][col1].getInitialX());
copy.board[row1][col1].setInitialY(copy.board[row2][col2].getInitialY());
copy.board[row2][col2].setInitialY(copy.board[row1][col1].getInitialY());
copy.board[row1][col1].setG_n(copy.board[row2][col2].getG_n() + 1);
copy.board[row2][col2].setG_n(copy.board[row1][col1].getG_n() + 1);
copy.board[row1][col1].update();
copy.board[row2][col2].update();
return copy;
}
public List<BoardPrototype> neighbors(BoardPrototype board) {
ArrayList<BoardPrototype> neighbors = new ArrayList<>();
int blankIndex = board.getBlankIndex();
int row = blankIndex / 4;
int col = blankIndex % 4;
if (row > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col > 0) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex - 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (row < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 4);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
if (col < 3) {
BoardPrototype cloned = (BoardPrototype) board.clone();
cloned = cloned.swap(blankIndex, blankIndex + 1);
cloned.setManhattanDistance(cloned.getManhattanDistance());
neighbors.add(cloned);
}
return neighbors;
}
public int getBlankIndex() {
int index = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(this.board[i][j].getValue() == 0) {
index = i * 4 + j;
}
}
}
return index;
}
public boolean isSolved() {
int count = 0;
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(board[i][j].getValue() == finalList.get(count)) {
count++;
if (count == 16) {
return true;
}
} else {
return false;
}
}
}
return false;
}
}
And this one is the code of the class that implements the A* algorithm:
public class Game15Solver {
private static Game15Solver game15Solver;
ManhattanComparator manhattanComparator = new ManhattanComparator();
private Game15Solver() {}
public static Game15Solver getInstance() {
if(game15Solver == null) {
game15Solver = new Game15Solver();
}
return game15Solver;
}
public List<BoardPrototype> AStar(BoardPrototype board) {
PriorityQueue<BoardPrototype> openList = new PriorityQueue<>(manhattanComparator);
List<BoardPrototype> closeList = new ArrayList<>();
openList.add(board);
while (!openList.isEmpty()) {
BoardPrototype current = openList.poll();
closeList.add(current);
openList.clear();
if (current.isSolved()) {
System.out.println("Solved");
} else {
for (BoardPrototype neighbor : current.neighbors(current)) {
if (!closeList.contains(neighbor)) {
if(!openList.contains(neighbor)) {
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
} else {
var tmpList = (Arrays.asList(openList.toArray()));
int ind = tmpList.indexOf(neighbor);
BoardPrototype boardPrototype = (BoardPrototype) tmpList.get(ind);
if(neighbor.getG_n() + 1 < boardPrototype.getG_n()) {
openList.remove(neighbor);
neighbor.setG_n(current.getG_n() + 1);
openList.add(neighbor);
}
}
}
}
}
}
return closeList;
}
}
Do you know how can I solve this problem? Thank you.
Im attempting to find the shortest path to all the nodes of a graph using the floyd warshall algorithm for a class. I was given the base code for the graph, and have tried implementing the algorithm through pseudocode, but havent figured out how to pick the specific edge based on the iteration im in.
Here is the code for the algorithm. the part that im trying to change is "initialize with adjacency matrix weight values" im not sure how to select that specific edge weight.
public static void FloydWarshall(Graph g) {
int V = g.getvCount();
// to store the calculated distances
float dist[][] = new float[V][V];
// initialize with adjacency matrix weight values
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
for(int k = 0; k<=g.edgeList.size(); k++){
if(g.edgeList.get(i).head.equals(i) && g.edgeList.get(j).tail.equals(j)){
int label = Integer.parseInt(g.edgeList.get(k).label);
dist[i][j] = label;
}}
}
}
// loop through all vertices one by one
for (int k = 0; k < V; k++) {
// pick all as source
for (int i = 0; i < V; i++) {
// pick all as destination
for (int j = 0; j < V; j++) {
// If k is on the shortest path from i to j
if (dist[i][k] + dist[k][j] < dist[i][j]) {
// update the value of dist[i][j]
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
// shortest path matrix
for (int z = 0; z < V; z++) {
for (int j = 0; j < V; j++) {
// if value is infinity
if (dist[z][j] == Float.MAX_VALUE)
System.out.print("INF ");
else
System.out.print(dist[z][j] + " ");
}
System.out.println();
}
And here is the code for the edge
public class Edge implements Comparable<Edge> {
String label;
Node tail;
Node head;
public Edge(Node tailNode, Node headNode, String theLabel) {
setLabel(theLabel);
setTail(tailNode);
setHead(headNode);
}
public String getLabel() {
return label;
}
public Node getTail() {
return tail;
}
public Node getHead() {
return head;
}
public void setLabel(String s) {
label = s;
}
public void setTail(Node n) {
tail = n;
}
public void setHead(Node n) {
head = n;
}
#Override
public int compareTo(Edge edge) {
try {
int edge1 = Integer.parseInt(edge.label);
int edge2 = Integer.parseInt(edge.label);
return Integer.compare(edge1, edge2);
} catch (NumberFormatException e) {
System.out.println(e);
}
return 0;
}
}
Additionally here is the code for the graph class that i have.
import java.util.*;
public class Graph {
ArrayList<Node> nodeList;
ArrayList<Edge> edgeList;
public Graph() {
nodeList = new ArrayList<Node>();
edgeList = new ArrayList<Edge>();
}
public ArrayList<Node> getNodeList() {
return nodeList;
}
public ArrayList<Edge> getEdgeList() {
return edgeList;
}
public void addNode(Node n) {
nodeList.add(n);
}
public void addEdge(Edge e) {
edgeList.add(e);
}
public String toString() {
String s = "Graph g.\n";
if (nodeList.size() > 0) {
for (Node n : nodeList) {
// Print node info
String t = "\nNode " + n.getName() + ", abbrev " + n.getAbbrev() + ", value " + n.getVal() + "\n";
s = s.concat(t);
}
s = s.concat("\n");
}
return s;
}
public void sortNodes(){
Collections.sort(nodeList);
}
private int vCount;
private float[][] adj;
public int getvCount() {
return vCount;
}
public float[][] getAdj() {
return adj;
}
public Graph(int vCount) {
this.vCount = vCount;
adj = new float[vCount][vCount];
for (int i = 0; i < vCount; i++) {
for (int j = 0; j < vCount; j++) {
if (i != j) {
adj[i][j] = Float.MAX_VALUE;
}
}
}
}
public void addEdge(int i, int j, float weight) {
adj[i][j] = weight;
}
public void removeEdge(int i, int j) {
adj[i][j] = Float.MAX_VALUE;
}
public boolean hasEdge(int i, int j) {
if (adj[i][j] != Float.MAX_VALUE && adj[i][j] != 0) {
return true;
}
return false;
}
public List<Integer> neighbours(int vertex) {
List<Integer> edges = new ArrayList<Integer>();
for (int i = 0; i < vCount; i++)
if (hasEdge(vertex, i))
edges.add(i);
return edges;
}
}
You can initialize all cells to be infinity, and then for each cell [i][j] where there is an edge from vertex i to vertex j, set its distance to be the edge weight. You could do this by iterating through all edges afterwards.
// initialize with adjacency matrix weight values
// set all to be initially infinity
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
dist[i][j] = Float.MAX_VALUE;
}
}
// set all edge weights
for(int k = 0; k <= g.edgeList.size(); k++){
Edge e = g.edgeList.get(k);
int i = Integer.parseInt(e.getHead().label);
int j = Integer.parseInt(e.getTail().label);
dist[i][j] = Integer.parseInt(e.getLabel());
}
I want to check if the sum of each row in any matrix is equal. How should I rewrite this to avoid NPE?
I can make it work for "normal" matrices like int[][] a = {{1,2,3}, {4,5,6}}, but I want it to work even when testing with null and empty matrices.
public static boolean allRowSumsEqual(int[][] m) {
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
As you said, this does work for most matrices. There are a few places I might check for null, see modified code below:
public static boolean allRowSumsEqual(int[][] m){
if(m == null) return true;
if(m.length == 0) return true;
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 1; i < m.length; i++){
// You can use your own function instead of the inner for loop
x = rowSum(m[i]);
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v){
int vSum = 0;
// Assume a null row has sum 0
if(v == null) return 0;
for (int i = 0 ; i < v.length ; i++){
vSum += v[i];
}
return vSum;
}
You need to define a result or an exception if you want to check for "null" parameter. You can return true if null is valid or false otherwise.
if(m == null) return true;
Empty or one lined matrices can return true all the time and does not require any calculation:
if(m.length < 2) return true;
The line test is more simple, I think:
// expect a positiv result
boolean result = true;
// calculate first line
int firstLine = rowSum(m[0]);
// loop remaining lines
for (int i = 1 ; i < m.length ; i++){
// compare first line with current line
if (firstLine != rowSum(m[i]))
{
// not equal -> change result
result = false;
// break loop
break;
}
}
return result;
public class Snippet {
public static boolean allRowSumsEqual(int[][] m) {
if (null == m || 0 == m.length)
return true;
boolean a = false;
int x = 0;
int total = 0;
if (null != m[0])
total = rowSum(m[0]);
for (int i = 1; i < m.length; i++) {
if (null != m[i]) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
} else
x = 0;
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
public static void main(String[] args) {
int[][] a = { { 1, 2, 3 }, { 3, 2, 1 }, null };
System.out.println(allRowSumsEqual(a));
int[][] b = { null, null, null };
System.out.println(allRowSumsEqual(b));
}
}
What do you think of this solution:
public static boolean allRowSumsEqual(int[][] m) {
if(m == null) { return false; }
int sum = 0;
for(int i = 0; i < m.length; i++) {
int temp = 0;
if(m[i] == null) { continue; }
for(int j = 0; j < m[i].length; j++) {
temp += m[i][j];
}
if(i == 0) { //is the first row
sum = temp;
}
else if(sum != temp) {
return false;
}
}
return true;
}
Well I have a program which handles a set of circles represented by an array. It's by default is of size of 10, but if more than 10 items are added, it extends the array by 10 more spaces. I looked for a solution to reduce the length of the set in case the number of items in it drops blow 10. I keep getting a
Exception in thread "main" java.lang.ArrayStoreException: oop.Circle
at oop.ObjectSet.reduce(ObjectSet.java:94)
at oop.ObjectSet.removeObject(ObjectSet.java:39)
at oop.CircleSet.removeObject(CircleSet.java:17)
at oop.Test.main(Test.java:60)
This is the source:
package oop;
public class ObjectSet {
protected Object[] objectSet;
protected int size;
public ObjectSet() {
objectSet = new Object[10];
size = 0;
}
public int numberOfItems() {
return size;
}
public boolean addObject(Object object) {
if (object != null) {
if (size == 0)
objectSet[size] = object;
if (size == objectSet.length)
extend();
if (contains(object) == -1) {
objectSet[size] = object;
size++;
return true;
}
}
return false;
}
public boolean removeObject(Object object) {
if (object != null && size > 0) {
int index = contains(object);
if(size == this.objectSet.length - 10)
reduce();
for (int i = index; i < size; i++) {
objectSet[i] = objectSet[i + 1];
}
objectSet[size - 1] = null;
size--;
return true;
}
return false;
}
public int contains(Object object) {
if (object != null && size > 0) {
for (int i = 0; i < size; i++) {
if (objectSet[i].equals(object))
return i;
}
}
return -1;
}
public void printSet(){
if(size > 0){
for (int i = 0; i < size; i++) {
System.out.println();
}
}
}
private void extend() {
Object[] temp = new Object[size];
for (int i = 0; i < size; i++) {
temp[i] = this.objectSet[i];
}
this.objectSet = new Object[size + 10];
for (int i = 0; i < size; i++) {
this.objectSet[i] = temp[i];
}
}
private void reduce(){
int newSize = this.objectSet.length - 10;
Object[] temp = new Object[newSize];
for (int i = 0; i < size; i++) {
temp[i] = this.objectSet[i];
}
this.objectSet = new ObjectSet[newSize];
for (int i = 0; i < size; i++) {
this.objectSet[i] = temp[i];
}
}
}
Sometimes you initialize the array as
this.objectSet = new Object[size + 10];
while other times you initialize it as
this.objectSet = new ObjectSet[newSize];
This is probably the cause of the exception.
I'm assuming you meant the latter to be :
this.objectSet = new Object[newSize];
You are trying to store Object instances in an array of ObjectSet. This line:
this.objectSet = new ObjectSet[newSize];
Should be
this.objectSet = new Object[newSize];
As it is in the extend method.
Note that you also need to change the subsequent loop termination condition to i < newSize.
public class Sudoku {
public static void main(String[] args) {
// Row and column Latin but with invalid subsquares
String config1 = "1234567892345678913456789124567891235678912346" + "78912345789123456891234567912345678";
String[][] puzzle1 = makeSudoku(config1);
if (isValidSudoku(puzzle1)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle1));
System.out.println("--------------------------------------------------");
// Row Latin but column not Latin and with invalid subsquares
String config2 = "12345678912345678912345678912345678912345678" + "9123456789123456789123456789123456789";
String[][] puzzle2 = makeSudoku(config2);
if (isValidSudoku(puzzle2)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle2));
System.out.println("--------------------------------------------------");
// A valid sudoku
String config3 = "25813764914698532779324685147286319558149273663" + "9571482315728964824619573967354218";
String[][] puzzle3 = makeSudoku(config3);
if (isValidSudoku(puzzle3)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle3));
System.out.println("--------------------------------------------------");
}
public static String[][] makeSudoku(String s) {
int SIZE = 9;
int k = 0;
String[][] x = new String[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x[i][j] = s.substring(k, k + 1);
k++;
}
}
return x;
}
public static String getPrintableSudoku(String[][] x) {
int SIZE = 9;
String temp = "";
for (int i = 0; i < SIZE; i++) {
if ((i == 3) || (i == 6)) {
temp = temp + "=================\n";
}
for (int j = 0; j < SIZE; j++) {
if ((j == 3) || (j == 6)) {
temp = temp + " || ";
}
temp = temp + x[i][j];
}
temp = temp + "\n";
}
return temp;
}
//sudoku validation
public static boolean isValidSudoku(String[][] x) {
return rowsAreLatin(x) && colsAreLatin(x) && goodSubsquares(x);
}
public static boolean rowsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume rows are latin
for (int i = 0; i < 9; i++) {
result = result && rowIsLatin(x, i); // Make sure each row is latin
}
return result;
}
public static boolean rowIsLatin(String[][] x, int i) {
boolean[] found = new boolean[9];
for (int j = 0; j < 9; j++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int j = 0; j < 9; j++) {
if (!found[j]) {
return false;
}
}
return true;
}
public static boolean colsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume cols are latin
for (int j = 0; j < 9; j++) {
result = result && colIsLatin(x, j); // Make sure each row is latin
}
return result;
}
public static boolean colIsLatin(String[][] x, int j) {
// fill in your code here
boolean[] found = new boolean[9];
for (int i = 0; i < 9; i++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int i = 0; i < 9; i++) {
if (!found[i]) {
return false;
}
}
return true;
}
public static boolean goodSubsquares(String[][] x) {
return true;
}
public static boolean goodSubsquare(String[][] x, int i, int j) {
boolean[] found = new boolean[9];
// We have a 3 x 3 arrangement of subsquares
// Multiplying each subscript by 3 converts to the original array subscripts
for (int p = i * 3, rowEnd = p + 3; p < rowEnd; p++) {
for (int q = j * 3, colEnd = q + 3; q < colEnd; q++) {
found[Integer.parseInt(x[p][q])] = true;
}
}
for (int p = 0; p < 9; p++) {
if (!found[p]) {
return false;
}
}
return true;
}
}
This the error I am getting. Help!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Sudoku.rowIsLatin(Sudoku.java:104)
at Sudoku.rowsAreLatin(Sudoku.java:93)
at Sudoku.isValidSudoku(Sudoku.java:85)
at Sudoku.main(Sudoku.java:8)
Java Result: 1
The problem is with the line:
Integer.parseInt(x[i][j])
Sudoku numbers range from [1, 9], but indices for an array (of length 9) range from [0, 8]. So, when the (i, j) element is a 9, the index is 9 and therefore the IndexOutOfBoundsException is being thrown.
You'll have to change it to
found[Integer.parseInt(x[i][j]) - 1] = true;
Note that you also make the same mistake in the column's respective method.