I've been stuck on this thing for a while, I just can't wrap my head around it. For a homework, I have to produce an algorithm for a sudoku solver that can check what number goes in a blank square in a row, in a column and in a block. It's a regular 9x9 sudoku and I'm assuming that the grid is already printed so I have to produce the part where it solves it.
I've read a ton of stuff on the subject I just get stuck expressing it.
I want the solver to do the following:
If the value is smaller than 9, increase it by 1
If the value is 9, set it to zero and go back 1
If the value is invalid, increase by 1
I've already read about backtracking and such but I'm in the early stage of the class so I'd like to keep it as simple as possible.
I'm more capable of writing in pseudo code but not so much with the algorithm itself and it's the algorithm that is needed for this exercise.
Thanks in advance for your help guys.
Seeing as it's homework, I believe I can point you in the general direction.
To start, keep a two-dimensional array (or a data structure that can represent the grid), and keep track of the values that can go there. Let's say it's a class named "possibilities":
public class Possibilities {
//Keep track of the numbers possible internally, with an accessor
}
The way sudoku works, there will usually be a square with only a single answer (in some cases, this won't be available, which means you need to potentially make a copy of the data and play out a little bit, or have a way to roll back). Simply put, fill in the answer, and then iterate over the adjacent squares to remove the freshly put number as a possibility (And check those squares simultaneously as new potential answers).
I think the easiest algorithm for solving a sudoku puzzle is a complete search. That is, trying every single combination until you find one that works. The easiest way to implement this is recursively. I know you don't want to get involved in backtracking, but I actually think that would be the easiest way for you to write this algorithm.
Assume you already have an algorithm that checks whether n can go in some cell at (i, j) in your board. This means that n does not violate any of the constraints (there can only be one number from 1 .. 9 in each row, column and box). This should not be too hard, you just have to loop through the row, column and box that contains cell (i, j) and make sure that n does not appear yet.
Then, you will have a recursive function called solve() that will return true if it finds a solution, otherwise it will return false. The function will constantly place numbers in empty cells of the sudoku board (only if they don't violate the constraints, which we assume you already write an algorithm for) until it is filled. Once filled, the puzzle is solved. You know that the board is valid because you've been checking the validity of every number you place on the way there. If no number can be placed at any point, it will backtrack by returning false.
The pseudocode for solve will look something like this:
boolean solve()
if the board is filled
return true
for each cell that is not empty
for n = 1 .. 9
if n does not exist in this row, column and box
place n in this cell
if solve()
return true
remove n from this cell
return false
Related
I'm new in programming and I'd like some help for an assignment, I only need a little clue to help me getting started (no answer, I only want to get a direction of how to do it then work my way).
The rules of the game : on the initial square is a marker that can move to other squares along the row. At each step in the game, you may move the marker the number of squares indicated by the integer in the square it currently occupies. The marker may move either left or right along the row but may not move past either end.
The goal of the game is to move the marker to the cave, the “0” at the far end of the row. In this configuration, you can solve the game by making the following set of moves:
eg: 2 3 1 2 4 0
first: move of 2 (to the right since it's impossible to go to the left) then: either move 1 to the right or 1 to the left then: if we moved left before: move 3 to the right (cannot go 3 to the left) if we moved right before then it's either 2 to the left or 2 to the right. 2 to the right is the right answer since then the next value is 0.
I must write the program that will try all the possibilities (so using a loop or a recursive I guess?) and return TRUE if there's a solution or FALSE if there are no solution. I had to choose the data structure from a few given by the prof for this assignment and decided to use an Array Based List since the get() is O(1) and it's mainly the only method used once the arraylist is created.
My program is only missing the (static?) method that will evaluate if it's possible or not, I dont need help for the rest of the assignment.
Assume that the ArrayBasedList is already given.
Thanks for your help!
I think your idea about using a recursive method makes a lot of sense. I appreciate you don't want the full answer, so this should just give you an idea:
Make a method (that passes in an integer x of the current position and your list) that returns a boolean.
In the method, check the value of list.get(x).
If it's 0, return true.
If it's -1, return false (more on that later).
Otherwise, store the value in a variable n, replace it with a -1, and return method(x+n) || method(x-n).
What the -1 does is it eventually fills everything in the array with a value that will terminate the program. Otherwise, you could end up with an infinite loop (like if you passed in [1, 2, 4, 2, 3]) with the value going back and forth.
A couple of things to keep in mind:
You'd need to make a new copy of the array every time, so you don't keep overwriting the original array.
You'd need to incorporate a try-catch (or equivalent logic) to make sure you are not trying to measure out of bounds.
If you have any further questions, feel free to ask!
I am pretty sure that I thoroughly understand how the methods with only one recursion work.
Ex) calculating factorial
public int factorial(int n){ //factorial recursion
if(n==0){
return 1;
}
else{
return n*factorial(n-1);
}
}
For these methods, I can even picture what's going on in the stacks and what values are being returned at each stack level.
But Whenever, I encounter methods with Double Recursions, the nightmare begins.
Below is a recursion problem with double recursions from coding bat.
Ex) Given an array of ints, is it possible to choose a group of some of the ints, such that the group sums to the given target? If yes, true. If no, false.
You use 3 parameters; starting index start, An int Array nums, target int value target.
Below is the solution for this problem.
public boolean groupSum(int start, int[] nums, int target) {
if (start >= nums.length) return (target == 0);
if (groupSum(start + 1, nums, target - nums[start])) return true;
if (groupSum(start + 1, nums, target)) return true;
return false;
}
My take to understand this solution is this. Say I was given an array {2,4,8} with starting index = 0, and target value 10. So (0,{2,4,8},10) goes in through the method, the function gets re-called at
if (groupSum(start + 1, nums, target - nums[start])) return true;
so it becomes (1,{2,4,8},8) and it does over and over until start index hits
3. when it hits 3. The stack at the last level(?) goes to the second recursive call. And this is where I start losing track of what's happening.
Can anybody break this down for me? And when people use double recursion,(I know it's very inefficient and in practice, almost no one uses it for its inefficiency. But just in an attempt to understand it.)can they actually visualize what's going to happen? or do they just use it hoping that the base case and recursion would work properly? I think this applies generally to all the ppl who wrote merge sort, tower of hanoi alogrithm etc..
Any help is greatly appreciated..
The idea of a double recursion is to break the problem into two smaller problems. Once you solve the smaller problems, you can either join their solutions (as is done in merge sort) or choose one of them - which is done in your example, which only requires the second smaller problem to be solved if solving the first smaller problem didn't solve the full problem.
Your example tries to determine if there is a subset of the input nums array whose sum is the target sum. start determines which part of the array is considered by the current recursive call (when it's 0, the entire array is considered).
The problem is broken to two, since if such a subset exists, it either contains the first element of the array (in which case the problem is reduced to finding if there's a sub-set of the last n-1 elements of the array whose sum is target minus the value of the first element) or doesn't contain it (in which case the problem is reduced to finding if there's a sub-set of the last n-1 elements of the array whose sum is target).
The first recursion handles the case where the subset contains the first element, which is why it makes a recursive call that would look for the target sum minus the first element in the remaining n-1 elements of the array. If the first recursion returns true, it means that the required subset exists, so the second recursion is never called.
The second recursion handles the case where the subset doesn't contain the first element, which is why it makes a recursive call that would look for the target sum in the remaining n-1 elements of the array (this time the first element is not subtracted from the target sum, since the first element is not included in the sum). Again, if the second recursive call returns true, if means that the required subset exists.
Well if you want to visualize it, usually it's kind of like a tree. You first follow one path through the tree until the end, then step one back and pick a different path (if possible). If there is none or you are happy with your result you just take another step back and so on.
I don't know if this helps you but when I learned recursion, it helped to just think of my method as already working.
So I thought: Great, so basically my method is already working, but I can't call it with the same parameters and have to make sure I return the right value for these exact parameters by using different ones.
If we take that example:
At first we know that if we have no numbers to look at left, then the answer depends on if the target is 0. (first line)
Now what do we do with the rest? Well... we'd need to think about it for a moment.
Just think about the very first number. Under what circumstances is it part of the solution? Well that would be if you could create target-firstnumber with the rest of the numbers. Because then when you add firstnumber, you reach target.
So you try to see if that's possible. If so, it's solvable. (second line)
But if not, it's still possible that the first number just isn't important for the solution. So you have to try again to build the target without that number. (third line)
And that's basically all there is to this.
Of course to think like this you need two things:
1. You need to believe that your method already works for other parameters
2. You need to make sure your recursion terminates. That's the first line in this example but you should always think about if there is any combination of parameters that will just create an endless recursion.
Try to understand it like this: Recursion can be rewritten as a while-loop. where the condition of the while is the negation of the stop-condition of the recursion.
As already said, there is nothing called double recursion.
I'm trying to solve the above problem using Java. Thought about using for loops but I can't see how this would work without knowing X and N in advance. I'm trying to solve it with recursion but not sure how it looks. Been trying for a couple hours now. Any help is greatly appreciated.
Example, if N = 4 and x = 3, possible arrays are:
[0,0,0,1]
[2,1,0,0]
[1,2,1,1]
[0,2,2,2]
My algorithem works like counting, you start counting until X (basiclly like counting in Base X) and when you get to X you add 1 to the next position in the Array and reset the last position.
so, as far as i know you can't return few arrays in a normal way so i'll assume you want to print them.
now, this is a "nice" code:
http://pastebin.com/Uqv3fMxg
few notes:
you should not make the function static, i did it from laziness.
this is not perfect, it print twice [1,0], [2,0] and so on. couln't find the problem and it is way too late for me, i'll try to check it again tommorow.
i'm not a guy that comments his code, i did a little but i'll explain everything i can here.
The program starts in the main method where i defined the Array and started the recurtion method.
The stop statement is when i got into the N position (that doesn't exist in the array, only N-1)
The parameters: the array, the position in the array that i am corrently counting and a "mode", is it a run to go to the next position or just to print all of the number in this position.
The alreadyHas variable is ment to not print number 2 times.
if i won't use it, it would print every number atleast 2 times, it will redo any work he has done until he move to this position and every position.
it is hard to explain, you can write 0 instead of it and see what happens.
so, i count until X, every time i print the new Array and to count every number and not skiping any i have to recount the last position with a different number in the last position.
after i have count all of the possible numbers in this possition, i am giving it a value of 0 and going to the next position.
so,to sum it up, you count the number in the first position of the array, when you reach the maximum you add a carry in the next position and reset the corrent position.
I have read many variations of the Knapsack problem, but the version I am tasked with is a little different and I don't quite understand how to solve it.
I have an array of integers that represent weights (ie. {1,4,6,12,7,2}) and need to find only one solution that adds up to the target weight.
I understand the basic algorithm, but I cannot understand how to implement it.
First, what is my base case? Is it when the array is empty? The target has been reached? The target has been over-reached? Or maybe some combination?
Second, when the target is over-reached, how do I backtrack and try the next item?
Third, what am I supposed to return? Should I be returning ints (in which case, am I supposed to print them out?)? Or do I return arrays and the final return is the solution?
Think carefully about the problem you are trying to solve. To approach this problem, I am
considering the inputs and outputs of the Knapsack algorithm.
Input: A set of integers (the knapsack) and a single integer (the proposed sum)
Output: A set of integers who add up to the proposed sum, or null.
In this way your code might look like this
public int[] knapsackSolve(int[] sack, int prospectiveSum) {
//your algorithm here
}
The recursive algorithm is straightforward. First compute the sum of the sack. If it equals
prospectiveSum then return the sack. Otherwise iterate over sack, and for each item initialise a new knapsack with that item removed. Call knapsackSolve on this. If there is a solution, return it. Otherwise proceed to the next item.
For example if we call knapsackSolve({1,2,3},5) the algorithm tries 1 + 2 + 3 = 5 which is false. So it loops through {1,2,3} and calls knapsackSolve on the sublists {2,3},{1,3} and {1,2}. knapsackSolve({2,3},5) is the one that returns a solution.
This isn't a very efficient algorithm although it illustrates fairly well how complex the Knapsack problem is!
Basically the Knapsack problem is formulated as (from Wikipedia): "Given a set of items, each with a mass and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. For your problem we are interested in weights only. So you can set all values to 1. Additionally we only want to know if the target weight can be reached exactly. I guess you are allowed to use a weight only once and not multiple times?
This problem can be solved nicely with dynamic programming. Are you familiar with that principle? Applying dynamic programming is much more elegant and quicker to program than backtracking. But if you are only allowed to do backtracking use the approach from user2738608 posted above.
I'm look for the "how do you find it" because I have no idea how to approach finding the algorithm complexity of my program.
I wrote a sudoku solver using java, without efficiency in mind (I wanted to try to make it work recursively, which i succeeded with!)
Some background:
my strategy employs backtracking to determine, for a given Sudoku puzzle, whether the puzzle only has one unique solution or not. So i basically read in a given puzzle, and solve it. Once i found one solution, i'm not necessarily done, need to continue to explore for further solutions. At the end, one of three possible outcomes happens: the puzzle is not solvable at all, the puzzle has a unique solution, or the puzzle has multiple solutions.
My program reads in the puzzle coordinates from a file that has one line for each given digit, consisting of the row, column, and digit. By my own convention, the upper left square of 7 is written as 007.
Implementation:
I load the values in, from the file, and stored them in a 2-D array
I go down the array until i find a Blank (unfilled value), and set it to 1. And check for any conflicts (whether the value i entered is valid or not).
If yes, I move onto the next value.
If no, I increment the value by 1, until I find a digit that works, or if none of them work (1 through 9), I go back 1 step to the last value that I adjusted and I increment that one (using recursion).
I am done solving when all 81 elements have been filled, without conflicts.
If any solutions are found, I print them to the terminal.
Otherwise, if I try to "go back one step" on the FIRST element that I initially modified, it means that there were no solutions.
How can my programs algorithm complexity? I thought it might be linear [ O(n) ], but I am accessing the array multiple times, so i'm not sure :(
Any help is appreciated
O(n ^ m) where n is the number of possibilities for each square (i.e., 9 in classic Sudoku) and m is the number of spaces that are blank.
This can be seen by working backwards from only a single blank. If there is only one blank, then you have n possibilities that you must work through in the worst case. If there are two blanks, then you must work through n possibilities for the first blank and n possibilities for the second blank for each of the possibilities for the first blank. If there are three blanks, then you must work through n possibilities for the first blank. Each of those possibilities will yield a puzzle with two blanks that has n^2 possibilities.
This algorithm performs a depth-first search through the possible solutions. Each level of the graph represents the choices for a single square. The depth of the graph is the number of squares that need to be filled. With a branching factor of n and a depth of m, finding a solution in the graph has a worst-case performance of O(n ^ m).
In many Sudokus, there will be a few numbers that can be placed directly with a bit of thought. By placing a number in the first empty cell, you give up on a lot of opportunities to reduce the possibilities. If the first ten empty cells have lots of possibilities, you get exponential growth. I'd ask the questions:
Where in the first line can the number 1 go?
Where in the first line can the number 2 go?
...
Where in the last line can the number 9 go?
Same but with nine columns?
Same but with the nine boxes?
Which number can go into the first cell?
Which number can go into the 81st cell?
That's 324 questions. If any question has exactly one answer, you pick that answer. If any question has no answer at all, you backtrack. If every question has two or more answers, you pick a question with the minimal number of answers.
You may get exponential growth, but only for problems that are really hard.