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.
Related
How do I create a function that has an array of integers and the array's length as parameters that will return true if the sum of the array elements is even and false otherwise?
How would I do this without using any static variables?
I've tried making a code that will check if,
current is odd and previous is even will return false recursively, else will return true recursively, this idea is based on the mathematical axiom that only even plus odd is equal to odd, every other combination is even.
public static boolean q3(int[] arr, int index) {
if (index == 0) {
return arr[index] % 2 == 0;
}
if (arr[index] % 2 == 0) {//if current is even
if (!q3(arr, index - 1)) {//even plus odd = odd
return false;
} else
return true; //every other combo equal true
} else if (q3(arr, index - 1)) {//if current is odd
return true;
} else {
return false;
}
}
I wrote 2 versions, one with recursion, other with no recursion
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
int[] arr={5, 3, 1};
System.out.println("sum of "+Arrays.toString(arr)+" is " + size_ispair_rec(arr, arr.length));
}
public static boolean size_ispair_rec(int[] arr, int size){
if(size-1 == 0){
return arr[size]%2==0;
}
return !((arr[size-1]%2 == 0) ^ size_ispair_rec(arr, size-1));
}
public static boolean size_ispair(int[] arr, int size){
int sum=0;
for(int i=0; i<size; ++i){
sum+=arr[i];
}
return sum%2 == 0 ? true : false;
}
}
Here is a recursive method that does the job. I've tried to keep the code readable.
The idea is that the only time you get an even number by addition is when
Both the numbers are even
Both the numbers are odd
At every recursive call, we check if adding the number to the previous calculated value makes it even or odd.
public static boolean isSumEven(int arr[], int length){
if(length == 0){
return true;
} else {
boolean sumPreviousElemsEven = isSumEven(arr, length - 1);
boolean currentElemEven = arr[length-1]%2 == 0 ? true : false;
if(sumPreviousElemsEven && currentElemEven || !sumPreviousElemsEven && !currentElemEven){
return true;
} else {
return false;
}
}
}
I am trying to write a 2048 game in java. I am trying to make it so it checks if the board has been changed, and if it was changed it will add to the move counter and add a number to the board. Otherwise it should not do anything. I am running into a bug where the method that checks if it was changed returns true every time and I can't seem to figure out why.
This is my isChecked method which should return true if the board has been changed and false otherwise.
public boolean isChanged(int [][]copy,int [][]orig){
if(copy.length!=orig.length){
System.out.print("INVALID MOVE");
return false;
}
for(int i=0;i<copy.length;i++){
for(int j=0;j<copy[i].length;j++){
if(copy[i][j]!=orig[i][j]) {
System.out.print("INVLAID MOVE");
return false;
}
}
}
System.out.println("VALID MOVE");
moves++;
return true;
}
Below are the method that handle left movement, combination, etc. the ones for up down and right are basically the same just with minor changes to change the direction so I decied not to include them in this post as I did not feel they were necessary
public void shiftLeft() {
for (int x = 0; x < board.length; x++) {
for (int y = board[x].length-1; y>0; y--) {
if (board[x][y -1] == 0 && board[x][y] != 0) {
board[x][y - 1] = board[x][y];
board[x][y] = 0;
if(y!=board[x].length-1)
y+=1;
}
}
}
}
public void combineLeft() {
for (int x = 0; x < board.length; x++) {
for (int y =board[x].length-2; y >=0; y--) {
if(board[x][y]==board[x][y+1]){
board[x][y]*=2;
board[x][y+1]=0;
}
}
}
}
public void left(){
int [][] copy=board.clone();
shiftLeft();
shiftLeft();
combineLeft();
shiftLeft();
if(isChanged(copy,board)==true)
addNum();
}
addNum() is simply a function that adds a number to a random empty position on the board. board is the class variable(these are all in the same class) which is a 2d int array which represents the game board.
Check the ischanged function. You are returning false if the corresponding values are not equal. Actually that means you are returning false if the board is not changed.
Or just do this:
if(copy[i][j]==orij[i][j]) //here I just replaced “!=“ with “==“
return false;
Also like #Talik said use deep copy
try using:
Arrays.copyOf(..)
I think clone just copies the reference on the arrays of the board into a new array. So every time you change board, you change the clone
other options are as seen here:
How to clone a multidimensional array in java?
a deep copy method
public static int[][] deepCopyIntMatrix(int[][] input) {
if (input == null)
return null;
int[][] result = new int[input.length][];
for (int r = 0; r < input.length; r++) {
result[r] = input[r].clone();
}
return result;
}
and cloning each row in the array manually
I have an array of numbers: S= {4,5} and I want to check if this group creates the sum = 13.
In this case, yes: 4 + 4 + 5 = 13
Another example: s={4,5}, sum = 6 -> no
I wrote a recursive function to solve this:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
}
But this function works only for 2 numbers in the array.
I need to write a recursive function that will deal with N numbers, like {4,9,3} or {3,2,1,7} etc.
I'm not sure how can I do this? How can I call a recursion N times, according to the length of the array? Or maybe I should change my algorithm completely?
Also - I'm not allowed to use loops.
return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
You can generalize this with a loop like this:
for (int i = 0; i < s.length; ++i) {
if (isSumOf(s,n-s[i])) return true;
}
return false;
But, since you can't use loops, you can write the equivalent loop as another recursive method:
boolean withoutLoop(int [] s,int n, int i) {
if (i >= s.length) return false;
return isSumOf(s,n-s[i]) || recurse(s, n, i+1);
}
and then call it like so from your isSumOf method:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return withoutLoop(s, n, 0); // Change here.
}
Or, if you want to write it more concisely:
return (n == 0) || (n < 0 && withoutLoop(s, n, 0));
Break the problem down:
Sum the numbers
Is the sum equal to 13?
Then think of a way to express summing an array as recursive task; e.g. Sum of elements 1 to N is element 1 + Sum of elements 2 to N.
Finally, turn that idea / expression into code.
For any recursion problem, use the template:
ResultType recursiveMethod(params) {
if( /* this is the simplest case */ ) {
return answer for the simplest case
} else {
partialResult = solve part of the problem
resultForRest = recursiveMethod(rest of problem)
}
}
Particularly for list processing, this becomes:
if(list is empty) {
return solution for an empty list
} else {
r = call self recursively for tail of list
return solution for head of list combined with r
}
(Where "head" is the first item, and "tail" is the rest. Tail may be empty.)
For your problem, the simplest case is an empty array:
if(s.length == 0) {
return n == 0;
}
For the else, the "part of the problem" is s[0] and the "rest of the problem" is s[1] onwards.
...
} else {
int head = s[0];
int[] tail = Arrays.copyOfRange(s,1,s.length-1);
return isSumOf(tail, n - head);
}
The code would be cleaner (and probably more efficient) if you used a List instead of an array directly, because you could then use List.subList() instead of copyOfRange().
You could also pass the whole array each time, along with an extra parameter indicating how much of the array has already been accounted for.
This should work:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
for (int x: s) {
if (isSumOf(s, n-x)) {
return true;
}
}
return false;
}
UPDATE:
Oh! no loop, only recursion, you will need an extra argument:
public static boolean isSumOf(int [] s,int n)
{
if(n == 0)
return true;
if(n < 0)
return false;
return isSum2(s, n, 0);
}
public static boolean isSum2(int [] s,int n,int i)
{
if (i >= s.length)
return false;
return isSumOf(s,n-s[i]) || isSum2(s,n,i+1);
}
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;
}
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.