Please give me some pointers on why my code does not work for this assignment. My idea is to have an index (param) which is the current place in the Vector, and target (param) which is the value of the given index in the array. Then I either move up or down until reaching one of the base cases. But it donĀ“t work.
The main problem is is that it outputs wrong results only false thus far.
bool RecursivePuzzle :: SolvableReal(Vector<int> & squares, int index, int target)
{
if (target == 0 && index == squares.size() ) return true;
if (index >= squares.size()) return false;
if (index < 0) return false;
int goUp = squares[index] + index;
int goDown = squares[index] - index;
return SolvableReal(squares, goUp, squares[index]) ||
SolvableReal(squares, goDown, squares[index]);
Probably not the whole answer, but this part looks wrong:
int goUp = squares[index] + index;
int goDown = squares[index] - index;
I think it should be
int goUp = index + squares[index];
int goDown = index - squares[index];
Shouldn't your final solution state be compared to size - 1?
if (target == 0 && index == squares.size() - 1 ) return true;
Related
I'm trying to write a function which takes an array of integers & searches the part of the array between the first and last for the given value. If the value is in the array, return that position. If it is not, I want to return -1.
Here is the code for my function.
int binarySearch(int *array, int min, int max, int value) {
int guess = 0;
bool found = false;
while (!found) {
guess = ((array[min] + array[max]) / 2);
if (array[guess] == value) {
found = true;
return guess;
}
else if (array[guess] < value) {
min = guess + 1;
}
else if (array[guess] > value) {
max = guess - 1;
}
}
return -1;
}
I'm unsure how to break out of the while loop when the value you are searching for is not in the array? This is the pseudocode I am following for implementing a binary search function :
Let min = 0 and max = n-1(array size -1 ). Compute guess as the average of max and
min, rounded down (so that it is an integer).
If array[guess] equals
target, then stop. You found it! Return guess.
If the guess was too
low, that is, array[guess] < target, then set min = guess + 1.
Otherwise, the guess was too high. Set max = guess - 1.
Go back to step 2.
I think it makes sense to change what the function returns. Instead of returning guess, it should return a valid index if the item is found and -1 otherwise.
Also, you are using guess as a value and as an index. That will definitely cause problems.
guess is a value below.
guess = ((array[min] + array[max]) / 2);
guess is an index below.
else if (array[guess] < value) {
Here's my suggestion:
// Return the index if found, -1 otherwise.
int binarySearch(int *array, int first, int last, int value)
{
// Terminating condition 1.
// If first crosses last, the item was not found.
// Return -1.
if ( first > last )
{
return -1;
}
int mid = (first + last)*0.5;
// Terminating condition 2.
// The item was found. Return the index.
if ( array[mid] == value )
{
return mid;
}
// Recurse
if (array[mid] < value)
{
return binarySearch(array, mid+1, last, value);
}
else
{
return binarySearch(array, first, mid-1, value);
}
}
No need for recursion if you use a while loop, just remember to calculate guess every time, and set guess to the middle of the indexes, not their values:
int binarySearch (int *array, int first, int last, int value)
{
int guess = 0;
while (first != last || array[guess] == value) {
guess = (first + last) / 2;
if (array[guess] == value)
return guess;
else if (array[guess] < value)
last = guess + 1;
else if (array[guess] > value)
first = guess - 1;
}
return -1;
}
I would also suggest
int first = 0, last = sizeof(array) / sizeof(array[0]) - 1;
instead of passing them as arguments.
Is there way to do the following search using a faster way? The items on A array are sorted in DESC order.
int find_pos(int A[], int value, int items_no, bool only_exact_match)
{
for(int i = 0; i < items_no; i++)
if(value == A[i] || (value > A[i] && !only_exact_match))
return i;
return -1;
}
You can use std::lower_bound algorithm in your case. It performs binary search with O(log N), as other people wrote. It will be something like this:
int find_pos(int A[], int value, int items_no, bool only_exact_match)
{
const int *pos_ptr = std::lower_bound(A, A + items_no, value, std::greater<int>());
const ptrdiff_t pos = pos_ptr - A;
if (pos >= items_no)
return -1;
if (*pos_ptr != value && only_exact_match)
return -1;
return pos;
}
A binary search
int left = 0;
int right = items_no; // Exclusive
while (left < right) {
int mid = (left + right) / 2;
if (value == A[mid])
return mid;
if (value < A[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return only_exact_match ? -1 : right - 1; // The greater
Because your array is sorted, you can search in steps, akin to a bisection. First, check the midpoint against your value. If it's equal, you have your answer. If it's greater, your value is in the lower half of the array. If not, your value is on the upper half. Repeat this process by bisecting the remaining elements of the array until you find your value, or run out of elements. As for your second if clause, if no matching value is found, the closest smaller element is element i+1, if that exists (i.e. you are not at the end of the array).
A question was asked to me during an online interview.
They provided a piece of code and we have to find out a possible bug in the code.
The code is provided below as it is.
The function is provided with a non empty zero indexed vector of integers (which contains only 1 and 0).
The function will return the start position of longest sequence of 1's.
for example if the input values {0,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1} it will return 3 because the longest sequence of 1's is from position 3 to 7 total five consecutive 1's.
if the input values are {0,0,1} then it will return 2 because there is only one 1 and length of longest sequence of 1 is one.
If there are no 1's then it will return -1.
The input vector can be changed so we can't change the signature of the vector to const.
I tested this function with variable no of inputs and I found out that it is working fine.
I am not able to find out any bug in the code. But the instruction says that there is a bug in the code and we can change maximum 2 lines of code to solve the bug.
int solution(vector<int>& A) {
int n = A.size();
int i = n - 1;
int result = -1;
int k = 0;
int maximal = 0;
while (i > 0) {
if (A[i] == 1) {
k = k + 1;
if (k >= maximal) {
maximal = k;
result = i;
}
} else {
k = 0;
}
i = i - 1;
}
if (A[i] == 1 && k + 1 > maximal)
result = 0;
return result;
}
To fix UB for empty case, I add check for !A.empty(),
and I profit of that to replace i by 0 (at that point i == 0)
and to replace the check with maximal value to have a coherent result for tie:
if (!A.empty() && A[0] == 1 && k + 1 >= maximal)
And as I may change an other line, I would fix the prototype as A is not modified.
int solution(const std::vector<int>& A) {
problem specifications are that
1.vector is immutable and
2.Input vector is not empty
I tried same problem in Java but different approach to see what is missing because i cant find any bug in above code.
package javaapplication7;
/**
*
* #author Owner
*/
public class JavaApplication7 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] A={0,1,0,1,1,1,1};
System.out.println(solution(A));
}
static int solution(int A[]){
int i=0,count=0,max=0,pos=-1;
while(i<=A.length-1)
{
if(A[i]==1)
{
count++;
i=i+1;
}
else
{
i=i+1;
count=0;
}
if(count>max)
{
pos=i-count;
max=count;
}
}
if(count==0)
return pos;
else
return pos;
}
}
the given code will favor a sequence closer to the left side if two sequences are of equal length. that doesn't happen for the checking of index 0
if (A[i] == 1 && k + 1 > maximal)
should be
if (A[i] == 1 && k + 1 >= maximal)
I'm working on a Sudoku solver, and my program is having trouble recursing backwards when it has exhausted its outputs.
I have four functions that do the check:
scolumn, srow, sbox. Each one will return false if the number already exists in the column row or box respectively.
bool sudoku::solve(int row, int column)
{
if(column == 9)
{
column = 0;
row +=1;
}
if(puzzle[row][column] != 0)
{
solve(row, column + 1);
return false;
}
else
{
for(int n = 0; n < 10; n ++)
{
if(srow(column, n) && scolumn(row,n) && sbox(row, column, n)
{
puzzle[row][column] = n;
if(!solve(row, column + 1);
table[row][column] = 0;
}
}
puzzle[row][column] = 0;// if not commented out then infinite loop
}
return false
}
the problem with it is that if its at 9 and there is no next choice, it will not backtrack correctly.
There are a number of problems with your code, as people have observed in the comments.
This answer summarises some of them:
1) As #n.m. said, you should not be trying '0' as a valid choice in a cell. That will be the cause of some infinite looping, no doubt.
2) As you have observed, you don't know how the recursion finishes. The answer is that when you get to the last cell, and you find a value that works in it, you are supposed to return true. This is what is supposed to break the for(n) loop: that loop is saying "try each number until the call of solve to the right of this cell succeeds'. Success is measured by your routine returning true.
Since you try every number (n) in the current cell, no matter whether or not the call to the solve on its right works ... it's not going to work.
You'll know that you're more on the right track when:
You can see the place in your code where you return true when you discover that you can put a number in the last cell (9,9)
You can see how it is that you stop trying numbers (n=0..9) when the call to the right succeeds.
Given int puzzle[9][9], and your srow, scol, and sbox functions:
bool sudoku::solve(int row, int column) //to solve entire puzzle, call with parameters 0 and 0
{
int cell;
//ignore all nonzero cells (zero = empty)
while (row < 9 && puzzle[row][column] != 0)
{
column++;
if (column == 9)
{
row++;
column = 0;
}
}
if (row == 9) return true; //puzzle is already solved
//try values 1-9 inclusive. If successful, then return true
for (cell = 1; cell <= 9; cell++)
{
puzzle[row][column] = cell;
if (srow(row) &&
scol(column) &&
sbox(row-row%3, column-column%3) &&
solve(row, column)) //recursion!!
{
return true;
}
}
//if no value works, reset the cell and return false.
puzzle[row][column] = 0;
return false;
}
I had a homework assignment that asked for a function that uses direct recursion to find the index of the left-most, lowest, negative integer in an array. Additional requirements were for the parameters of the function to be the array and the size and that the return value for no valid value was -999.
I came up with this:
int LowIndexMinNeg(int src[], int size)
{
if (size == 0)
return -999;
int index = LowIndexMinNeg(src, size - 1);
if (index >= 0)
return (src[size - 1] < src[index]) ? (size - 1) : index;
else
return (src[size - 1] < 0) ? (size - 1) : index;
}
It works, satisfies the requirements, and got me full credit. Can this be implemented with tail recursion?
It seems to me that since you have to take the result from the recursive call to use in a comparison to decide if you pass that one on or update it that it wouldn't be possible but recursion still ties my brain in knots a it so there might be something obvious that I'm missing.
Note: My homework assignment was already turned in and graded.
If you transform the result of recursion before returning, it is not tail recursive.
EDIT: Having said that, if you want to make the function tail recursive:
const int SENTINEL= 0;
int LowIndexMinNeg(int src[], int size, int index)
{
if (size == 0)
{
if (index<0 || src[index]>=0)
return -999;
else
return index;
}
int current_index= size - 1;
int new_index= src[current_index]<=src[index] ? current_index : index;
return LowIndexMinNeg(src, size - 1, new_index);
}
And call as LowIndexMinNeg(src, src_size, src_size - 1)
EDIT2: finding the poorly termed leftmost most negative value. You can probably state that as the index of the first most negative value.
EDIT3: removing most of the conditionals, since it's easier to find the index of the lowest value, then check if it's negative.
You need to store the lowest number found so far somewhere. With your function you're using the stack
to store that.
With a tail recursive function you'll need to store the lowest number found so far elsewhere.
e.g:
As a global variable (ugh..).
As a parameter to the function itself.
As a member variable
The requirement you have for your function probably rules out all those, so you're left with something like the code you have, which cannot be written to be tail-recursive.
To get an idea of e.g. the 2 last point:
int LowIndexMinNeg(int src[], int size,int current_lowest = 0,int lowest_index = 0) {
if(size == 0)
return current_lowest == 0 ? -999 : lowest_index;
int val = src[size - 1] ;
if(val < 0 && val < current_lowest) {
current_lowest = val;
lowest_index = size -1;
}
return LowIndexMin(src,size - 1,current_lowest,lowest_index);
}
And
struct find_smallest {
int current_lowest = 0;
int lowest_index = 0
int LowIndexMinNeg(int src[], int size) {
if(size == 0)
return current_lowest == 0 ? -999 : lowest_index;
int val = src[size - 1] ;
if(val < 0 && val < current_lowest) {
current_lowest = val;
lowest_index = size - 1;
}
return LowIndexMin(src,size - 1);
}
};
Here's how you might implement that using tail recursion:
int LowIndexMinNeg(int src[], int size, int index = 0, int lowest_index = -999, int lowest_value = 0)
{
if (index >= size) {
return lowest_index;
}
if (src[index] < lowest_value) {
return LowIndexMinNeg(src, size, index+1, index, src[index]);
} else {
return LowIndexMinNeg(src, size, index+1, lowest_index, lowest_value);
}
}
This implementation uses default arguments to keep the function all together, but this makes for a messy interface. You can split this into two functions if you like:
static int LowIndexMinNegHelper(int src[], int size, int index, int lowest_index, int lowest_value)
{
if (index >= size) {
return lowest_index;
}
if (src[index] < lowest_value) {
return LowIndexMinNegHelper(src, size, index+1, index, src[index]);
} else {
return LowIndexMinNegHelper(src, size, index+1, lowest_index, lowest_value);
}
}
int LowIndexMinNeg(int src[], int size)
{
return LowIndexMinNegHelper(src, size, 0, -999, 0);
}
In this case, LowIndexMinNegHelper only needs to be a local function (which I've indicated with static above).
I might have a proposal, but of course I had to change the signature :
int LowIndexMinNeg(int src[], int size, int min = -999)
{
if (size == 0)
return min;
const int min_value = (min == -999) ? 0 : src[min];
return LowIndexMinNeg(src, size - 1, src[size - 1] <= min_value ? size - 1 : min);
}
I'm not sure whether the rules for the assignment would have permitted defining an auxiliary function, but that is one standard transformation for achieving tail recursion when the most natural signature of the operation does not permit it. For example:
int LowIndexMinNeg2(int src[], int size, int min)
{
if (size == 0) return min;
src--; size--;
if (min >= 0) min++;
if (src[0] < 0
&& (min < 0 || src[0] <= src[min]))
min = 0;
return LowIndexMinNeg2(src, size, min);
}
int LowIndexMinNeg2(int src[], int size)
{
return LowIndexMinNeg2(src + size, size, -999);
}
This version also reverses the order of traversal to make it possible to distinguish a "real" value of 'min' from the 'not found' value. Other, likely more readable, approaches would involve making use of additional accumulators for the actual minimum value (instead of only an index) and/or the current offset into the array (so that traversal can be done in "normal" order. But of course if I were coding something like this for serious use I wouldn't be using recursion in the first place.
You could do this with two statics...
int LowIndexMinNeg(int src[], int size)
{
static int _min = 0;
static int _index = 0;
if (size == 0) return -999;
if (_index == size) return (src[_min] < 0) ? _min : -999;
if (src[_index] < 0 && src[_index] < src[_min]) _min = _index;
++_index;
return LowIndexMinNeg(src, size);
}