How can I loop through a Sudoku board? - java

For example, say we have a Sudoku board like this:
0 0 6 5 8 9 7 4 3
0 5 0 0 0 0 0 6 0
7 0 9 0 6 0 1 0 0
0 3 0 0 0 2 0 8 7
0 0 1 0 0 0 4 0 0
8 9 0 6 0 0 0 5 0
0 0 2 0 5 0 3 0 6
0 7 0 0 0 0 0 9 0
3 1 8 4 9 6 5 0 0
I want to store it into one array such that the first 9 elements of the array are the first sub block, i.e. the values {0 0 6 0 5 0 7 0 9} and followed by {5 8 9 0 0 0 0 6 0}.
I've tried finding a solution but I always get an array index out of bounds error and it is too brute force. Something similar to this:
while(st.hasMoreTokens()) {
if(ctr == 27) {
c.addSubBlock(sb1);
c.addSubBlock(sb2);
c.addSubBlock(sb3);
sb1 = new SubBlock();
sb2 = new SubBlock();
sb3 = new SubBlock();
ctr = 0;
}
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
ctr+=9;
}
Please give me some tips. Code snippets would also be a great help.
EDIT: This thread somehow helped me figured it out. And yes, this is part of the Sudoku where I'm trying to encode the board into an array.
What I did was to transform first the input String into a 2d array (9x9) and use int block = (row/3)*3 + (col/3); to compute exactly which sub block each element belongs.

Create a 3x3 array of sub blocks
Use 2 counters (x & y) for tracking the position in the full board of each element read
Add the values at (x,y) into sub block (x/3,y/3)
Something like this:
SubBlock board[][] = new SubBlock[3][3];
int x, y;
for ( y=0; y<9; y++ )
for ( x=0; x<9; x++ )
board[y/3][x/3].addElement(Integer.parseInt(st.nextToken()));
board[0][0] will be the top-left SubBlock, board[2][2] the bottom-right one.

Store everything in a two dimension array. E.g.
int[] board = {
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}};
//looping
public static void Main(string[] args){
for(int i = 0; i < 9; i++)
{
System.out.println("SubBlock number"+i);
for(int j = 0; j < 9; j++){
System.out.println(board[i][j]);
}
}
}

Assuming that you are reading input left to right, top to bottom, try a set of 4 nested loops like this:
int board[] = new int[81];
for (int outY = 0; outY < 3; outY++)
{
for (int outX = 0; outX < 3; outX++)
{
for (int inY = 0; inY < 3; inY++)
{
for (int inX = 0; inX < 3; inX++)
{
board[27*outY + 9*outX + 3 * inY + inX] = //parse an int from your input here
}
}
}
}

It would be great if we knew why you are trying to loop through the board.
If you want to check if you can enter a number, I recommend you use maps for each of the 3x3 squares.
Then check if the item is in the map already or not. For the rows and columns, you can either loop over the 2D array and check each element, or -again- use a map for each column and a map for each row.

I'm not entirely sure if you want an answer for a single-dimension array or if you're willing to make it a two-dimensional array (as you mention each nine element set with curly braces), but if two-dimensional is OK...
The OP in this Code Review posting used a 'fancy' way of sifting through the subgrids by using the math (i % 3) + rowStart inside one of the square brackets and (i / 3) + colStart inside the other. One commenter noted this modulo method to be a bit obscure, and I'm prone to agree, but for how clean it is and the fact that it works, I think it's a solid solution. So, paired with the iteration of the for loop, we can sift through each 'subgrid' cell, as well as each element of row + col.
for(i=0; i<9; ++i)
{
if (puzzle[row][i] == num) return 0;
if (puzzle[i][col] == num) return 0;
if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0;
}
If we find a number in one of the cells that matches, it's a duplicate, and we exit the function as 'false', or, 0.
EDIT:
Now that I think of it, you could use this same trick for a single-dimension array by using i % 9 instead of 3. You could then determine which 'row' we're on by doing i / 9 and trusting that, since we're dealing with type ints, we'll truncate the unnecessary decimals.
This does verify that this trick is a bit prone towards N-1 indexed data, as someone would assume 'go to the 81st element' would mean go to the 9th column of the 9th row, but using 81 % 9 would yield 0, and 81 / 9 would yield 9, so we'd go to the 0th place at row 9.

Related

Number of ways to form an amount with certain coins

