I'm pretty new to coding in general and I'm writing a recursive sudoku solver right now in java. However, I keep getting a Stack Overflow error and I can't for the life of me figure out why.
Here's the whole code. The error supposedly lies in the various solve methods.
import java.util.*;
public class sudoku{
protected static int n;
protected static int[][] game;
public static boolean checkRow(int a, int b){
boolean z = true;
for(int i=0;i<n;i++){
if(i==b) continue;
else if(game[a][b]==game[a][i]){
z = false;
break;
}
}
return(z);
}
public static boolean checkColumn(int a, int b){
boolean z = true;
for(int i=0;i<n;i++){
if(i==a) continue;
else if(game[i][b]==game[a][b]){
z = false;
break;
}
}
return(z);
}
public static boolean checkBox(int a, int b){
boolean z = true;
int x = (int)Math.sqrt(n)*(int)(a/Math.sqrt(n));
int y = (int)Math.sqrt(n)*(int)(b/Math.sqrt(n));
for(int i=x;i<x+Math.sqrt(n);i++){
for(int j=y;j<y+Math.sqrt(n);j++){
if(a==i&&b==j) continue;
else if(game[a][b]==game[i][j]){
z = false;
break;
}
}
}
return(z);
}
public static boolean checkAll(int a, int b){
return(checkRow(a,b)&&checkColumn(a,b)&&checkBox(a,b));
}
public static void solvePrevious(int row, int col){
if(row==0&&col==0){
System.out.println("This game is unsolvable.");
return;
}
else if(col==0) solve(row-1,n-1,game[row-1][n-1]+1);
else solve(row,col-1,game[row][col]+1);
}
public static void solveNext(int row, int col){
if(row==n-1&&col==n-1) return;
else if(col==n-1) solve(row+1,0,1);
else solve(row,col+1,1);
}
public static void solve(int row, int col, int value){
if(value<=n){
game[row][col] = value;
if(checkAll(row,col)) solveNext(row,col);
else solve(row,col,value+1);
}
else solvePrevious(row,col);
}
public static void main(String[] args){
Scanner inp = new Scanner(System.in);
System.out.println("What is the side length of the puzzle?");
n = 0;
do{
n = inp.nextInt();
if(Math.sqrt(n)%1!=0) System.out.println("The side length must be a perfect square.");
}while(Math.sqrt(n)%1!=0);
game = new int[n][n];
solve(0,0,1);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
System.out.print(game[i][j]+" ");
}
System.out.println(" ");
}
}
}
I think you don’t need to call solvePrevious from the solve method.
I’m a bit confused about the method names—the “previous” could either mean “previous cell” or “previous number for the same cell”. This is something you could improve.
The basic idea should look like this:
/* in main: */
solve(0, 0, 1);
solve(row, col, num) {
if (checkAll(row, col)) {
solveNextCell(row, col);
}
if (num < n * n) {
solve(row, col, num + 1);
}
}
solveNextCell(row, col) {
if (row == n - 1 && col == n - 1)
printSolution();
else if (col == n - 1)
solve(row + 1, 0, 1);
else
solve(row, col + 1, 1);
}
This way, you only “search forward”. Because the two methods call each other recursively, all the “previous” steps are remembered implicitly by the call hierarchy.
But even then will your program run a looooooong loooooong time, at least for the initially empty board. This is because it tries each number in each field of the first row, which are 9^9 = 387420489. Just assuming that in the second row there are similarly many positions, the number of tries grows to 150094635296999121, which is such a large number that I don’t know how to pronounce it. And that is just row 2 of 9.
So I suggest that you take an entirely different approach: As soon as you fill in a number, you mark that number as forbidden in the respective row, column and box. That way, you don’t have to loop over all the rows, columns and boxes each time. When I programmed a Sudoku solver, I had good success with remembering for each cell which numbers are still possible, and ruling them out as far as possible before even starting to recurse and trying every possible number.
Related
given array of coins (int) and an int n the function need to return true if there is atleast one solution to the coin-change problem.
meaning: for array of ints> 0: [c(0) ,c(1) ,c(2) ,c(3) ,...... ,c(k)]. check if there is a solution for
the eqauation: a(0)*c(0)+ a(1)*c(1)+.....+ a(k)*c(k)= n. //n is the money we need to change
given c(0),c(1),....,c(n) >0 and a(0),a(1),....,a(n) =>0 both integers.
so I managed to make this code: the problem is that its algorithmic efficiency sucks, and this should be running on high values, and big coins array, so I need a code that is able to do this quicker.
public static boolean change(int[] coins, int n) {
boolean ans = false;
//loop running in recursion till founds ans/ passing limit
for (int i = 0; i < coins.length & (!ans); i = i + 1) {
if (n % coins[i] == 0) {
return true;
}
if (n >= coins[i]) {
ans = change(coins, n - coins[i]);
}
}
return ans;
}//O(n*k^n) solution for false ans , very bad :(
for example: for coins = {2,4,8} and n= 4111; I should get false, but the program unable to run this.
btw I would prefer this function to use recursion, but any solution/ guidnes is good :)
this is an other try doing this better but still not running as wanted.
//trying to use binary search and using divisions instead of minus
public static int iscashable(int[] coins, int n, int min, int max)
{
int check=(max+min)/2;
if(check == coins.length-1 | check == 0)
return check;
if(n/coins[check] > n% coins[check])
{
return (iscashable(coins,n,check,max));
}
else
{
return check;
}
}
public static int canchange(int[] coins, int n, int count)
{
int x=0;
int check= iscashable(coins,n,0,coins.length-count);
if(n%coins[check]==0)
{
return 0;
}
if(check==0)
{
return n;
}
if(n/coins[check] > n% coins[check])
{
x= (n/coins[check]) - (n% coins[check]);
int k= n-(coins[check]*x);
return canchange(coins, k, count+1);
}
else
{
return canchange(coins,n-coins[check],count+1);
}
}
the problem is both about runtime and number of recursion calls (with big number given, every recursion layer is coins.length^(num of layers));
I really thank you for your help!
I'm currently creating a minesweeper game, at the moment I'm just finishing up a method that counts neighboring mines, it also has parameters for the number of rows, columns and mines, I also declared a maxMines variable that doesn't allow more than 20 mines on the grid... Now, I want to make this method return true if the square was successfully mined, and false if the maximum number of mines was exceeded, or the square has already been mined.
Also I want this method to use the parameters to check whether a mine would be on those coordinates and I have no idea where to begin, if anyone can give me a starting point, it would be greatly appreciated.
Here is my code (The error lies at the very bottom of mineTile; if statement):
import java.util.Random;
public class Minefield extends Minesweeper{
boolean[][] minefield;
int[][] minedNeighbour;
Random random = new Random();//random number generator
int row;
int column;
int mines;
public int emptySpaces = column*row;
int maxMines = 20;
public Minefield(int row, int column, int mines) {
this.row = row;
this.column = column;
this.mines = mines;
int x,y;
minedNeighbour = new int[10][10];
//initializeMines(); //fill with zero's
//placeMines(); //get the random numbers and place 10 mines
//fillNoOfSurroundingNeighbours(); //based on the mines 8 boxes surronding the mine will be calculated and shown to the player
//startBoard(); //This fills the actual board
}
public void mineTile(int x, int y){
int i,j; //loop variables
if(minedNeighbour[x][y]!= -1)return; //already used
minedNeighbour[x][y] = 0;//square used
emptySpaces--;//decreases the emptyspaces counter
for (i = x-1 ;i<=x+1 ; i++)
{
for(j = y-1 ;j<=y+1 ; j++)
{
if(minedNeighbour[i][j] == 99)
{
minedNeighbour[x][y]++;
}
if(i >= 0 && j >= 0 && i < 5 && j < 5)
{
if(minedNeighbour[i][j] == 99)
{
minedNeighbour[x][y]++;
}
}
}
}
if(mines > maxMines)
{
return false;
}
else {
return true;
}
}
}
Your method is set to return a void, so that means you can't return anything. If you want to return a boolean, change your method header to reflect that, i.e. by changing it to
public boolean mineTile(int x, int y)
The problem is there is an array of 10000 that is already filled for me. The range of numbers that will fill the array will be between 0 and 2500. The array is unsorted. My goal is to find the existence of 1320 through one linear search, and the second linear search will check how many times the number 1320 appears. The array is a random array.
I have tried setting up a linear search that will check whether the number in the array exists. I have also tried to set up the linear search that will check how many times an array exists. Neither worked, this is my first time working with arrays so I am not sure if I am even doing them correctly
public static void main(String[] args) {
// Finish adding Code
boolean DoesItExist;
int iHowMany;
final int SIZE = 10000, ENTRY = 1320;
int[] NumArray = new int[SIZE];
OwenHeading.getHeader("Assignment 9: Arrays.");
fillTheArray(NumArray, SIZE);
System.out.println("DONE");
}
public static void fillTheArray(int[] iTempArray, int SIZE) {
final int RANGE = 2500;
Random rand = new Random();
for (int index = 0; index <= SIZE - 1; index++)
iTempArray[index] = rand.nextInt(RANGE);
}
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
boolean TempDoesItExist;
return TempDoesItExist;
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
return HowManyExist;
}
public static void programOutput(boolean TempDoesItExist, int TempHowMany) {
if (TempDoesItExist)
System.out.println("does");
// Cool, you found the number 1320
else
System.out.println("does not");
// Dang, you didn't find the number 1320
}
}
I am not asking for the exact answer, just some help that will get me going into the right direction. I feel like I would be able to do this project easier if I started from scratch, but my teacher wants us to use his starter project.
Initialize your boolean and counter
Bool doesItExist = false;
Int iHowManyTimes = 0;
You can check for values in arrays in java in a linear fashion like this:
for (int number : NumArray) {
if (anItemInArray == myValue) {
doesItExist = true;
return;
}
}
afterwards do it all over again and increment your counter
for (int number : NumArray) {
if (number == ENTRY) {
iHowMany += 1;
}
}
Edit: Return statement added to first loop, as there is no reason to continue after the value is found
you can modify two methods of linear search you have in this way and that is going to work :
just declare a counter and increment it each time you find your ENTRY number.
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
return true;
}
}
return false
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
HowManyExist ++;
}
}
return HowManyExist;
}
It looks like you didn't call the linear search methods. For a linear search you can just do something like the following:
found=false;
howManyCounter=0;
for (int x=0, x<array.length; x++){
if (array[x]==numberYouWant){
found=true;
howManyCounter++;
}
}
This is my recursive function to solve the N-Queens problem that asks to find the number of configurations of queens on a chess board such that they cannot attack each other. With the help of validPosition this function successfully enters the base case (curRow == N) the proper number of times for each value of N. However, I am unclear as to how to extract this information. If the function enters the base case 10 times than this function should return 10.
But, having it return boolean is the technique for conditionally branching on its recursive call. Is there a clean and consistent method to both enter the base case the correct number of times and also successfully propagate that information up to the root function call and return it to the caller?
static boolean findNQueensSolutions(int N, int curRow, int[][] board, int result) {
if (curRow == N) {
return true;
}
for (int curCol = 0; curCol < N; curCol++) {
if (validPosition(board, curRow, curCol, N)) {
board[curRow][curCol] = 1;
if (findNQueensSolutions(N, curRow + 1, board, result)) {
return true;
}
board[curRow][curCol] = 0;
}
}
return false;
}
you need to collect information about successful positions, like this:
static int findNQueensSolutions(int N, int curRow, int[][] board) {
if (curRow == N)
return 1; // found 1 position
int result = 0; // found 0 positions yet
for (int curCol = 0; curCol < N; curCol++)
if (validPosition(board, curRow, curCol, N)) {
board[curRow][curCol] = 1;
result += findNQueensSolutions(N, curRow + 1, board); // do not return immediately, maybe there are more?
board[curRow][curCol] = 0;
}
return result;
}
For my programming course I have to write recursive functions, but aside from the theoretical questions given during the classes I can't figure out how to do it with my own code.
If anyone could help me out and give me a pointer on where to start it'd be great!
The method is as follows:
public boolean hasColumn(Marble m) {
boolean hasColumn = false;
for (int i = 0; i < DIM && hasColumn == false; i++) {
int winCount = 0;
for (int j = 0; j < DIM && hasColumn == false; j++) {
if (j == 0) {
winCount = 1;
} else {
if (getField(j, i).equals(getField(j - 1, i))
&& getField(j, i).equals(m)) {
winCount++;
if (winCount == WINLENGTH) {
hasColumn = true;
}
} else {
winCount = 1;
}
}
if (!(getField(j, i).equals(m))) {
hasColumn = false;
}
}
}
return hasColumn;
}
There's a field[DIM][DIM], which stores Marbles. Marble has a Mark, which is 0-4, with 0 being empty and 1-4 being colour values. The method determines whether someone has a marble column of 5 and wins.
Input is the Marble type of a player. Output is boolean hasColumn true or false. The output value is correct, there's just no recursion.
The idea is to make it find a vertical column in a recursive way. This also has to be done with horizontal/vertical, but I figured when I get this figured out I'll manage those by myself.
Thank you in advance!
public boolean hasColumn(Marble m, int i, int j, int wincount) {
if (wincount == WINLENGTH)
return true;
if (i == DIM)
return false;
if (j == DIM)
return hasColumn(m, i + 1, 0, 0);
return hasColumn(m, i, j + 1, getField(j, i).equals(m) ? wincount + 1 : 0);
}
Depending on whether you'd like to find a line/column of elements equal to a given Marble element or rather of same value, you may call this method:
hasColumn(aMarble, 0, 0, 0);
hasColumn(getField(0, 0), 0, 0, 0);
There's a duality between certain types of recursion and iteration.
Consider that in your iterative function you are iteratinng over columns using two variables, i and j. Could you transform those local variables into parameters to the function? You would be transforming state internal to the function (local variables) into state implicit in the function call.
Looks like task sounds like:
1. We have a square matrix of Marble elements(it can be simple integers) with dimension DIM.
2. We have a method getField(int, int) return a marble from this matrix
3. We have an iterative decision to discover if this matrix has any column with equal values of marble elements
Our goal is write recursive variant of this method
So, look here. Recursive algorithm check ROW existing with same value:
public class Marble {
public static final int DIM = 10;
public int[][] marbleAr = new int[DIM][DIM];
public void init(){
for(int i=0;i<DIM;i++){
for(int j=0;j<DIM;j++){
marbleAr[i][j] = new Random().nextInt(10);
if(i == 2){
marbleAr[i][j] = 7;
}
}
}
}
public int get(int i, int j){
return marbleAr[i][j];
}
public void printMarbleAr(){
for(int i=0;i<DIM;i++){
for(int j=0;j<DIM;j++){
System.out.print(marbleAr[i][j] + " ");
}
System.out.println();
}
}
public boolean hasColumn(int val, int col, int row){
if(row == 0){
return true;
}
if(this.hasColumn(val, col, row-1)){
if(this.get(col, row) == this.get(col,row-1)){
return true;
}else{
if(col == DIM-1){
return false;
}
return this.hasColumn(val, col+1, row);
}
}
return false;
}
public static void main(String[] args) {
int v = 7;
Marble marble = new Marble();
marble.init();
marble.printMarbleAr();
System.out.println(marble.hasColumn(v, 0, DIM-1));
}
}
Your method name is hasColumn and return variable
name is hasColumn. That's BAD.
I don't see hasColumn invoked inside the method again to actually
go down to recursion path.