How to assign the value in a string to a 2d array? - java

I am writing a Sudoku solver in java and wonder how to assign the value in a string to a 2d array by using charAt or something else?
for example, this is the printboard looks like:
1 2 3 4 5 6 7 8 9
+-----------+-----------+-----------+
A | 0 0 0 | 0 0 5 | 0 9 0 |
B | 1 4 0 | 0 0 0 | 6 7 0 |
C | 0 8 0 | 0 0 2 | 4 5 1 |
+-----------+-----------+-----------+
D | 0 6 3 | 0 7 0 | 0 1 0 |
E | 9 0 0 | 0 0 0 | 0 0 3 |
F | 0 1 0 | 0 9 0 | 5 2 0 |
+-----------+-----------+-----------+
G | 0 0 7 | 2 0 0 | 0 8 0 |
H | 0 2 6 | 0 0 0 | 0 3 5 |
I | 0 0 0 | 4 0 9 | 0 6 0 |
+-----------+-----------+-----------+
and this is the way I am using to assign values to the printboard so far:
public void printBoard() {
System.out.print(" ");
for (int j = 0; j < 3; j++)
System.out.print(" " + (j+1));
System.out.print(" ");
for (int j = 3; j < 6; j++)
System.out.print(" " + (j+1));
System.out.print(" ");
for (int j = 6; j < 9; j++)
System.out.print(" " + (j+1));
System.out.print(" ");
System.out.println();
System.out.print(" +-----------+-----------+-----------+\n");
char row_letter = 'A';
for (int i = 0; i < 3; i++) {
System.out.print(row_letter + " |");
row_letter++;
System.out.print(" " + board[i][0] +
" " + board[i][1] +
" " + board[i][2] + " |" +
" " + board[i][3] +
" " + board[i][4] +
" " + board[i][5] + " |" +
" " + board[i][6] +
" " + board[i][7] +
" " + board[i][8] + " |");
System.out.println("");
}
System.out.print(" +-----------+-----------+-----------+\n");
for (int i = 3; i < 6; i++) {
System.out.print(row_letter + " |");
row_letter++;
System.out.print(" " + board[i][0] +
" " + board[i][1] +
" " + board[i][2] + " |" +
" " + board[i][3] +
" " + board[i][4] +
" " + board[i][5] + " |" +
" " + board[i][6] +
" " + board[i][7] +
" " + board[i][8] + " |");
System.out.println("");
}
System.out.print(" +-----------+-----------+-----------+\n");
for (int i = 6; i < 9; i++) {
System.out.print(row_letter + " |");
row_letter++;
System.out.print(" " + board[i][0] +
" " + board[i][1] +
" " + board[i][2] + " |" +
" " + board[i][3] +
" " + board[i][4] +
" " + board[i][5] + " |" +
" " + board[i][6] +
" " + board[i][7] +
" " + board[i][8] + " |");
System.out.println("");
}
System.out.print(" +-----------+-----------+-----------+\n");
}
public static void main(String[] args) {
int[][] board = new int[9][9];
board[0][3] = 1;
board[0][5] = 5;
board[1][0] = 1;
board[1][1] = 4;
board[1][6] = 6;
board[1][7] = 7;
board[2][1] = 8;
board[2][5] = 2;
board[2][6] = 4;
board[3][1] = 6;
board[3][2] = 3;
board[3][4] = 7;
board[3][7] = 1;
board[4][0] = 9;
board[4][8] = 3;
board[5][1] = 1;
board[5][4] = 9;
board[5][6] = 5;
board[5][7] = 2;
board[6][2] = 7;
board[6][3] = 2;
board[6][7] = 8;
board[7][1] = 2;
board[7][2] = 6;
board[7][7] = 3;
board[7][8] = 5;
board[8][3] = 4;
board[8][5] = 9;
I want to know how can I use a 81 digit string like:"000005090140000670080002451063070010900000003007200080026000035000409060"
to assign values to printboard in certain position, 0 represents unsolved.

To strictly answer the question, the formula
81 / 9 * row + col
will give you the character position in the string that represents the board position that you want, as long as you use zero indexed rows and columns.
So something like
public String GetBoardValue(int row, int col)
{
return boardString.CharAt(81 / 9 * row + col);
}
Be careful though, code like this is very fragile and prone to break. The numbers 81 and 9 used here only work when the string is exactly 81 characters long. 'Magic numbers' in programming are bad.
As markus has mentioned you need to think about what you are trying to achieve here. A pure string representation of the board in this manner has no intrinsic value or meaning. At least the 2D array is a data representation that more closely matches the Sudoku game board. However creating your own object to encapsulate the board data and provide accessors specific to the Sudoku board would be a much better way to go. It would give the data meaning and be much easier to work with. The goal of programming is to write code that makes sense so that someone else reading your code understands it and can work with it. Because in many cases that person will be you a couple of months down the track when you haven't looked at this code for a while. If it takes you time to read the code just to understand what you meant, then there are better ways to write it.

Related

How to fix the code so it can run 5 times with for-loop?

I'm trying to run this 5 times with five different numbers (randomly, see int x), it runs without any problem with 1 attempt.
I tried to add a for-loop (lines with //) and it became a mess.
What can I do to fix it?
Example Result: --> What can I do to fix it?
My code will print the following:
Trial Number of Elements Search Key ....
1 65536 123 (random) ....
- - - - - - - - - - - - - - - - - - - - - - -- - -- - - - - - - - -
I want to become the following:
Trial Number of Elements Search Key
1 65536 123 (random)
2 65536 1234 (random)
3 65536 1123 (random)
4 65536 11234 (random)
5 65536 15234 (random)
Since your BinarySearch object contains a "compareCount" I think you added the for loop one line to late... Each run might create a new BinarySearch() to reset the compareCount.
So move the loop up.
Also your left/right index can produce index out of bounds if you find
the first element
the last element
no element
You could fix the logging like this:
(result > 0 ? arr[result - 1] : "nout found")
(result < max_range ? arr[result + 1] : "not found")
You need to handle the case when result = -1 (when values is not present in the array)
so when result = -1
you are trying to access arr[result - 1] i.e. arr[-2], which is clearly an invalid index
import java.util.Random;
class BinarySearch {
private int compareCount;
int binarySearch(int arr[], int l, int r, int x) {
if (r >= l) {
int mid = l + (r - l) / 2;
compareCount++;
if (arr[mid] == x)
return mid;
compareCount++;
if (arr[mid] > x)
return binarySearch(arr, l, mid - 1, x);
return binarySearch(arr, mid + 1, r, x);
}
return -1;
}
public static void main(String args[])
{
for (int i = 0; i<5;i++) {
BinarySearch ob = new BinarySearch();
int[] arr = new Random().ints(65536, 1, 65536 + 1).sorted().toArray();
int n = arr.length;
Random rand = new Random();
int max_range = 65536;
int x = rand.nextInt(max_range); // generate a random number between 1-65536
System.out.println(x);
int result = ob.binarySearch(arr, 0, n - 1, x);
String isFound = "N";
if (result != -1)
isFound = "Y";
int N = 65536;
int expect = (int)(Math.log(N) / Math.log(2)) + 1;
if(result != -1){
int right_index = 0;
if(result+1 == max_range) {
right_index = arr[result];
}
else {
right_index = arr[result + 1];
}
int left_index = 0;
if(result == 0) {
left_index = arr[0];
}
else {
left_index = arr[result + 1];
}
System.out.println
(" Trial " + " Number of Elements " + " Search Key " + " Left Index " + " Right Index " + " Found/Not Found " + " Expected Comparision " + " Acutal Comparsion " + "\n"
+" " + (i + 1) + " " + arr.length + " " + x + " " + left_index + " " + right_index + " " + isFound + " " + expect + " "+ ob.compareCount);
}
else {
System.out.println
(" Trial " + " Number of Elements " + " Search Key " + " Left Index " + " Right Index " + " Found/Not Found " + " Expected Comparision " + " Acutal Comparsion " + "\n"
+" "+(i+ 1)+" " + arr.length + " " + x + " " + "NOT FOUND" + " " + "NOT FOUND" + " " + isFound + " " + expect + " "+ ob.compareCount);
}
}
}
}

Non Recursive Merge Sort With 2 Array List

I'm trying non-recursive Merge Sort with 2 Arrays, But it doesn't work when given array's size is not 2^n.
It works fine when the given array's size is 2^n.
For example, given array which's size is not 2^n : 7 2 9 11 4 3 8 6 1 10
As step is 1, sort result is :
2 7 9 11 3 4 6 8 1 10
And now it will sort with 4 items, 4 items, 2 items.
But it doesn't work.
so I checked the console, and it seems like, the problem is
while(leftStart <= leftLast && rightStart <= rightLast).
As I catched, when checking 2 7 9 11 and 3 4 6 8 to sort, the leftStart is going to higher than leftLast, 2 < 7 (leftStart++), 2 < 9 (leftStart++) so leftStart > leftLast, the while loop is broken ).
It should check for the others, because it could be L1.get(leftStart) > L1.get(rightStart)
But I don't know how to solve this problem..
Thank you for your help.
public statid void main(String[] args){
ArrayList<Integer> l = new ArrayList<>();
l.add(7);
l.add(2);
l.add(9);
l.add(11);
l.add(4);
l.add(3);
l.add(8);
l.add(6);
l.add(1);
l.add(10);
sort(l);
}
public static void sort(ArrayList l) {
L1 = null;
L2 = null;
step = 1;
L1 = l;
L2 = new ArrayList<>();
for(int i = 0; i < L1.size(); i++)
L2.add(null);
int tSize = l.size();
while(step <= l.size() ) {
for(int i = 0; i < tSize; i += this.step*2) {
int leftStart = i;
int leftLast = (leftStart + this.step)-1;
if(leftLast >= tSize-1)
continue;
int rightStart = i + this.step;
int rightLast = (rightStart + this.step)-1;
if(rightStart >= tSize)
rightStart = tSize - 1;
int idx = i;
// System.out.println("step : " + step + " || idx : " + idx + " || leftStart : " + leftStart + " || rightStart : " + rightStart);
// System.out.println("step : " + step + " || idx : " + idx + " || leftEnd : " + leftLast + " || rightEnd : " + rightLast);
// System.out.println();
while(leftStart <= leftLast && rightStart <= rightLast) {
System.out.println("leftStart : " + leftStart + " || rightStart : " + rightStart + " || idx : " + idx);
Object a = L1.get(leftStart);
Object b = L1.get(rightStart);
if(comp.compare ( a, b ) < 0 ) {
L2.set(idx++, L1.get(leftStart++));
L2.set(idx, L1.get(rightStart));
}else {
System.out.println("idx :::: " + idx);
L2.set(idx++, L1.get(rightStart++));
L2.set(idx, L1.get(leftStart));
}
}
}
for(int i = 0; i < L1.size(); i++) {
L1.set(i, L2.get(i));
}
System.out.println("============================");
for(int j = 0; j < L1.size(); j++) {
System.out.print(L1.get(j) + " ");
}
System.out.println("\n============================");
step *= 2;
}
}
The result:
1 2 3 4 6 7 8 9 8 10
If an array has an odd number of items, then splitting it will result in one subarray will have one more item than the other.
[2,7,9,11,3,4,6,8,1,10]
/ \
[2,7,9,11,3] [4,6,8,1,10]
/ \ / \
[2,7,9] [11,3] [4,6,8] [1,10]
/ \ / \
[2,7] [9] [4,6] [8]
Both recursive and non-recursive merge sort have the same time complexity of O(nlog(n)).
The iterative version doesn't use recursion to split the array. Rather, it uses nested loops.

Java ArrayList for Tic Tac Toe game

Hello I'm starting out with Java and I need a little help. I'm currently working on a tic tac toe game project and I'm stuck. At the beginning of the game I want all 9 spots on the game board to have a ' ' so that the board shows as empty, but when players select their next move I want them to use the following format: A1, A2, A3, B1, etc. How do I link my arrayList with these strings?
Example A1 would be = 0, A2 = 1.... C3=8
public static void printGameBoard() {
System.out.println(" A B C");
System.out.println(" ______________");
System.out.println(" | | | |");
System.out.println("1 |" + board.get(0) + " | " + board.get(1) + " | " + board.get(2) + " | ");
System.out.println(" |----|----|----|");
System.out.println("2 |" + board.get(3) + " | " + board.get(4) + " | " + board.get(5) + " | ");
System.out.println(" |----|----|----|");
System.out.println("3 |" + board.get(6) + " | " + board.get(7) + " | " + board.get(8) + " | ");
System.out.println(" |____|____|____|\n");
public static int gameplay() {
boardSize = 9;
board = new ArrayList();
for(int i = 0; i < boardSize; i++) {
board.add(Character.valueOf(' '));
}
return playerTurn();
}
So, you're ArrayList is a linear container, contain 0-n elements. Your grid is a two dimensional container, allowing elements to be referenced via yxx reference. You need a means to be able to convert between these.
You know that the grid is a 3x3 matrix (3 rows by 3 columns), so a little bit of simple maths will come in handy.
A references the first col, so your index would be (y - 1) + (0 * 3) (remember, Java is 0 indexed)
B references the second col, so your index would be (y - 1) + (1 * 3)
And C references the third col, so your index would be (y - 1) + (2 * 3)
Now, what you need is away to convert the letters to a number, astonishing, this is actually very simply...
String cell = "A1";
int col = cell.charAt(0) - 'A';
will return 0.
A slightly safer solution would be to remove the case entirely from your operation, something like...
int col = cell.toLowerCase().charAt(0) - 'a';
Now, you'd need to do some validation on the input to make sure the values are within range.
But what about the row??
String cell = "A1";
int col = cell.toLowerCase().charAt(0) - 'a';
int row = Integer.parseInt(cell.substring(1)) - 1;
System.out.println(row + "x" + col);
Simple :)
So, you could then put it together something like...
if (row >= 0 && row < 3 && col >= 0 && col < 3) {
int index = (row * 3) + col;
board.set(index, "x");
}
or something along those lines
And because I got my maths all turned around backwards....
String[] cols = new String[]{"A", "B", "C"};
for (int rowIndex = 1; rowIndex < 4; rowIndex++) {
for (String colValue : cols) {
String cell = colValue + rowIndex;
int col = cell.toLowerCase().charAt(0) - 'a';
int row = Integer.parseInt(cell.substring(1)) - 1;
int index = (row * 3) + col;
System.out.println("Cell = " + cell + "; index = " + index);
}
}
Outputs
Cell = A1; index = 0
Cell = B1; index = 1
Cell = C1; index = 2
Cell = A2; index = 3
Cell = B2; index = 4
Cell = C2; index = 5
Cell = A3; index = 6
Cell = B3; index = 7
Cell = C3; index = 8
try this.
for(int i = 0; i < boardSize; i++) {
board.add(Character.valueOf(i+1));
}

Get sum of integers with old numbers 1 + (1 + 2) + (1 + 2 + 3) + ... + (1 + 2 + 3 + ... + n)

I'm trying to reach this :
1 + (1 + 2) + (1 + 2 + 3) + ... + (1 + 2 + 3 + ... + n)
I'm already getting this result:-
(1 + 2) + (2 + 3)
with this code :
int n = 8;
for (int i = 1; i < n; i++){
int j = i + 1;
System.out.print("(" + i + " + " + j + ")");
}
How can I achieve the top result ?
You need two loops like this :
int n = 8;
String del;
String del2 = "";
for (int i = 1; i <= n; i++) {
System.out.print(del2 + "(");
del = "";
for (int j = 1; j <= i; j++) {
System.out.print(del + j);
del = " + ";
}
System.out.print(")");
del2 = " + ";
}
code demo
Move the declaration of j before the loop and initialize it with 0, then just add the current i to j.
That would solve what? – AKSW
This would calculate the sum of the equation.
To print the equation you also need one loop only:
int n = 8;
StringBuilder equation = new StringBuilder("1");
StringBuilder equationGroup = new StringBuilder("1");
for (int i = 2; i < n; i++) {
equationGroup.append(" + ");
equationGroup.append(i);
equation.append(" + (");
equation.append(equationGroup.toString());
equation.append(")");
}
System.out.println(equation.toString());
Well, thanks #YCF_L for your answer it's the correct one, but this complete one after edit, i posted it in case some one need the complete solution:
int n = 8;
String del;
String delPlus = "";
String rightPract = "", leftPract = "";
for (int i = 2; i < n; i++) {
System.out.print(delPlus + rightPract);
del = "";
for (int j = 1; j < i; j++) {
System.out.print(del + j);
del = " + ";
}
System.out.print(leftPract);
delPlus = " + ";
rightPract = "(";
leftPract = ")";
}
Now the result is :-
1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4 + 5) + (1 + 2 + 3 + 4 + 5 + 6)
If you take the recursion approach you have to think of it as a recursion inside another recursion. add(i,n) generates 1 and (1+2) and (1+2+3) up to (1+2+3...n). then the sum(i,n) recursively sum them together
public static int add(int i, int n){
if(i == n){
return n;
}
return i + add(i+1,n);
}
public static int sum(int i, int n){
if(i == n){
return add(0,n);
}
return add(0, i) + sum(i+1,n);
}
public static void main(String[] args){
int n = 8;
System.out.print(sum(0, n));
}

Bitwise operations, how to check for 0 or 1?

I have an integer like:
0x10000010
I would like to know if a particular bit is 1 or 0. For example, something like:
int number = 0x10000010;
for (int i = 0; i < 8; i++) {
if (ith bit == 1) {
System.out.println("bit " + i + " is 1.");
} else {
System.out.println("bit " + i + " is 0.");
}
}
---- output ----
bit 0 is 1
bit 1 is 0
bit 2 is 0
bit 3 is 0
bit 4 is 0
bit 5 is 0
bit 6 is 1
bit 7 is 0
I've forgotten how to do this, and what this type of operation is called,
Thanks
number & (1 << i) will be 0 if the bit wasn't set, non-zero if it was.
Similar to dty's answer
int number = 0b10000010; // you are assuming this is binary not hex.
for (int i = 0; i < 8; i++) {
if((number >> i) & 1 != 0)
System.out.println("bit " + i + " is 1.");
else
System.out.println("bit " + i + " is 0.");
}
or
int number = 0b10000010; // you are assuming this is binary not hex.
for (int i = 0; i < 8; i++)
System.out.println("bit " + i + " is " + ((number >> i) & 1));

Categories

Resources