I have a 9x9 sudoku grid and I need to get a random number from every 3x3 square in the grid.
The most awful code would be something like this:
if(square == 0) {
row = random.nextInt(3);
col = random.nextInt(3);
}
if(square == 1) {
row = random.nextInt(3);
col = random.nextInt(3) + 3;
}
if(square == 2) {
row = random.nextInt(3);
col = random.nextInt(3) + 6;
}
if(square == 3) {
row = random.nextInt(3) + 3;
col = random.nextInt(3);
}
if(square == 4) {
row = random.nextInt(3) + 3;
col = random.nextInt(3) + 3;
}
if(square == 5) {
row = random.nextInt(3) + 3;
col = random.nextInt(3) + 6;
}
if(square == 6) {
row = random.nextInt(3) + 6;
col = random.nextInt(3);
}
if(square == 7) {
row = random.nextInt(3) + 6;
col = random.nextInt(3) + 3;
}
if(square == 8) {
row = random.nextInt(3) + 6;
col = random.nextInt(3) + 6;
}
where square is the index of the square in the grid (square = 0,1,...,8)
I cannot figure out how to write it in a better way.
Some ideas? Thanks
This should work for any square size. In your case is 3x3, so size is 3.
int size = 3;
row = random.nextInt(size) + (square / size) * size;
col = random.nextInt(size) + (square % size) * size;
Something like this
int[] rowAdd = new int[] { 0, 0, 0, 3, 3, 3, 6, 6, 6 };
int[] colAdd = new int[] { 0, 3, 6, 0, 3, 6, 0, 3, 6 };
row = random.nextInt(3) + rowAdd[square];
col = random.nextInt(3) + colAdd[square];
Put in one array values which should be added to variable row, name it rowAdd. In second array colAdd put variable which should be added to col.
Finally, use square like the index to fetch correct value for addition.
Of course, arrays rowAdd and colAdd should be part of the method. (It is vast of time and memory to create new arrays every time when you call the method). These arrays should be class related, so they should be static.
This is the code for all things in once
public class Test {
public static void main(String[] args) {
//initializing arrays
int[][] grid = new int[9][9];
int[] numbers = new int[9];
//populating grid
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
grid[i][j] = (int)(Math.random()*10);
}
}
//printing grid
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
System.out.print(grid[i][j]);
}
System.out.println();
}
System.out.println();
int counter = 0;
//first and second loops counts for 0,3,6
for(int i = 0; i < 9; i += 3) {
for(int j = 0; j < 9; j += 3) {
//after taking i or j values(which must be either 0,3 or 6) goes for 3x3 parts and saving those numbers in number array
for(int t = i; t < i+3; t++) {
for(int k = j; k < j+3; k++) {
numbers[counter] = grid[t][k];
counter++;
}
}
//you can pick randomly from numbers array here
//showing which numbers picked
for(int t = 0; t < 9; t++) {
System.out.print(numbers[t]);
}
System.out.println();
System.out.println();
counter = 0;
}
}
}
}
Related
Program should print out the given values in array1 and print the second array as true or false.
Array1 represents a boardgame where characters can stand at the different positions. The integers indicate how dangerous it is to stand at every position.
If the character finds itself at int 3, it is to be declared dead.
If you add the values of each neighbor(not including the current position) and the total value equals 15 or more, it is also to be declared dead.
dead = false (F)
alive = true (T)
So if the current position is 2 or 1 and the total value of every neighbor is less then 15, the character lives. The neighbors missing in the edge of the array is to be counted as 0.
How do i print this the same way as array1 but with boolean values of T or F?
totalavGrannar is the variable that should add all the neighbors total value.
My code so far:
import java.util.Arrays;
public class uppg10{
public static void main(String[] args){
int [][] array1 = {{1,1,2,3,3},
{2,1,1,2,3},
{3,2,2,1,2},
{3,3,3,3,3}};
boolean [][] array2 = new boolean [4][5];
int rows = array1.length;
int cols = array1[0].length;
int totalavGrannar = 0;
array2 = new boolean[rows][cols];
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
System.out.print(String.format("%4d", array1[row][col]));
if ( ( (col+1) % cols ==0) && (col > 0))
System.out.println();
}
}
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
boolean trueorFalse;
if (array1[row][col]<3) {
trueorFalse = true;
array2[row][col] = trueorFalse;
}
else{
trueorFalse = false;
}
row = 1;
col = 1;
for(int offsetRow=row-1; offsetRow<=row+1; offsetRow++){
for(int offsetCol=col-1; offsetCol<=col+1; offsetCol++){
totalavGrannar += array1[offsetRow][offsetCol];
boolean trueorFalse2;
if (totalavGrannar<15) {
trueorFalse2 = true;
array2[row][col] = trueorFalse2;
}
else{
trueorFalse2 = false;
}
}
}
}
}
for (int row=0; row<array2.length; row++) {
for (int col=0; col<array2[row].length; col++) {
System.out.print(String.format("%8s" , array2[row][col] ? "T" : "F"));
if ( ( (col+1) % cols ==0) && (col > 0))
System.out.println();
}
}
}
}
How do i print this the same way as array1 but with boolean values of T or F?
For your question you did it correct in your code.
Your code not work because you have few others problems:
In the second loop you override array2 values even if false(dead).
you make him alive (set to true)
if (totalavGrannar<15) {
trueorFalse2 = true;
array2[row][col] = trueorFalse2;
}
Also, you sum the position with all neighbors (total 9 cells instead of only 8 neighbors)
--> In solution I set condition to exclude the position itself.
Another problem is that when you sum neighbors you check equality to 15 per addition for updat (T/F). This is wasteful.
--> You need to sum all and only then update value (T/F).
In the second loop you reset you loop condition to '1' so you have endless loop.
--> I removed those lines.
You forgot to reset totalavGrannar
A short fix I suggest:
(I also removed some redundant lines)
import java.util.Arrays;
public class uppg10 {
public static void main(String[] args) {
int[][] array1 = {{1, 1, 2, 3, 3},
{2, 1, 1, 2, 3},
{3, 2, 2, 1, 2},
{3, 3, 3, 3, 3}};
int rows = array1.length;
int cols = array1[0].length;
boolean[][] array2 = new boolean[rows][cols];
int totalavGrannar = 0;
//Print array1
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
System.out.print(String.format("%4d", array1[row][col]));
if (((col + 1) % cols == 0) && (col > 0))
System.out.println();
}
}
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (array1[row][col] < 3)
array2[row][col] = true;
//Iterate neighbors to sum values
for (int offsetRow = row - 1; offsetRow <= row + 1; offsetRow++) {
for (int offsetCol = col - 1; offsetCol <= col + 1; offsetCol++) {
if (offsetRow >= 0 && offsetCol >= 0) //0-bounds check
/*if (offsetRow < array1.length && offsetCol < array1.length) //edges-bounds check
if (offsetRow != row && offsetCol != col) { //exclude position from sum
totalavGrannar += array1[offsetRow][offsetCol];
}*/
if (offsetRow < array1.length && offsetCol < array1[0].length) //edges-bounds check
if (offsetRow != row || offsetCol != col) { //exclude position from sum
totalavGrannar += array1[offsetRow][offsetCol];
}
}
}
if (totalavGrannar >= 15)
array2[row][col] = false;
totalavGrannar = 0;
}
}
for (int row = 0; row < array2.length; row++) {
for (int col = 0; col < array2[row].length; col++) {
System.out.print(String.format("%8s", array2[row][col] ? "T" : "F"));
if (((col + 1) % cols == 0) && (col > 0))
System.out.println();
}
}
}
}
I am currently working on a SudokuChecker I want to check the subfields [3x3] of the sudoku. The following code does this:
int[][] field = new field[9][9];
int wrongNumbers = 0;
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
// Check subfield by using an array
int arr[] = new int[10];
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
arr[field[i + k][j + l]]++;
}
}
for (int k = 1; k < arr.length; k++) {
wrongNumbers += arr[k] > 1 ? arr[k] - 1 : 0;
}
}
}
I want to know are there any improvements for the given code?
(I am not talking about making the 3, 9, etc. constant)
I found a very good answer in Codefights from thucnguyen:
boolean sudoku(int[][] grid) {
for (int i = 0; i <9; i++) {
int row = 0, col = 0, group = 0;
for (int j = 0; j <9; j++) {
// check for row i
row += grid[i][j];
// check for col i
col += grid[j][i];
// check for sub-grid i
group += grid[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3];
}
if (row != 45 || col != 45 || group != 45) return false;
}
return true;
}
I am doing my homework right now and have a question about refactoring my code in Java.
I am working on a Sudoku right now and I need to check if the 3x3 boxes are valid or not. To do that I create a one dimensional array with all the numbers of the boxes and later I compare the value of them. It is working right now but it really isn't refactored at all. I would really like to know if there is any way to reduce all this copy paste.
public static boolean validFieldParts() {
int counter = 0;
boolean isValid = false;
int[] copyArray1 = new int[field.length];
int[] copyArray2 = new int[field.length];
int[] copyArray3 = new int[field.length];
int[] copyArray4 = new int[field.length];
int[] copyArray5 = new int[field.length];
int[] copyArray6 = new int[field.length];
int[] copyArray7 = new int[field.length];
int[] copyArray8 = new int[field.length];
int[] copyArray9 = new int[field.length];
// copy the array
// 1 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray1[i * 3 + j] = field[i][j];
}
}
// 2 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 3; j < 6; j++) {
copyArray2[i * 3 + j - 3] = field[i][j];
}
}
// 3 große Feld
for (int i = 0; i < field.length / 3; i++) {
for (int j = 6; j < 9; j++) {
copyArray3[i * 3 + j - 6] = field[i][j];
}
}
// 4 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray4[(i - 3) * 3 + j] = field[i][j];
}
}
// 5 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 3; j < 6; j++) {
copyArray5[(i - 3) * 3 + j - 3] = field[i][j];
}
}
// 6 große Feld
for (int i = 3; i < 6; i++) {
for (int j = 6; j < 9; j++) {
copyArray6[(i - 3) * 3 + j - 6] = field[i][j];
}
}
// 7 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 0; j < field[i].length / 3; j++) {
copyArray7[(i - 6) * 3 + j] = field[i][j];
}
}
// 8 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 3; j < 6; j++) {
copyArray8[(i - 6) * 3 + j - 3] = field[i][j];
}
}
// 9 große Feld
for (int i = 6; i < 9; i++) {
for (int j = 6; j < 9; j++) {
copyArray9[(i - 6) * 3 + j - 6] = field[i][j];
}
}
Arrays.sort(copyArray1);
Arrays.sort(copyArray2);
Arrays.sort(copyArray3);
Arrays.sort(copyArray4);
Arrays.sort(copyArray5);
Arrays.sort(copyArray6);
Arrays.sort(copyArray7);
Arrays.sort(copyArray8);
Arrays.sort(copyArray9);
for (int i = 1; i < copyArray1.length; i++) {
if (copyArray1[i] == copyArray1[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray2.length; i++) {
if (copyArray2[i] == copyArray2[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray3.length; i++) {
if (copyArray3[i] == copyArray3[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray4.length; i++) {
if (copyArray4[i] == copyArray4[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray5.length; i++) {
if (copyArray5[i] == copyArray5[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray6.length; i++) {
if (copyArray6[i] == copyArray6[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray7.length; i++) {
if (copyArray7[i] == copyArray7[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray8.length; i++) {
if (copyArray8[i] == copyArray8[i - 1])
counter++;
else
continue;
}
for (int i = 1; i < copyArray9.length; i++) {
if (copyArray9[i] == copyArray9[i - 1])
counter++;
else
continue;
}
if (counter > 0)
isValid = false;
else
isValid = true;
return isValid;
}
Instead of using 9 different arrays and 9 different loops to represent each section of 9, I would have another nested for loop that iterates over each cluster using the same array.
//Iterate over each 'block'
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
//Iterate over each cell in the block
for (int i = row*3; i < (row+1)*3; i++) {
for (int j = col*3; j < (col+1)*3; j++) {
copyArray[(i - 3) * 3 + j - 3] = field[i][j];
}
}
//Sort array and do duplication check here - return false if dupe found
}
}
return true
This would cut down on the length of your code, although it may not be more efficient.
Instead of using a counter flag, it would be much faster to instead return false whenever you would have incremented the counter, and to return true at the end. This would prevent unnecessary code from running
Here a complete refactoring. Here the improuvements:
Created two new methods: createCopy and isValid
Deleted unused variables counter and isValid
Substituted 9 arrays with one two size array.
The code as not been tested, please take a bit careful attention on method createCopy in particular.
// Creates each block of 9 digits copying digits from field
// row, col are the block position, starting from upper left 0, 0 to
// last block 2, 2
public static int[] createCopy(int[] field, int row, int col) {
int[] copy = new int[9];
for (int i = 3 * row; i < 3 * row + 3; i++) {
for (int j = 3 * col; j < 3 * col + 3; j++) {
copy[(i - 3 * row) * 3 + j - 3 * col] = field[i][j];
}
}
return copy;
}
// Check if one block is valid
private static boolean isValid(int[] copyArray) {
Arrays.sort(copyArray);
for (int i = 1; i < copyArray.length; i++) {
if (copyArray[i] == copyArray[i - 1]) {
// Exit immediately if not valid
return false;
}
}
return true;
}
// Create blocks, then validate them
// At first not valid block return false
public static boolean validFieldParts() {
int[][] copyArrays = new int[3][3];
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
copyArrays[row][col] = createCopy(field, row, col);
}
}
for (int[] copyArray : copyArrays) {
if (!isValid(copyArray)) {
// Exit immediately if not valid
return false;
}
}
return true;
}
Hey guys I am doing a question where I have to find a point in a Matrix A of N x M rows such that
the sum of rows above the point is equal to the sum of row
Consider this example
/**
* A[0][0] = 2 A[0][1] = 7 A[0][2] = 5
* A[1][0] = 3 A[1][1] = 1 A[1][2] = 1
* A[2][0] = 2 A[2][1] = 1 A[2][2] = -7
* A[3][0] = 0 A[3][1] = 2 A[3][2] = 1
* A[4][0] = 1 A[4][1] = 6 A[4][2] = 8
* #param matrix
* #return
*/
In this example the if we look at the point A[1][1], it can be said that the row above (sum = 14) is equal to the sum of rows below the point.
Can anyone help me on this?
I have so far gotten this far. But I know this is a sucky approach.
public int solution(int[][] matrix) {
int rows = matrix[0].length;
int columns = matrix.length;
int sumabove = 0;
int sumbelow = 0;
for( int i = 1; i < rows; i++ ) {
for (int j = 0; j < columns; j++) {
sumabove += matrix[i - 1][j];
sumbelow += matrix[i + 1][j];
}
}
return 0;
}
The idea is to calculate sum for every row (int[] rowsSum) and sum for all rows (totalRowsSum). And then to iterate through rows, comparing sum of previous rows (currentSum) with sum of next rows (totalRowsSum - currentSum - rowsSum[i]).
Code example.
public static int solution(int[][] matrix)
{
int foundRowNumber = -1;
int rows = matrix.length;
int columns = matrix[0].length;
int[] rowsSum = new int[rows];
int totalRowsSum = 0;
for (int i = 0; i < rows; i++)
{
int rowSum = 0;
for (int j = 0; j < columns; j++)
{
rowSum += matrix[i][j];
}
rowsSum[i] = rowSum;
totalRowsSum += rowSum;
}
int currentSum = 0;
for (int i = 0; i < rows; i ++)
{
if (currentSum == totalRowsSum - currentSum - rowsSum[i])
{
foundRowNumber = i;
break;
}
currentSum += rowsSum[i];
}
return foundRowNumber;
}
i'd say:
1st: get the sum of the whole matrix
2nd: divide by 2 and store in a var (mid)
3rd: loop it to go down a row each time and it will get the sum of that row and subtract it from the total sum, if it is smaller than the remaining then keeps going, if the remaining number is smaller then (mid) then you went over the middle and you start checking the columns for the row you are in and before in another loop using the same concept
something like this (pseudo code):
int sum = matrix.sum();
int mid = sum/2;
int topsum = 0;
int botsum = sum;
int counter=0;
bool fail = false;
while(topsum!=botsum && !fail) //either break when both top and bottom are same or if there is no middle gorund
{
int rowsum; //use loop to get the sum of the row
for(int i=0; i>colLength(); i++) rowsum=+ matrix[counter][i];
topsum =+ rowsum;
botsum=-rowsum;
counter++;
if(botsum>mid) //if you go over the middle
{
botsum=-rowsum; //take it back before last addition acction
counter --; //go back to the last row;
//loop
//here you will start checking columns to get to the middle.
}
}
this was made so that it would get you the cell and not row, but you can change it to your liking.
Ok I was able to do make a solution. But I think I made a mess of the complexity. I was supposed to do in a linear complexity. Anyways my solution is
public class MainClass {
static int matrix[][] = {{2, 7, 5}, {3, 1, 1}, {2, 1, -7}, {0, 2, 1}, {1, 6, 8}};
public static void main(String[] args) {
System.out.print(solution(matrix));
}
/**
* A[0][0] = 2 A[0][1] = 7 A[0][2] = 5
* A[1][0] = 3 A[1][1] = 1 A[1][2] = 1
* A[2][0] = 2 A[2][1] = 1 A[2][2] = -7
* A[3][0] = 0 A[3][1] = 2 A[3][2] = 1
* A[4][0] = 1 A[4][1] = 6 A[4][2] = 8
* #param matrix
* #return
*/
public static int solution(int[][] matrix) {
int columns = matrix[0].length;
int rows = matrix.length;
int sumRowsAbove = 0;
int sumRowsBelow = 0;
int sumColLeft = 0;
int sumColRight = 0;
int equilibrium = 0;
for( int i = 0; i < rows; i++ ) {
for (int j = 0; j < columns; j++) {
sumRowsBelow = getSumRowsBelow(i);
sumRowsAbove = getSumAbove(i);
sumColLeft = getSumColumnLeft(j);
sumColRight = getSumColumnRight(j);
if(sumRowsAbove == sumRowsBelow && sumColLeft == sumColRight) {
equilibrium++;
}
int x = 2;
x+=2;
}
}
return equilibrium;
}
public static int getSumRowsBelow(int rowNum) {
int columns = matrix[0].length;
int rows = matrix.length;
int sumBelow = 0;
for( int i = rowNum; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if((i+1) < rows){
sumBelow += matrix[i + 1][j];
}
}
}
return sumBelow;
}
public static int getSumColumnRight(int column) {
int columns = matrix[0].length;
int rows = matrix.length;
int sumBelow = 0;
for (int j = column; j <= columns; j++) {
for( int i = 0; i < rows; i++) {
if((j+1) < columns){
sumBelow += matrix[i][j + 1];
}
}
}
return sumBelow;
}
public static int getSumColumnLeft(int column) {
int columns = matrix[0].length;
int rows = matrix.length;
int sumBelow = 0;
for (int j = column; j >= 0; j--) {
for( int i = 0; i < rows; i++) {
if((j-1) >= 0){
sumBelow += matrix[i][j - 1];
}
}
}
return sumBelow;
}
public static int getSumAbove(int rowNum) {
int columns = matrix[0].length;
int rows = matrix.length;
int sumBelow = 0;
for( int i = rowNum; i >= 0; i--) {
for (int j = 0; j < columns; j++) {
if((i-1) >= 0){
sumBelow += matrix[i - 1][j];
}
}
}
return sumBelow;
}
}
This is a codility question regarding find the number of points (equilibriums) such the sum of elements in rows above the selected point is equal to the sum of rows below the point. And also sum of columns from the left of the selected point is equal to the sum of columns to the right of the point.
I need to write a short program on how to add two matrices.. The first matrix should look like this:
1 2 3 4 5 6 7 8 9 10
11 12 13.......19 20
21................30
31................40
41................50
etc..
91...............100
But I don't really come to a solution how to increment the first array.. :S
Here is what I got so far:
package uebung05;
public class MatrixAddition
{
public static void main(String[] argv)
{
int firstArray[][] = new int[10][10];
int secondArray[][] = new int[10][10];
int ergArray[][] = new int[10][10];
System.out.println("Matrix 1\n----------------------------");
// Inkrementieren der ersten Matrix
for(int row = 0; row < firstArray.length; row++)
{
for(int column = 0; column < firstArray[row].length; column++)
{
// Increment Array here???
System.out.print(firstArray[row][column] + " ");
}
System.out.println();
}
System.out.println("\nMatrix 2\n----------------------------");
// Dekrementieren der zweiten Matrix
for(int row = 0; row < secondArray.length; row++)
{
for(int column = 0; column < secondArray[row].length; column++)
{
// Array mit Werten befüllen
secondArray[row][column] = column + 1;
System.out.print(secondArray[row][column] + " ");
}
System.out.println();
}
System.out.println("\nAddition beider Matrizen\n----------------------------");
// Addition firstArray & secondArray
for(int row = 0; row < ergArray.length; row++)
{
for(int column = 0; column < ergArray[row].length; column++)
{
// Addition
ergArray[row][column] = firstArray[row][column] +
secondArray[row][column];
System.out.print(ergArray[row][column] + " ");
}
System.out.println();
}
}
}
Method to add the first and second matrices together:
public static int[][] matrixAdd(int[][] A, int[][] B)
{
// Check if matrices have contents
if ((A.length < 0) || (A[0].length < 0)) return B;
if ((B.length < 0) || (B[0].length < 0)) return A;
// create new matrix to store added values in
int[][] C = new int[A.length][A[0].length];
for (int i = 0; i < A.length; i++)
{
for (int j = 0; j < A[i].length; j++)
{
C[i][j] = A[i][j] + B[i][j];
}
}
return C;
}
But I don't really come to a solution how to increment the first array.
// Inkrementieren der ersten Matrix
for(int row = 0; row < firstArray.length; row++)
{
for(int column = 0; column < firstArray[row].length; column++)
{
firstArray[row][column] = 1+ row*10 + column;
System.out.print(firstArray[row][column] + " ");
}
System.out.println();
}
Sum two matrices in the new one and return:
public int[][] addMatrixes(int[][] src1, int[][] src2){
int[][] dst = new int[src1.length][src1[0].length];
for(int i=0;i<src1.length;i++){
for(int j=0;j<src1[0].length;j++){
dst[i][j] = src1[i][j] + src2[i][j];
}
}
return dst;
}
Not very generic, but you can define your first matrix with only one easy loop :
int dim = 10;
int size = dim*dim;
int firstArray[][] = new int[dim][dim];
int row, column;
for (int index = 0; index < size; index++ ){
row = index/dim;
column = index%dim;
firstArray[row][column]=row*10+column+1;
System.out.print(String.valueOf(firstArray[row][column])+"\t");
if (column == 9){ System.out.println("");}
}