The exercise:
Build a recursion(with no loops) that every cell that you go inside is the number of steps that you can go, it could be right/left until you get to the last cell. if you can't get to the last cell return false, else return true.
you must start from index 0.
My problem: I build the program, it's not working, ,i am able to get to last cell but in the output i get false, i understand why i get false but i don't know how to fix it.
Test:
public static void main(String[] args)
{
// Q - isWay
System.out.println("\nTesting Question 3\n==================");
int[] a1 = {2,4,1,6,4,2,4,3,5};
System.out.println("a = {2,4,1,6,4,2,4,3,5}");
System.out.println("Ex14.isWay(a) is: " + Ex14.isWay(a1)); //need to return true
int[] a2 = {1,4,3,1,2,4,3};
System.out.println("a2 = {1,4,3,1,2,4,3}");
System.out.println("Ex14.isWay(a2) is: " + Ex14.isWay(a2));//need to return false
}
public class Ex14
{
public static boolean isWay(int[] a)
{
int i = 0;
if(a.length <= 1)
return false;
return isWay(a , 0);
}
public static boolean isWay(int[] a,int i)
{
int temp1 , temp2;
if(i == a.length-1)
return true;
if(!((a[i]+i < a.length) && (i-a[i] >= 0))) // can't go right and left
return false;
else if(a[i] > 0)
{
if(a[i]+i < a.length) // go right
{
temp1 = a[i] + i;
a[i] = -1;
return isWay(a, temp1);
}
else if (i-a[i] >= 0) // go left
{
temp2 = i - a[i];
a[i] = -1;
return isWay(a, temp2);
}
}
return false;
}
}
Your condition for returning false is wrong.
if(!((a[i]+i < a.length) && (i-a[i] >= 0)))
should be
if(!((a[i]+i < a.length) || (i-a[i] >= 0)))
You want to return false if you can't proceed either left or right. Your condition tests whether you can't proceed both left and right.
EDIT:
My original suggested fix wasn't enough, since your method must be able to back-track if you reach a dead end.
Here's an alternative approach:
public static boolean isWay(int[] a,int i) {
int temp1 , temp2;
if(i == a.length-1) {
return true;
}
boolean found = false;
if(a[i]+i < a.length && a[a[i]+i] > 0) { // go right
temp1 = a[i] + i;
a[i] = -1;
found = isWay(a, temp1);
if (!found) {
a[i] = temp1 - i; // must restore a[i] to its original value, in order
// to be able to go left
}
}
if (!found && i-a[i] >= 0 && a[i - a[i]] > 0) { // go left
temp2 = i - a[i];
a[i] = -1;
found = isWay(a, temp2);
}
return found;
}
The idea is that if you can go both left and right, and going right leads to a dead end, you must try to go left when the recursive call for going right returns.
This returns true for both {1,4,3,6,1,2,4,3} and {2,4,1,6,4,2,4,3,5}.
I didn't get what you want to do but here is an example of a recursive function that effective && all booleans in an array
public static boolean recurse(boolean[] ary)
{
if (ary.length == 1) {
return ary[0];
}
return ary[0] && recurse(Arrays.copyOfRange(ary, 1, ary.length));
}
Test :
public static void main(String[] args)
{
boolean[] ary = { true, true, true, true, true};
System.out.println(recurse(ary));
boolean[] ary2 = { true, true, false, true, true};
System.out.println(recurse(ary2));
}
True
False
I hope that help you to resolve your problem else you can explain more what you want to do with this function
This is how i solved it:
public static void main(String[] args)
{
int[] a = { 2, 4, 1, 6, 4, 2, 4, 3, 5 };
System.out.println(isWay(a)); // true
int[] a1 = { 1, 4, 3, 1, 2, 4, 3 };
System.out.println(isWay(a1)); // false
}
public static boolean isWay(int[] a)
{
return isWay(a, 0);
}
private static boolean isWay(int[] a, int i)
{
if (i == a.length - 1) // if we are in the last index
return true;
if (i >= a.length || i < 0) // boundaries
return false;
if (a[i] == -1) // if marked return false to prevent infinite recursion..
return false;
int temp = a[i]; // mark where we already have been...
a[i] = -1;
boolean r1 = isWay(a, i + temp); // we are trying to move right
boolean r2 = isWay(a, i - temp); // we are trying to move left
a[i] = temp; // revert changes
return r1 || r2;
}
Related
This is all about the famous NQueens problem. My program works fine (backtrack approach). It finds all the solutions for a given board size.
Code is shown below.
I'm trying to modify the code so that I can find all the solutions for a given column of the first queen. I don't want to change the position of first queen. For an example it will provide me with the solution of
[2, 0, 3, 1, 4] and [2, 4, 1, 3, 0]
when I set the first queen at 2, board size 5 (third column, index starts from zero).
I tried this by setting different values for k (and board[k] as well) but doesn't quite reach the goal.
Any hints will be appreciated.
Here is my code. Removed details about place method since it shouldn't be changed to achieve my new goal.
public class NQueensAllSolutions
{
// Board size
static int size = 8;
// One dimensional array to store the column number for all queens.
static int[] board = new int[size];
// This method will check the validity for a new queen. works fine.
static boolean place(int k)
{
.
.
}
public static void main(String[] args)
{
int k;
long t=0; // for counting total found solutions
k = 0;
board[k] = -1;
while(k >= 0) {
board[k]++;
while(board[k] < size && !(place(k))) board[k]++;
if(board[k] < size) {
if(k == size-1) { // a solution is found.
t++;
//System.out.println("\n\nTotal: "+t+" --> "+Arrays.toString(board));
}
else {
k++; board[k] = -1;
}
}
else {
k--; // backtrack.
}
}
System.out.println("\n\nTotal: "+t);
}
}
Just keep k greater than 0 in the while loop:
import java.util.Arrays;
public class Queens
{
static int size = 5;
static int[] board = new int[size];
static boolean isValid(int k)
{
int c1 = board[k];
int c2 = board[k];
for(int r=k-1;r>=0;r--)
{
c1--;
c2++;
if(board[r] == board[k] || board[r] == c1 || board[r] == c2)
return false;
}
return true;
}
public static void main(String[] args)
{
int t = 0;
// Set the first queen position
board[0] = 2;
int k = 1;
board[k] = -1;
// k must stay greater than 0
while(k >= 1) {
board[k]++;
while(board[k] < size && !isValid(k))
board[k]++;
if(board[k] < size) {
if(k == size-1) {
t++;
System.out.println("Solution "+t+" --> "+Arrays.toString(board));
}
else {
k++;
board[k] = -1;
}
}
else {
k--;
}
}
}
}
Output:
Solution 1 --> [2, 0, 3, 1, 4]
Solution 2 --> [2, 4, 1, 3, 0]
UPDATE
Here is a generalized version that can force a queen at position (fixedRow, fixedCol).
The key change is the new getNextCol() method, which is used to get the next possible column for a queen. On row fixedRow, the only possible column is fixedCol. On the other rows, all columns are possible.
import java.util.Arrays;
public class Queens
{
static int size = 5;
static int fixedRow = 2;
static int fixedCol = 0;
static int[] board = new int[size];
static boolean isValid(int k)
{
int c1 = board[k];
int c2 = board[k];
for(int r=k-1;r>=0;r--)
{
c1--;
c2++;
if(board[r] == board[k] || board[r] == c1 || board[r] == c2)
return false;
}
return true;
}
static int getNextCol(int k, int col)
{
if(k == fixedRow) {
// Only one possible move on this row
return col == -1 ? fixedCol : size;
}
else {
// Try the next column
return col+1;
}
}
public static void main(String[] args)
{
int t = 0;
int k = 0;
board[k] = -1;
while(k >= 0) {
board[k] = getNextCol(k, board[k]);
while(board[k] < size && !isValid(k))
board[k] = getNextCol(k, board[k]);
if(board[k] < size) {
if(k == size-1) {
t++;
System.out.println("Solution "+t+" --> "+Arrays.toString(board));
}
else {
k++;
board[k] = -1;
}
}
else {
k--;
}
}
}
}
Output:
Solution 1 --> [1, 3, 0, 2, 4]
Solution 2 --> [4, 2, 0, 3, 1]
Everything I have tried so far divides the code by 2 and it does it twice for some reason.
CSP-ARRAY
An array inhabitant represents cities and their respective populations. For example, the following arrays shows 8 cities and their respective populations:[3, 6, 0, 4, 3, 2, 7, 1]Some cities have a population of 0 due to a pandemic zombie disease that is wiping away the human lives. After each day, any city that is adjacent to a zombie-ridden city will lose half of its population.Write a program to loop though each city population and make it lose half of its population if it is adjacent (right or left) to a city with zero people until all cities have no humans left.
package Arrays;
public class Project {
public static void main(String[] args){
int i = 0;
boolean hi = false;
boolean hi1 = false;
boolean hi2 = false;
boolean hi3 = false;
boolean hi4 = false;
boolean hi5 = false;
boolean hi6 = false;
boolean hi7 = false;
int[] a = {3, 6, 0, 4, 3, 2, 7, 1};
if(a[0]==0) {
hi=true;
}
if(a[1]==0) {
hi1=true;
}
if(a[2]==0) {
hi2=true;
}
if(a[3]==0) {
hi3=true;
}
if(a[4]==0) {
hi4=true;
}
if(a[5]==0) {
hi5=true;
}
if(a[6]==0) {
hi6=true;
}
if(a[7]==0) {
hi7=true;
}
int z=1;
while(hi!=false || hi1!=false || hi2!=false || hi3!=false || hi4!=false || hi5!=false || hi6!=false || hi7!=false) {
if(hi=true){
a[1]=a[1]/2;
}
if(hi1=true){
a[0]=a[0]/2;
a[2]=a[2]/2;
}
if(hi2=true){
a[1]=a[1]/2;
a[3]=a[3]/2;
}
if(hi3=true){
a[2]=a[2]/2;
a[4]=a[4]/2;
}
if(hi4=true){
a[3]=a[3]/2;
a[5]=a[5]/2;
}
if(hi5=true){
a[4]=a[4]/2;
a[6]=a[6]/2;
}
if(hi6=true){
a[5]=a[5]/2;
a[7]=a[7]/2;
}
if(hi7=true){
a[6]=a[6]/2;
}
System.out.println("Day "+i+": ["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+"] ");
i++;
}
}
}
I think it is pretty simple. Just go through the array and check previous and next value.
public static void calc(int[] arr) {
for(int i = 1; i < arr.length; i++)
if(arr[i] > 0 && arr[i - 1] == 0)
arr[i] /= -2;
for(int i = arr.length - 2; i >= 0; i--)
if(arr[i] < 0)
arr[i] = -arr[i];
else if(arr[i] > 0 && arr[i + 1] == 0)
arr[i] /= 2;
}
I am also new to Java, but here is my attempt.
import java.util.Arrays;
public class Project {
public static void main(String[] args) {
int[] a = {3, 6, 0, 4, 3, 2, 7, 1};
zombieApocalypse(a);
}
public static void zombieApocalypse(int[] array) {
boolean keepGoing = true;
int j = 1;
while (keepGoing) {
int[] arrayCopy = array;
//first element
if (array[0] == 0) {
arrayCopy[1] = array[1] / 2;
}
//element in the middle
for (int i = 1; i < array.length - 1; i++) {
if (array[i] == 0) {
arrayCopy[i - 1] = array[i - 1] / 2;
arrayCopy[i + 1] = array[i + 1] / 2;
}
}
//last element
if (array[array.length - 1] == 0) {
arrayCopy[array.length - 1] = array[array.length - 1] / 2;
}
System.out.println("Day " + j);
//copies clone back to original array
array = arrayCopy;
System.out.println(Arrays.toString(array));
j++;
int counter = 0;
//for each element checking if every city is zero
for (int element : array) {
counter = counter + element;
}
//if each element value in every city is zero, we stop
if (counter == 0) {
keepGoing = false;
}
}
}
}
This is what you were going for.
import java.util.Arrays;
public class Project {
public static void main(String[] args) {
int i = 0;
boolean hi = false;
boolean hi1 = false;
boolean hi2 = false;
boolean hi3 = false;
boolean hi4 = false;
boolean hi5 = false;
boolean hi6 = false;
boolean hi7 = false;
int[] a = {3, 6, 0, 4, 3, 2, 7, 1};
//the line of code below this comment is never used ever, what is it for?
int z = 1;
while ((((!hi || !hi1) || (!hi2 || !hi3)) || (!hi4 || !hi5)) || (!hi6 || !hi7)){
if (hi) {
a[1] = a[1] / 2;
}
if (hi1) {
a[0] = a[0] / 2;
a[2] = a[2] / 2;
}
if (hi2) {
a[1] = a[1] / 2;
a[3] = a[3] / 2;
}
if (hi3) {
a[2] = a[2] / 2;
a[4] = a[4] / 2;
}
if (hi4) {
a[3] = a[3] / 2;
a[5] = a[5] / 2;
}
if (hi5) {
a[4] = a[4] / 2;
a[6] = a[6] / 2;
}
if (hi6) {
a[5] = a[5] / 2;
a[7] = a[7] / 2;
}
if (hi7) {
a[6] = a[6] / 2;
}
System.out.println("Day " + i + Arrays.toString(a));
i++;
/*if you want to update the boolean values after they are changed, then you have to include it within the block of code
that is changing it. (if they are outside of this block of code, how will they ever update?)
*/
if (a[0] == 0) {
hi = true;
}
if (a[1] == 0) {
hi1 = true;
}
if (a[2] == 0) {
hi2 = true;
}
if (a[3] == 0) {
hi3 = true;
}
if (a[4] == 0) {
hi4 = true;
}
if (a[5] == 0) {
hi5 = true;
}
if (a[6] == 0) {
hi6 = true;
}
if (a[7] == 0) {
hi7 = true;
}
}
}
}
For each day iteration, you find the cities that have 0 population and push those indices to an array and let's name this array "indices". Then loop through this array and divide the population half only neighbor of these indices. I write in javascript.
const inhabitants = (Arr) => {
let day = 0;
let A = Arr;
// allEqual checks if the all elements in array is 0
// when allEqual is true loop is over
const allEqual = (arr) => arr.every((v) => v === arr[0]);
while (!allEqual(A)) {
// find the array[i]= 0 and push the "i" in indices
let indices = [];
for (let i = 0; i < A.length; i++) {
if (A[i] === 0) {
indices.push(i);
}
}
// just divide the neighbor elements of element 0
for (let j = 0; j < indices.length; j++) {
if (indices[j] > 0) {
A[indices[j] - 1] = Math.floor(A[indices[j] - 1] / 2);
}
if (indices[j] + 1 < A.length) {
A[indices[j] + 1] = Math.floor(A[indices[j] + 1] / 2);
}
}
day++;
console.log(`population on day ${day}`, A);
}
};
How i can check if all elements in the arrays are even or odd?
For the evens I try with this:
public boolean isEvens(int[] array) {
for (int i = 0; i<array.length;i++) {
if ( i % 2 == 0) {
return true;
}
else {
return false;
}
}
}
But there is error......
Thnx in advance !
You should check the array elements, not the array indices.
You shouldn't return true before checking all the elements of the array.
You can use a counter to count the number of odds or evens, or a boolean to determine if there are any odds or evens.
For example:
public boolean allEven(int[] array) {
for (int i = 0; i<array.length; i++) {
if (array[i] % 2 != 0) {
return false;
}
}
return true;
}
To check whether all are even or all are odd:
public boolean allEvenOrAllOdd(int[] array) {
boolean hasOdd = false;
boolean hasEven = false;
for (int i = 0; i<array.length; i++) {
if (array[i] % 2 == 0) {
hasEven = true;
if (hasOdd) { // has both odds and evens
return false;
}
} else {
hasOdd = true;
if (hasEven) { // has both odds and evens
return false;
}
}
}
return true; // either all elements are odd or all elements are even
}
Since java 8 it's a good practice to reduce code by using lambdas:
For even:
return Arrays.stream(array).allMatch( i -> i % 2 == 0);
for odd:
return Arrays.stream(array).allMatch( i -> i % 2 == 1);
Just check for an odd element, if not present then all are even.
public boolean isEvens (int[] array){
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 != 0) {
return false;
}
}
return true;
}
You want to be comparing array elements at index i, and not i itself.
The check should be if (array[i] % 2 == 0)
Use Below code to for reference use a[i]
public static void isEvens() {
int [] array = {1,2,3,4,5};
for (int i = 0; i<array.length;i++) {
if (array[i] % 2 == 0) {
System.out.println("Even");
}
else {
System.out.println("Odd");
}
}
I would recommend using recursion for it, because with recursion the run time will be less than with loops, also it's some lines of code.
I made a code for doing this but with c#, I will post it below, it might help you, because the syntax in java is so similar to the syntax of c#.
public static bool isAllEvens(int[] a, int index)
{
if (index == 0 && a[index] % 2 == 0) return true;
else
{
if (a[index] % 2 == 0)
return true && isAllEvens(a, index - 1);
return false;
}
}
And to call this function just call it with two parameters(array, and array.length - 1 which is the last index).
Here is an example for calling this function:
int[] a = new int[4];
a[0] = 8; a[1] = 4; a[2] = 8; a[3] = 8;
Console.WriteLine(isAllEvens(a, a.Length - 1));
I have a Long array with these numbers:
long[] = {1,2,3,5,6,7};
Notice that 4 is missing.
What's the best way to test this array if any such gaps exist or not?
If you're guaranteed that arrays is ordered without any duplicate then you could check that in O(1)
I think this code should work in this specific case :)
//assume that given array is ordered and has no duplicated value
long[] myarray = {5,6,7}; //no gap
long[] myarray1 = {1,2,4}; //has gap
long[] myarray2 = {10,11,12,13,14,15}; //no gap
//return true if has gap
//return false if no gap
//throw null-pointer if empty
public static boolean checkIfHasGap(long[] array) {
if (array.length == 0) {
throw new NullPointerException("Given Array is empty");
} else {
return array[0] + array.length != array[array.length - 1] + 1;
}
}
public static boolean hasGaps(long[] array) {
if (array == null || array.length == 0) {
return false;
}
if (array[array.length - 1] - array[0] + 1 != array.length) {
return true;
}
for (int i = 1; i < array.length; i++) {
if (array[i] != array[i - 1] + 1) {
return true;
}
}
return false;
}
This method first check for the "easy" cases, then iterate the array to check the more complex cases.
Loop through the array and check, if the current item is exactly x more than the current index, where x is the first element in your array.
public boolean hasGaps(long[] array) {
if(array == null || array.length == 0) {
return false;
}
long start = array[0];
for(int i = 0; i < array.length; i++) {
if(array[i] != i + start) {
return true;
}
}
return false;
}
A simpler and reliable way:
const getMissingNumbers = (list) => {
if (!list || list.length === 0) return [];
const missing = [];
// sort the list
list.sort((a, b) => a - b);
// pin start and end points in the list
const step = list[0];
const last = list[list.length - 1];
for (let i = step; i < last; i++) {
if (list.indexOf(i) === -1) missing.push(i);
}
return missing;
}
This the question I must answer-
Given an array of ints, return true if the value 3 appears in the array exactly 3 times, and no 3's are next to each other.
haveThree({3, 1, 3, 1, 3}) → true
haveThree({3, 1, 3, 3}) → false
haveThree({3, 4, 3, 3, 4}) → false
This is my solution:
public boolean haveThree(int[] nums) {
int count = 0;
for (int i=0;i<nums.length-1;i++) {
if (nums[i] == 3 && nums[i+1] ==3) {
return false;
}
else
if ((nums[i]==3 && nums[i+1]!=3)||(nums[i]==3 && nums[i+1]!=3)) {
count ++;
}
}
return count ==3;
}
It fails for some tests. For example {3,1,3,1,3} should result in true being returned; however, false is returned and I can't figure out why.
You need to loop all the way to nums.length to count all occurences. Also, there is no need for the else statement. I would do something like:
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
if ((i < nums.length - 1) && (nums[i + 1] == 3)) {
return false;
}
count++;
}
}
It fails for that example because you don't check the last index, presumably to fix the out of bounds error for checking if two 3's are next to eachother. Also the or condition in your second if statement is redundant.
public boolean haveThree(int[] nums) {
int count = 0;
for (int i=0;i<nums.length-1;i++) {
if (nums[i] == 3 && nums[i+1] ==3) {
return false;
}
if ((nums[i]==3)) { //removed redundant condition and doesn't need to be an else
count ++;
}
}
// check the last index, you've already ensured the second to last is not also a 3
if(nums[nums.length-1] == 3) {
count++;
}
return count == 3;
}
Because you're not comparing the final value, you can't tell if the last array element is a three or not. What I would do (to guarantee going through each element as needed) is add a flag boolean that lets you know if the previous value was a three or not (resetting it back to false if the current value is not three).
My example:
public boolean haveThree(int[] nums) {
int count = 0;
boolean flag = false;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 3) { // The current value is a 3
if(flag) { // Previous value was a 3, rejecting.
return false;
}
else { // We have another 3, set the flag
count++;
flag = true;
}
}
else { // Since this wasn't a 3, we can set the flag back to false
flag = false;
}
}
return count == 3;
}
The for statement also has another form designed for iteration through Collections and arrays, and can be used to make your loops more compact and easy to read.
boolean haveThree(int[] nums) {
int count = 0, prevNum = 0;
for (int i : nums){
if (i==3) {
count++;
if (prevNum == i)
return false;
}
prevNum = i;
}
return count == 3;
}
As some people have already pointed out, you are not counting all the 3s that are present in the array. Your loop ends just before the last element in order to avoid ArrayIndexOutOfBoundsException.
It is a logical error. Your code fails for the test case that you've mentioned because first if condition returns false when i = 0. I wrote the following code snippet when I practiced. Hope it helps.
public boolean haveThree(int[] nums) {
int threeCount = 0;
boolean successive3s = false;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 3) {
threeCount++;
}
if (nums[i] == 3 && (i + 1) < nums.length && nums[i + 1] == 3)
successive3s = true;
}
return (!successive3s && threeCount == 3);
}
public boolean haveThree(int[] nums) {
int count = 0;
if(nums.length >= 1 && nums[0] == 3)
count++;
for(int i = 1; i < nums.length; i++) {
if(nums[i - 1] == 3 && nums[i] == 3)
return false;
if(nums[i] == 3)
count++;
}
return count == 3;
}
I made a trailing counter for mine.
public boolean haveThree(int[] nums)
{
//We check to see if it is possible to get 3 without being in a row.
//In this case, it is the smallest at five chars
//E.G 31313, so if we have any size less than this, we know it to be false.
if (nums.length >= 5)
{
//Create a counter to track how many 3's we have in a row,
//as well as how many we have total.
int counterInRow = 0;
int counterThrees = 0;
//Check for 3's
for (int i = 0; i < nums.length; i++)
{
//If a number is 3, we increment both;
if (nums[i] == 3)
{
counterInRow++;
counterThrees++;
}
//Otherwise, we reset the amount in a row to 0;
else
{
counterInRow = 0;
}
//If we have 2 or more in a row, we return false.
if (counterInRow >= 2)
{
return false;
}
}
//Return if the amount of the counterThrees equals 3 or not.
return (counterThrees == 3);
}
//If we have less than 5 characters, it isn't possible. We then,
//Return false;
else
{
return false;
}
}