Related
I have little problem with removing col from a 2d array.
The goal is to remove from every row specific index "2" and give it back.
Its how it need to be
I made it but got little problem with 0 at the end.
Its how I got
private static void removeEntry(int[][] workArray, int col) {
int row = workArray.length;
//largest row count
int max = 0;
int tempNum = 0;
for (int[] ints : workArray) {
tempNum = 0;
for (int j = 0; j < ints.length; j++) {
tempNum++;
if (tempNum > max) {
max = tempNum;
}
}
}
int [][] newArray = new int[row][max];
for(int i = 0; i < row; i++) {
for(int j = 0; j < max; j++) {
if(j < col && j < workArray[i].length) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col && j < workArray[i].length) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
for (int i = 0; i < workArray.length; i++) {
for (int j = 0; j < workArray[i].length; j++) {
workArray[i][j] = newArray[i][j];
}
}
Then I tried to remove 0 but don't work
int remIndex = 0;
for (int i = 0; i < workArray.length; i++) {
for (int j = remIndex; j < workArray[i].length-1; j++) {
if(workArray[i][j] == remIndex){
workArray[i][j] = workArray[i][j + 1];
}
}
}
An array is a container of data that occupies a contiguous block of memory, its size should be defined when the array is being instantiated and can't be changed.
If you need an array of smaller or greater length, then you need to create a new one and copy all previously added elements that should be retained.
There's also no such thing in Java as "2D" arrays, we can create a nested array, i.e. an array containing other arrays.
And similarly to how we can reassign an integer value at a particular index in a plain array int[], we can change a reference in the array of arrays, i.e. we can make it point to another (newly created) array.
And that's what is required according to do in your assignment since the method is void. I.e. the given array needs to be changed by replacing all of its "rows", that greater or equal in length than the given column to remove col, with a new array that will retain all the previous element except for the one at index col.
private static void removeEntry(int[][] workArray, int col) {
for (int row = 0; row < workArray.length; row++) {
if (workArray[row].length <= col) { // no need to change anything
continue;
}
int newLength = workArray[row].length - 1;
int[] newRow = new int[newLength]; // creating a new row shorter by 1
for (int oldCol = 0, newCol = 0; oldCol < workArray[row].length; oldCol++, newCol++) {
if (oldCol == col) { // skipping the target column
newCol--; // newCol would be incremented automatically at the end of the iteration, but we want it to remain the same
continue;
}
newRow[newCol] = workArray[row][oldCol];
}
workArray[row] = newRow; // reassigning the row
}
}
main()
public static void main(String[] args) {
int[][] testArr =
{{1, 2},
{1, 2, 3},
{1, 2, 3, 4}};
removeEntry(testArr, 2);
// printing the testArr
for (int[] arr: testArr) {
System.out.println(Arrays.toString(arr));
}
}
Output:
[1, 2]
[1, 2]
[1, 2, 4]
A link to the Online Demo
If you've made the method to be void by mistake, you are required to return a new array, i.e. the return type int[] (check the requirements of your assignment carefully). Then a minor change needs to be applied to the logic explained and implemented above: every array should be replaced with a new one and then placed into the newly created resulting array.
Note Arrays.copyOf() allows creating a duplicate of the hole array, and System.arraycopy() can help you to copy the elements in the given range from one array into another, but because you are working on an assignment I suggest you to do it manually with loops because you are expected to demonstrate the knowledge on how to manipulate with arrays, not the knowledge of special utility features (unless otherwise specified in the assignment).
private static int[][] removeEntry(int[][] workArray, int col) {
int[][] result = new int[workArray.length][];
for (int row = 0; row < workArray.length; row++) {
int newLength = col < workArray[row].length ? workArray[row].length - 1 : workArray[row].length;
int[] newRow = new int[newLength];
for (int oldCol = 0, newCol = 0; oldCol < workArray[row].length; oldCol++, newCol++) {
if (oldCol == col) {
newCol--;
continue;
}
newRow[newCol] = workArray[row][oldCol];
}
result[row] = newRow; // reassigning the row
}
return result;
}
main()
public static void main(String[] args) {
int[][] testArr =
{{1, 2},
{1, 2, 3},
{1, 2, 3, 4}};
int[][] newArr = removeEntry(testArr, 2);
// printing the testArr
for (int[] arr: newArr) {
System.out.println(Arrays.toString(arr));
}
}
Output:
[1, 2]
[1, 2]
[1, 2, 4]
A link to the Online Demo
Here is my approach on this. I used System.arraycopy() to copy the array up to the removed column and from directly after the removed column to the end. This way, we remove the column completely from the array.
private static int[][] removeEntry(int[][] workArray, int col) {
int[][] resultArray = new int[workArray.length][];
int index = 0;
for (int[] row : workArray) {
if (row.length - 1 < col) {
resultArray[index] = row;
index++;
continue;
}
int[] arrayCopy = new int[row.length - 1];
System.arraycopy(row, 0, arrayCopy, 0, col);
System.arraycopy(row, col + 1, arrayCopy, col, row.length - col - 1);
resultArray[index] = arrayCopy;
index++;
}
return resultArray;
}
Arrays are of fixed size. At the time of initializing array, a default value is stored in it. Here, 0 is stored as default. So I would suggest you to not initialize "col" as "max" but rather do it in for loop like this :-
int [][] newArray = new int[row][];
for(int i = 0; i < row; i++) {
if(col <= workArray[i].length){
newArray[i] = new int[workArray[i].length-1]; //initialize it here
}
for(int j = 0; j < workArray[i].length; j++) {
if(j < col) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
return newArray;
You are also supposed to return modified array as we can't changed the size of array and thus we had to create a new one ( newArray ). So do change the method definition as :-
private static int[][] removeEntry(int[][] workArray, int col)
Finally, whole method would look like :-
private static int[][] removeEntry(int[][] workArray, int col) {
int row = workArray.length;
//largest row count
int [][] newArray = new int[row][];
for(int i = 0; i < row; i++) {
if(col <= workArray[i].length){
newArray[i] = new int[workArray[i].length-1]; //initialize it here
}
for(int j = 0; j < workArray[i].length; j++) {
if(j < col) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
return newArray;
}
and you can use it like :-
workArray = removeEntry(workArray, 2);
I want to check a whole Sudoku table if all the blocks got the 9 values or not but I was able to check only the first block and I need to check the other 8 blocks how?
public static boolean checkSubs(int[][] p) {
int[] nums = new int[9];
int x=0, temp;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++) {
temp = p[i][j];
for ( int m=0; m<nums.length; m++)
if ( nums[m]==temp ) return false;
nums[x++]=temp; }
return true; }
You can modify your checkSubsMethod.
Add i and j of the top left corner of sudoku subblock (e.g (0,0), (0,3),... (3,0), (3,3)... (6,3),(6,6)).
Use set to check does the value already used or not. The add() method of Set class return true if value doesn't in the set and false if value already added to the set.
And when you generalise your method you can use it for fields of any size. In your case size is 9x9, here is the example
public static boolean checkSubs(int[][] p, int topI, int topJ) {
Set<Integer> nums = new HashSet<>();
for (int i = topI; i < topI + 3; i++) {
for (int j = topJ; j < topJ + 3; j++) {
if (!nums.add(p[i][j])) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
int[][] sudoku = {
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9}};
for (int i = 0; i < sudoku.length;i += 3){
for (int j = 0; j<sudoku[0].length; j += 3){
if (!checkSubs(sudoku, i, j)){
System.out.println("DUPLICATED VALUES FOUND!");
return;
}
}
}
System.out.println("OK!!");
}
The output for this case will be OK!!
If you change the input like this
int[][] sudoku = {
{3,3,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9},
{1,2,3,1,2,3,1,2,3},
{4,5,6,4,5,6,4,5,6},
{7,8,9,7,8,9,7,8,9}};
The output will be DUPLICATED VALUES FOUND!
You can modify this example for your purposes in future.
I am having trouble to create a (recursive) function that prints all possible indexes for a multi dimensional table.
I got the information about the multi-dimensionality as an array.
Example:
int[]{6,6} would be a 2-dimensional table with 6x6 = 36 fields, so the result would be [0,0],[0,1],[1,1],[1,2],[2,2]... and so on.
Another example:
int[]{2,2,2} would be a 3-dimensional table with 8 possible indexes: [0,0,0],[0,0,1],[0,1,1]... and so on
I'm trying to do this in Java 7.
Edit: As requested, what I got so far. Code is producing OutOfBound Exception.
loop(new int[2], new int[]{6, 6}, 0);
private void loop(int[] index, int[] dimensionSizes, int dimensionIndex) {
if (index[dimensionIndex] < dimensionSizes[dimensionIndex] && dimensionIndex < dimensionSizes.length) {
System.out.println(Arrays.toString(index));
index[dimensionIndex] = index[dimensionIndex] + 1;
if (index[dimensionIndex] < dimensionSizes[dimensionIndex]) {
loop(index, dimensionSizes, dimensionIndex);
} else {
loop(index, dimensionSizes, dimensionIndex + 1);
}
}
}
I think this code could respond to your question:
public static void printAllIndex(int[] dimensions) {
int[] index = new int[dimensions.length];
int stepNumber = 0;
// Initialization
for (int i : index) { index[i] = 0; } // init index to 0
for (int d : dimensions) { stepNumber += d; } // count number of iteration needed
System.out.println(Arrays.toString(index)); // print first index [0,0,...]
for(int s = 0; s <= stepNumber - 1; s++) {
boolean allEquals = true;
int value = index[index.length - 1];
for (int i = index.length - 1; i >= 0; i--) {
if(index[i] != value) {
index[i]++;
allEquals = false;
break;
}
}
if (allEquals) { index[index.length - 1]++; }
System.out.println(Arrays.toString(index));
}
}
I am doing a game called 1010! Probably some of you have heard of it. Bascially I encouter some trouble when writing the Algorithm for clearance.
The rule is such that if any row or any column is occupied, then clear row and column respectively.
The scoring is such that each move gains a+10*b points. a is the number of square in the input piece p and b is the total number of row&column cleared.
To start, I create a two dimensional Array board[10][10], poulate each elements in the board[][] with an empty square.
In the class of Square, it has public void method of unset()-> "empty the square" & boolean status() -> "judge if square is empty"In the class of piece, it has int numofSquare -> "return the number of square in each piece for score calculation"
In particular, I don't know how to write it if both row and column are occupied as they are inter-cross each other in an two dimensional array.
It fail the test under some condition, in which some of the squares are not cleared but they should have been cleared and I am pretty sure is the logic problem.
My thinking is that:
Loop through squares in first row and first column, record the number of square that are occupied (using c and r); if both are 10, clear row&column, otherwise clear row or column or do nothing.
reset the c &r to 0, loop through square in the second row, second column…
update score.
Basically the hard part is that if I seperate clear column and clear row algorithm ,I will either judge row or column first then clear them . However, as every column contains at least one square belong to the row, and every row contains at least one square belong to the column, there will be mistake when both row and column are full.
Thanks for help.
import java.util.ArrayList;
public class GameState{
public static final int noOfSquares = 10;
// the extent of the board in both directions
public static final int noOfBoxes = 3;
// the number of boxes in the game
private Square[][] board; // the current state of the board
private Box[] boxes; // the current state of the boxes
private int score; // the current score
// initialise the instance variables for board
// all squares and all boxes are initially empty
public GameState()
{
getboard();
score = 0;
board = new Square[10][10];
for(int i =0;i<board.length;i++){
for(int j =0;j<board[i].length;j++){
board[i][j] = new Square();
}
}
boxes = new Box[3];
for(int k =0;k<boxes.length;k++){
boxes[k] = new Box();
}
}
// return the current state of the board
public Square[][] getBoard()
{
return board;
}
// return the current score
public int getScore()
{
return score;
}
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
for (int row=0;row<10;row++){
for (int column=0;column<10;column++) {
if (board[row][column].status() == true){
c = c + 1;
if( c == 10 ) {
rowandcolumn = rowandcolumn + 1;
for(int z=0;z<10;z++){
board[row][z].unset(); //Clear column
}
}
}
if (board[column][row].status() == true){
r = r + 1;
if( r == 10) {
rowandcolumn = rowandcolumn + 1;
for(int q=0;q<10;q++){
board[q][row].unset(); //Clear row
}
}
}
}
r=0; //reset
c=0;
}
score = score + p.numberofBox()+10*rowandcolumn;
}
how about this
void Background::liquidate(int &score){
int arr_flag[2][10]; //0 is row,1 is column。
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 10; j++)
{
arr_flag[i][j] = 1;
}
}
//column
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[i][j].type == 0)
{
arr_flag[0][i] = 0;
break;
}
}
}
//row
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[j][i].type == 0)
{
arr_flag[1][i] = 0;
break;
}
}
}
//clear column
for (int i = 0; i < 10; i++)
{
if (arr_flag[0][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[i][j].Clear();
}
}
}
//clear row
for (int i = 0; i < 10; i++)
{
if (arr_flag[1][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[j][i].Clear();
}
}
}
}
I tried to write somme code for the idea I posted
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
int row=FindFirstRow();
int column=FindFirstColumn();
if(row!=-1 && column!=-1)
{
rowandcolumn++;
//actions here: row found and column found
//clear row and column
clearRow(row);
clearColumn(column);
}
else if(row!=-1)
{
//only row is found
//clear row
clearRow(row);
}
else if(column!=-1)
{
//only column is found
//clear column
clearColumn(column);
}
else
{
//nothing is found
}
public void clearRow(int row)
{
for(int i=0; i<10;i++)
{
board[row][i].unset();
}
}
public void clearColumn(int column)
{
for(int i=0; i<10;i++)
{
board[i][column].unset();
}
}
//this method returns the first matching row index. If nothing is found it returns -1;
public int FindFirstRow()
{
for (int row=0;row<10;row++)
{
int r=0;
for (int column=0;column<10;column++)
{
if (board[row][column].status() == true)
{
r = r + 1;
if( r == 10)
{
//row found
return row;
}
}
}
r=0; //reset
}
//nothing found
return -1;
}
//this method returns the first matching column index. If nothing is found it returns -1;
public int FindFirstColumn()
{
for (int column=0;column<10;column++)
{
int c=0;
for (int row=0;row<10;row++)
{
if (board[row][column].status() == true)
{
c = c + 1;
if( c == 10 )
{
//matching column found
return column;
}
}
}
c=0; //reset
}
//nothing found
return -1;
}
I am trying to implement an iterative Sudoku solver. To avoid recursion I used a stack, but I'm having problems with its management. The starting board is represented by a String array (variable 'input' in the following code) in which each element is composed of 3 numbers: the [row, col] and its value (i.e, "006" means that the element in the 1st line and 1st col is 6) and is translated into an array of int by the constructor. When I run it, I cannot get a solution, so there are probably mistakes in the nested for cycles. Any help is appreciated.
import java.util.ArrayList;
public class SudokuSolver {
private int[][] matrix = new int[9][9];
private String[] input = { "006", "073", "102", "131", "149", "217",
"235", "303", "345", "361", "378", "422", "465", "514", "521",
"548", "582", "658", "679", "743", "752", "784", "818", "883" };
private ArrayList<int[][]> stack = new ArrayList<>();
public SudokuSolver() {
// Building the board based on input array
for (int n = 0; n < input.length; ++n) {
int i = Integer.parseInt(input[n].substring(0, 1));
int j = Integer.parseInt(input[n].substring(1, 2));
int val = Integer.parseInt(input[n].substring(2, 3));
matrix[i][j] = val;
}
stack.add(matrix);
}
private boolean isSolution(int[][] cells) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if(cells[i][j] == 0)
return false;
}
}
return true;
}
private boolean isValid(int i, int j, int val, int[][] cells) {
for (int k = 0; k < 9; k++)
if (val == cells[k][j])
return false;
for (int k = 0; k < 9; k++)
if (val == cells[i][k])
return false;
return true;
}
private boolean iterativeSudokuSolver() {
int[][] current = null;
while(stack.size() > 0 && !isSolution(stack.get(0))) {
current = stack.remove(0);
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (current[row][col] == 0) {
for (int val = 1; val <= 9; val++) {
if (isValid(row, col, val, current)) {
current[row][col] = val;
stack.add(0, current);
break;
}
}
}
}
}
}
if (current != null && isSolution(current))
return true;
else
return false;
}
public static void main(String [] args) {
SudokuSolver sudokuSolver = new SudokuSolver();
boolean result = sudokuSolver.iterativeSudokuSolver();
if (result)
System.out.println("Sudoku solved");
else
System.out.println("Sudoku not solved");
}
}
A stack implementation by adding and removing the 0-th element of an ArrayList is a very bad idea: it forces the whole content of the array to be shifted back an forth every time. Use LinkedList or modify the end of the list.
When you add and remove the same instance of the matrix back and forth to the stack, it is still the same matrix object, even though you may call it "current" or any other name. This means that when you change something in the matrix and then remove it from your stack, the change stays there (and in every other element of your stack, which are identical links to the same object). The logic of your solution looks like it needs to store the previous state of the solution on the stack, if so - allocate a new array every time and copy the data (also not very efficient, but try starting there).
A good question has to be specific. "Why this doesn't work?" is a bad question. Fix the obvious problems first, debug, and if puzzled provide more information about the state of your program (data in, data on step #1...N, for example)