I am trying to solve this problem. http://www.lintcode.com/en/problem/coin-change-ii/#
This is the standard coin change problem solvable with dynamic programming. The goal is to find the number of ways to create an amount using an infinite set of coins, where each has a certain value. I have created the following solution :
public int change(int amount, int[] coins) {
// write your code here
int[] dp = new int[amount + 1];
dp[0] = 1;
// for(int coin : coins) {
// for(int i = 1; i <= amount; i++) {
// if(i >= coin) dp[i] += dp[i-coin];
// }
// }
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
return dp[amount];
}
Why does the first for loop give the correct answer, but the second one does not? What am I missing here? Shouldn't the answer be the same? Could you provide a visual to help me "see" why the second for loop is incorrect?
When the amount = 8 and coins = [2,3,8] the output is 5 when it should be 3 when using the 2nd for loop's technique which is not correct.
Thank you.
Let's consider the loop that works first:
for(int coin : coins) {
for(int i = 1; i <= amount; i++) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
Each iteration of the outer loop takes a coin of one value and finds out the number of ways to reach any value between the coin value and amount, adding that coin to the result of the previous iterations.
Considering your amount = 8 and coins = [2,3,8] example:
The array is initialized to
index 0 1 2 3 4 5 6 7 8
value 1 0 0 0 0 0 0 0 0
which means that without any of the coins, the only amount we can reach is 0, and we have a single way to reach that amount (0 2s, 0 3s, 0 8s).
Now we find the amounts we can reach with just the coin of value 2:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 0 1 0 1 0 1
It's not surprising that we can reach any even amount. For each such amount we have a single way to reach that amount (1 2s to reach 2, 2 2s to reach 4, etc...).
Now we find the amounts we can reach with coins of value 2 or 3. We can reach an amount k using a single coin of 3 if we already found ways to reach the amount k-3.
Below I show the number of ways to reach each value between 0 and 8, and specify how many coins of each type are used in each combination.
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 2
0x2 - 1x2 0x2 2x2 1x2 3x2 2x2 4x2
0x3 - 0x3 1x3 0x3 1x3 0x3 1x3 0x3
or or
0x2 1x2
2x3 3x3
Finally, in the last iteration we consider the coin of 8. It can only be used to reach the amount 8, so we get the final result:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 3
When you swap the loops:
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
you bring the order the coins are added into play. For example, the amount 5 can be reached by either first taking a coin of 2 and then a coin of 3, or by first taking a coin of 3 and then a coin of 5. Therefore the value of dp[5] is now 2.
Similarly, dp[8] results in 5 since you can take any of the following sequences of coins:
2+3+3
3+2+3
3+3+2
2+2+2+2
8
The original loop doesn't distinguish between 2+3+3, 3+2+3 and 3+3+2. Hence the different output.
private static int coinChange(int[] coins, int sum) {
int size = coins.length;
int[][] arr = new int[size + 1][sum + 1];
// Applying the recursive solution:
for(int i = 1; i < size +1; i++){
for(int j = 1; j < sum +1; j++) {
arr[i][0] = 1;
if (coins[i - 1] > j) {
arr[i][j] = arr[i - 1][j];
} else
arr[i][j] = arr[i - 1][j]+arr[i][j - coins[i - 1]] ;
}}
return arr[size][sum];enter code here

Implement sudoku puzzle 9x9 by Graph

I have a sudoku puzzle 9x9 in a text file and I wondering how can we create a Graph from sudoku puzzle.Sudoku puzzle is a int[][] Example puzzle
0 0 0 0 9 8 0 4 5
0 0 4 3 2 0 7 0 0
7 9 0 5 0 0 0 3 0
0 0 0 9 0 0 4 0 0
0 4 5 0 0 2 8 0 0
8 7 9 6 0 4 0 1 0
0 3 0 0 7 9 0 6 4
4 5 0 2 1 3 9 0 8
0 8 7 4 6 5 0 0 0
and class Graph
class Graph
{
private int V;
private LinkedList<Integer> adj[];
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
}
void addEdge(int v,int w)
{
adj[v].add(w);
adj[w].add(v);
}
public int getV()
{
return V;
}
public LinkedList<Integer> getListAdj(int u)
{
return adj[u];
}
I write a function to read puzzle from a text file and implement it to graph
public boolean readGraph(String input_name, int result[])
{
return true;
}
But I stuck in this step.
Here goes:
First, I already know that the puzzle is 9x9, so the newlines in the text file are meaningless to me. I can ignore them. Also, I know that each element of the puzzle is only ever going to be a single character long so (after getting the text file into memory like so: Reading a plain text file in Java):
I get my String puzzle which is that text file into memory. Now I want to iterate over that String like so:
Graph graph = new Graph(81); //9x9 graph with 81 verticies
int whichVertextAreWeOn = 0;
for (int i = 0; i < puzzle.length(); i++){
char c = puzzle.charAt(i);
if(c>'0' && c > '9'){
int integer = Integer.parseInt(c);
//now I need to add this to my Graph... Saving my work now, comments are appreciated
//Turns out you simply add edges to each vertex in a graph, the vertex itself has no value...
//so I'm going to keep track of which vertex I'm on, this is starting to seem like a bad data structure for this purpose, but I shall carry on. -Adding an iterator to keep track of which vertex I'm on.
for(int w = 0; w < graph.V(); w++;){
if(vertextIsLinked(whichVertextAreWeOn, w))
graph.addEdge(whichVertextAreWeOn, w);
}
//hum... from here I need to add an edge to this vertex for each connected vertex...
}
}
private boolean vertextIsLinked(int vertexWeAreOn, int possibleVertext){
//use rules of Sukdoku to figure out if these two verticies should be linked. This would return true for any vertex in horizontal or vertical alignment to the vertexWeAreOn.
}

Creating a sliding number puzzle board using arrays in Java

So I'm kind of new to Java and decided to create a sliding number puzzle of some sort. Here's what I have :
int[] puz = {1,2,3,
4,5,6,
7,8,9}
for(int i=0; i<puz.length; i++){
System.out.println(puz[i]);
}
The 1 is supposed to be the blank spot but I'll figure that out later. My problem is that the code prints:
1
2
3
4
5
6
7
8
9
when I want it to print:
1 2 3
4 5 6
7 8 9
I've also tried doing a nested loop that I'm too embarrassed to show on here due to how hideous it was.
Would I try using a 2d array instead?
I guess you could try...
int puz = {1,2,3,4,5,6,7,8,9};
int n = Math.ceil(Math.sqrt(puz.length));
for (int i = 0; i < puz.length; i++) {
System.out.print(puz[i] + ((i + 1) % n == 0 ? "\r\n" : " ");
}
Try creating a variable counter and increment it every time you iterate through the loop. Using a modulus operator, divide it by 3 and when remainder is 0, create a new line.
int puz = {1,2,3,4,5,6,7,8,9};
int counter = 1;
for(int i=0; i<puz.length; i++){
System.out.print(puz[i]);
if (counter % 3 == 0){
System.out.println("");
}
counter++;
}
The trick here is to use the modulus operator. This operator divides one number by another, and returns the remainder. In java (and everywhere else as far as I know), % is the modulus operator. If you want every third number to have a line break after it, simply divide by three using modulus division, like so:
int[] puz = {1,2,3,4,5,6,7,8,9};
//For what it's worth, you don't have this semicolon in your question, so I added it in.
for(int i=0; i<puz.length; i++){
System.out.print(puz[i] + " ");
if(i % 3 == 2){//It's equal to 2 because you start at 0 and not 1.
System.out.println("");
}
}
This code, when executed, prints the following, which is what you wanted:
1 2 3
4 5 6
7 8 9

Is there a predefined method to padarray in java by a given no of rows and columns with a number

How to padarray in java that is add row and column to a existing array in front and back with a given number.
For example :-
let x = 1 2 3
4 5 6
7 8 9
and now want to 2 rows and columns of zeros in this:
x = 0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 1 2 3 0 0
0 0 4 5 6 0 0
0 0 7 8 9 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
So, i want to know that is there a existing method or way to do this in java like it is available in matlab using the predefined method called padarray(x,[r,c]).
You can never add rows or columns to 2 dimensional arrays at all. Arrays are fixed size. You could use a dynamic data structure such as List<List<Integer>>.
What you also can do is create a new array (that is bigger or smaller than your current one) using the Arrays.copyOf(int[] original, int newLength); method.
You array x is like:
int[][] x = new int[][]{{1,2,3}, {4,5,6}, {7,8,9}};
There is no one-liner (I know of) to transform it to your desired format. You have to create a method that creates a new 2 dimensional array and place your values at the correct indexes.
Here is some code that takes the 2D array you want padded, what you want it to be padded with, and how many pads to surround the array with (yours would be 2 because you want your array surrounded with 2 layers of 0's).
public static int[][] padArray(int[][] arr, int padWith, int numOfPads) {
int[][] temp = new int[arr.length + numOfPads*2][arr[0].length + numOfPads*2];
for (int i = 0; i < temp.length; i++) {
for (int j = 0; j < temp[i].length; j++) {
temp[i][j] = padWith;
}
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
temp[i+numOfPads][j+numOfPads] = arr[i][j];
}
}
return temp;
}

How can I go through a 2D Array via the secondary diagonal?

As I said, I would like to "scroll" through a Multi Dimensional array via the secondary diagonal, my desired input to be: (Case a) [It can be in either C++ or Java, it doesn't matter]
NOTE+EDIT: The order is not random. It starts from the 1 at the bottom and goes its way up.
Is this possible?
If not then at least half of the code? (Case b)
// Case a:
16 15 13 10
14 12 9 6
11 8 5 3
7 4 2 1
// Case b:
0 0 0 1
0 0 9 6
0 8 5 3
7 4 2 1
You can do this with a simple loop (this is Java):
int size = 4;
int[][] matrix = new int[size][size];
// . . .
for (int i = 0; i < size; ++i) {
doSomethingWith(matrix[i][size - i - 1]);
}
int[][] a={{7,6,4,1},{5,3,9,6},{2,8,5,3},{7,4,2,1}};
for(int i=0; i<a.length; i++)
{
for(int j=a[i].length-1; j>=a[i].length-(i+1); j--)
{
System.out.print(a[i][j]+",");
}
System.out.println();
}

Categories

Resources