Solving a maze in 2d array - c++

I had referred to many articles and questions that answered how to solve a maze effectively but here I want to confirm what's going wrong in my code. Consider the maze:
2 1 0 0 3
0 1 0 1 1
0 1 0 0 1
0 1 1 0 0
0 0 0 0 0
where the 1's represent the walls and 0's represent the path.(source is 2 and destination is 3).
I have to output whether there is a path or not.
int y=0;
while(y==0)
{
robo1(n,m,maze);//this function adds 2 to any '0'/'3' in (i,j+1),(i+1,j),(i-1,j),(i,j-1) (if exists),where (i,j) is 2
robo2(n,m,k2,maze);//this function adds 3 to any '0'/'2' in (i,j+1),(i+1,j),(i-1,j),(i,j-1) (if exists), where (i,j) is 3
if(find5(n,m,maze)==1)//this function returns 1 if there is '5' in the maze
y++;
if(find0(n,m,maze)==0)//this function returns 0 if there are no '0' in the maze
break;
}
if(find0(n,m,maze)==0 && y==0)
printf("-1\n");//no path
else
printf("1\n");//there is a path
My idea is that if after any number of loops a five is found in the maze, then it would mean there is a path.
But while implementing this function in code I get wrong answers and sometimes run-time errors.
Is there any flaw in the above logic?

The general idea should almost work, but of course everything is in the details.
One case in which your approach will not work even if implemented correctly is however this:
2 1 0 0 0
1 1 0 1 1
0 0 0 1 3
i.e. if both 2 and 3 are "closed" by walls but there are 0s in the room. Your loop will never end because despite having 0s around neither of the two robo function will change anything.
A simple solution is returning 0/1 from robos if they actually changed at least a value in the matrix and quitting when this doesn't happen.
Note that this is not a very efficient way of solving a maze (your code will keep checking the same cells over and over many times).

Related

Can we really avoid extra space when all the values are non-negative?

This question is a follow-up of another one I had asked quite a while ago:
We have been given an array of integers and another number k and we need to find the total number of continuous subarrays whose sum equals to k. For e.g., for the input: [1,1,1] and k=2, the expected output is 2.
In the accepted answer, #talex says:
PS: BTW if all values are non-negative there is better algorithm. it doesn't require extra memory.
While I didn't think much about it then, I am curious about it now. IMHO, we will require extra memory. In the event that all the input values are non-negative, our running (prefix) sum will go on increasing, and as such, sure, we don't need an unordered_map to store the frequency of a particular sum. But, we will still need extra memory (perhaps an unordered_set) to store the running (prefix) sums that we get along the way. This obviously contradicts what #talex said.
Could someone please confirm if we absolutely do need extra memory or if it could be avoided?
Thanks!
Let's start with a slightly simpler problem: all values are positive (no zeros). In this case the sub arrays can overlap, but they cannot contain one another.
I.e.: arr = 2 1 5 1 1 5 1 2, Sum = 8
2 1 5 1 1 5 1 2
|---|
|-----|
|-----|
|---|
But this situation can never occur:
* * * * * * *
|-------|
|---|
With this in mind there is algorithm that doesn't require extra space (well.. O(1) space) and has O(n) time complexity. The ideea is to have left and right indexes indicating the current sequence and the sum of the current sequence.
if the sum is k increment the counter, advance left and right
if the sum is less than k then advance right
else advance left
Now if there are zeros the intervals can contain one another, but only if the zeros are on the margins of the interval.
To adapt to non-negative numbers:
Do as above, except:
skip zeros when advancing left
if sum is k:
count consecutive zeros to the right of right, lets say zeroes_right_count
count consecutive zeros to the left of left. lets say zeroes_left_count
instead of incrementing the count as before, increase the counter by: (zeroes_left_count + 1) * (zeroes_right_count + 1)
Example:
... 7 0 0 5 1 2 0 0 0 9 ...
^ ^
left right
Here we have 2 zeroes to the left and 3 zeros to the right. This makes (2 + 1) * (3 + 1) = 12 sequences with sum 8 here:
5 1 2
5 1 2 0
5 1 2 0 0
5 1 2 0 0 0
0 5 1 2
0 5 1 2 0
0 5 1 2 0 0
0 5 1 2 0 0 0
0 0 5 1 2
0 0 5 1 2 0
0 0 5 1 2 0 0
0 0 5 1 2 0 0 0
I think this algorithm would work, using O(1) space.
We maintain two pointers to the beginning and end of the current subsequence, as well as the sum of the current subsequence. Initially, both pointers point to array[0], and the sum is obviously set to array[0].
Advance the end pointer (thus extending the subsequence to the right), and increase the sum by the value it points to, until that sum exceeds k. Then advance the start pointer (thus shrinking the subsequence from the left), and decrease the sum, until that sum gets below k. Keep doing this until the end pointer reaches the end of the array. Keep track of the number of times the sum was exactly k.

How do I generate all vectors of size n where each element may contain 1 of m different values?

Sorry if this is a duplicate, but I did not find any answers which match mine.
Consider that I have a vector which contains 3 values. I want to construct another vector of a specified length from this vector. For example, let's say that the length n=3 and the vector contains the following values 0 1 2. The output that I expect is as follows:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
2 0 0
2 0 1
2 0 2
2 1 0
2 1 1
2 1 2
2 2 0
2 2 1
2 2 2
My current implementation simply constructs for loops based on nand generates the expected output. I want to be able to construct output vectors of different lengths and with different values in the input vector.
I have looked at possible implementations using next_permutation, but unfortunately passing a length value does not seem to work.
Are there time and complexity algorithms that one can use for this case? Again, I might have compute this for up to n=17and sizeof vector around 6.
Below is my implementation for n=3. Here, encis the vector which contains the input.
vector<vector<int> > combo_3(vector<double>enc,int bw){
vector<vector<int> > possibles;
for (unsigned int inner=0;inner<enc.size();inner++){
for (unsigned int inner1=0;inner1<enc.size();inner1++){
for (unsigned int inner2=0;inner2<enc.size();inner2++){
cout<<inner<<" "<<inner1<<" "<<inner2<<endl;
unsigned int arr[]={inner,inner1,inner2};
vector<int>current(arr,arr+sizeof(arr)/sizeof(arr[0]));
possibles.push_back(current);
current.clear();
}
}
}
return possibles;
}
What you are doing is simple counting. Think of your output vector as a list of a list of digits (a vector of a vector). Each digit may have one of m different values where m is the size of your input vector.
This is not permutation generation. Generating every permutation means generating every possible ordering of an input vector, which is not what you're looking for at all.
If you think of this as a counting problem the answer may become clearer to you. For example, how would you generate all base 10 numbers with 5 digits? In that case, your input vector has size 10, and each vector in your output list has length 5.

How to find and return a repeating sequence within a vector

I have a vector that is filled dynamically and will always contain a repeating sequence with characters and length that I am unsure of. For example, the vector could contain these elements:
0 1 1 2 3 1 0 1 1 2 3 1 0 1 1 2
and the repeating sequence in that vector is:
0 1 1 2 3 1
How can I search the vector and find those elements. I would like to put the found sequence in a new vector. I assumed at first it would only take a simple for loop and checking for repetition of the first and second element in the array, so in the case above I would exit the loop when I reached 0 1 a second time, but the problem is that it cannot be assumed that the first 2 elements will be in the repeating pattern, so
0 1 2 3 2 3 2 3 2 3
can be valid elements in the vector. Any ideas?
in general (infinite result) it is impossible to know the sequence because something like that can happen 1 million 0 and then 1,after 1000 zero u will think that the sequence is zero only,but if the vector is finite
you can write somethink like that
for(I..VECTORSIZE / 2)
if(VECTORSIZE % I == 0)
CHECK IF SUBVECTOR(0,I) == SUBVECTOR(I,I*2) == SUBVECTOR(I*2,I*3)....
return I
else continute;

Distance span between two binary strings

Is there any way of finding efficiently (bitwise operations) the distance (not Hamming Distance!) of two 8-bit binary strings?
Each byte is guaranteed to have only one bit set.
Like:
a=0 0 0 0 0 0 0 1
b=0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 1 -> distance = 3
^^^^^
------
a=0 0 0 0 0 1 0 0
b=0 1 0 0 0 0 0 0
0 1 0 0 0 1 0 0 -> distance = 3
^^^^^
------
a=0 1 0 0 0 0 0 0
b=0 0 0 0 0 0 1 0
0 1 0 0 0 0 1 0 -> distance = 4
^^^^^^^
I could work with something like logarithms but that is not very efficient
"Efficient" can mean a different things here: e.g., asymptotic vs performance for a known range of inputs; time vs space; etc.
I'll assume you care about raw speed for the small bounded inputs you describe.
Baseline approach. Take the smaller bit, and left shift it until it's equal to the larger bit, counting shifts. While this is O(n), that sort of analysis doesn't matter here since n is bounded.
You might compare that baseline to either of the following approaches, which have better time complexity but may or may not be faster for your inputs.
Alternative 1. Put all the distances in a lookup matrix. O(1) time complexity, but O(n^2) space complexity.
Alternative 2. Have a lookup table for the logarithms, and return the difference log2(a) - log2(b), where a >= b. O(1) time complexity, O(n) space complexity. (Note that I'm assuming that dist(a, a) = 0, which is a off-by-one from what you describe above.)
I don't know in practice which of those will be faster, but the main point is not to assume that O(n) means that the algorithm is slower in absolute terms for your inputs.
You can use OR operation (logical summing) and then find a maximum amount of zeros, which goes one by one. Hope i get your question right.

iterate through a 3d matrix, finding all solutions

iterate through a 3d matrix
i need to check every possible solution to a certain predicament.
i have a matrix[x][y][z] that represents possible nodes to travel through. I already finished a method that should give me a set of solutions (it disables a single path every iteration and recalculates the entire solution, disable priority is based on travel capacity of the last solution)
but i need to see how effective my method is in terms of total time taken to calculate a set. For this i require a method calculate the solution on every permutation of these paths.
currently it only has a single layer in between 2 main layers (L1) where 0 is a free path and 1 is a non accessible path.
This here is the starting layout where i can toggle the values on layer L1 from 0 to 1 to disable a path and the basis of my shortest path search algorithm.
L0 0 0 0 0 0 L1 0 1 0 1 0 L2 0 0 0 0 0
0 1 0 1 0 1 1 1 1 1 0 1 0 1 0
0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
0 1 0 1 0 1 1 1 1 1 0 1 0 1 0
0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
how can i iterate through every possible combination of disabling the free paths when the dimensions of the matrix are non constant (meaning they are already user defined on compile time and can be changed whenever)? there are 2^n solutions where n is the number of free path on all mediary layers.
(a quick explanation in C or C++ would be best, even pseudo code is good) since there currently 9 free path to make combinations with there should be about 2^9 solutions which i need to test with. I havent done any brute force algorithms before so i have no idea how to make one.