Find all paths of length L in 2 D grid in C++ - c++

I'm trying to find all paths of length L in a 2-D grid(forgetting boundaries for the moment) by calling route(string s) recursively and appending to the stringth.
'l' stands for left
'r' stands for right
'd' stands for down
and
'u' stands for up
My logic is correct I think. I need to call route(string s) recursively with each of these values and append to s.
I can see the flaw in my code but cannot think of a way to correct it. I am changing the value of string s by appending to it 'r','l','u' or 'd' at each call but since successive calls are in the same scope, i get garbage answers and not the permutations of u,l,d,r that I am expecting.
#include <iostream>
#include <vector>
using namespace std;
void route(string s, int k);
int main(void){
string result="";
route("",5);
}
void route(string initial, int k){
if(initial.length()>5){
cout<<initial<<endl;
cout<<"Length of initial:"<<initial.length();
return;
}
for(int i=0;i<4;i++){
switch(i){
case 0:
{
initial.append("r");
route(initial);
}
case 1:
{
initial.append("l");
route(initial);
}
case 2:
{
initial.append("u");
route(initial);
}
case 3:
{
initial.append("d");
route(initial);
}
}
}
}

There is no need to change initial, just pass the new string to route. e.g.
route(initial + "u",k-1);
Note that you aren't using the k value currently, and you also aren't recursing for the r and l cases.
One more thing - a for loop with a switch in it for each different case, is a strange construction. Why not just call the 4 different options one after the other?
route(initial + "l",k-1);
route(initial + "r",k-1);
route(initial + "u",k-1);
route(initial + "d",k-1);

Related

How to memoize or make recursive function with no apparent pattern?

Consider the following code, it was done for the Codeforces Round #731 (Div. 3), problem B https://codeforces.com/contest/1547/problem/B
In short, you are given a string and you are supposed to check if it's possible to create that string by sequentially adding letters in alphabetical order in either the front to the back of a string that starts empty.
Ex. the string "bac", you would first make the empty string be "a", then it can be either "ba" or "ab", then we try again and we get that based on the last result it now can be "bac", "cba", "abc", "cab". We get that is possible so we return true.
We can only do this procedure up to 26 times.
My code would make a tree, grabbing a base string as the head, and two children nodes, one with the letter added to the front and one with the letter added to the back, if neither worked out, then I would repeat it again with the children nodes.
I rewrote my solution and sent a completely different one, but I still wanted to know if there was a way to optimize so it could actually be executed. The code works if n is around 14 or 15, it stutters a little bit but can finish; but once it goes to 20 it will not even finish.
#include <iostream>
#include <string>
using namespace std;
bool solve(string fs,string s = "", int n = 0){
if(s == fs){
return true;
}
if(n > 26 || s.size() > fs.size()){
return false;
}
if(solve(fs,s+(char)(96+n+1),n+1) ||solve(fs,(char)(96+n+1)+s,n+1)){
return true;
}
return false;
}
int main(){
int t;cin>>t;
for(int i = 0; i < t; i++){
string p;
cin>>p;
if(solve(p)){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
}```
You are doing brute force approach which is time complexity of n * 2^n. And it looks pretty reasonable to fail(TLE) when n is around 20 (taking into account that t is up to 10000)
I cannot come up with a way for efficient memoization, however this problem can easily be solved with greedy approach. You don't have to check all the combinations. Check out the official editorial

Edit string by calling it using concatenation in C++

I'm a very new C++ user (and a new StackOverflow user at that), and I'm trying to code a very basic Tic-Tac-Toe (Naughts and Crosses) game. I'm not sure how to render the board as it is updated.
My main question is if it is possible to call a string using concatenation. I have an array set up that indexes the states of the 9 spaces of the board using a 0 for empty, a 1 for an X, and a 2 for an O. If I set up 9 variables in a user-defined renderBoard() function named bit1, bit2, etc; Can I call them this way:
void renderBoard()
{
int i = 1;
string bit1;
string bit2;
string bit3;
string bit4;
string bit5;
string bit6;
string bit7;
string bit8;
string bit9;
while (i < 10)
{
if (Spaces[i] = 0)
{
(bit + i) = * //This is the main bit I'm wondering about
}
else
{
//Check for 1, 2, and edit the string bits accordingly
}
++i;
}
//Put all of the strings together, as well as some more strings for adding the grid
//Output the whole concatenated string to the command line
}
If anyone knows of a better way to do this, please let me know. I've tried Googling and rifling through various C++ help websites, but I find it difficult to express my particular case through anything other than a long-winded and specific explanation.
Thanks for you help!!
If I correctly understood your problem, your problem is that you want to access the strings named bit1, bit2, etc using a variable i like bit + i.
And no, you cannot do that!
It will throw a compile time error.
Please correct me if I didn't get what you are looking for.
But one question is still in my mind that why are you using string variables bit1, bit2 etc?
I think you just want to store single digit value in those strings. If this is the case, you can just use a single string of length 9.
You can do this as follows:
int i = 0; //because string indices start from 0 and also array indices.
string bit(9, ' '); //declare a string of length 9 with default value of a space (you can modify it with your default value)
while (i < 9) { // i < 9 because highest index will be 8
if (Spaces[i] == 0) {
bit[i] = '*';
} else {
}
++i;
}
Declaring 9 variables like this is apparently wrong. What you are looking for is an array.
std::array<std::string, 9> bits;
(You need #include <array> and #include <string>.)
Then, you can traverse the string using a for-loop: (in C++, arrays are indexed starting from zero, not one)
for (std::size_t i = 0; i < 9; ++i) {
// operate on bits[i]
}
In the for-loop, you can use the subscript operator to access the element: bits[i].
Finally, to put all the strings together, use std::accumulate:
std::accumulate(bits.begin(), bits.end(), std::string{})
(You need #include <numeric>.)

R G B element array swap

I'm trying to create this c++ program to perform the description below. I am pretty certain the issue is in the recursive, but uncertain how to fix it. I'm guessing it just keeps iterating through to infinity and crashes. I do not even get an output. I figured I could just compare the previous and current pointer and perform a 3-piece temp swap based on lexicography. I would use a pointer to iterate through the array and decrement it after each swap, then recursively call with that ptr as the parameter. Didn't work, I'm here, help me please :). If there is a simpler solution that would work too, but prefer to understand where I went wrong with this code.
#include <string>
#include <iostream>
using namespace std;
// Given an array of strictly the characters 'R', 'G', and
// 'B', segregate the values of the array so that all the
// Rs come first, the Gs come second, and the Bs come last.
// You can only swap elements of the array.
char* RGBorder(char* c_a)
{
size_t sz = sizeof(c_a)/sizeof(*c_a);
char* ptr_ca = c_a;
char* prv_ptr = ptr_ca;
ptr_ca++;
char temp;
while(*ptr_ca)
{
switch(*ptr_ca)
{
case 'R' :
if( *prv_ptr < *ptr_ca ) {
temp = *prv_ptr; *prv_ptr = *ptr_ca; *ptr_ca = temp;
} else if( *prv_ptr == *ptr_ca ) {
continue;
} else { ptr_ca--; RGBorder(ptr_ca); }
case 'G' :
if( *prv_ptr < *ptr_ca ) {
temp = *prv_ptr; *prv_ptr = *ptr_ca; *ptr_ca = temp;
} else if( *prv_ptr == *ptr_ca ) {
continue;
} else { ptr_ca--; RGBorder(ptr_ca); }
default:
ptr_ca++;
continue;
}
ptr_ca++;
cout << *ptr_ca;
}
return c_a;
}
int main()
{
char ca[] = {'G', 'B', 'R', 'R', 'B', 'R', 'G'};
char *oca =RGBorder(ca);
char *pca = oca;
while(*pca)
{
cout << *pca << endl;
pca++;
}
}
There are many issues with your code.
1) You call the function RGBorder with a character pointer, and then attempt to get the number of characters using this:
size_t sz = sizeof(c_a)/sizeof(*c_a);
This will not get you the number of characters. Instead this will simply get you the
sizeof(char *) / sizeof(char)
which is usually 4 or 8. The only way to call your function using a char array is either provide a null-terminated array (thus you can use strlen), or you have to pass the number of characters in the array as a separate argument:
char *RGBorder(char *c_a, int size)
2) I didn't go through your code, but there are easier ways to do a 3-way partition in an array. One popular algorithm to do this is one based on the Dutch National Flag problem.
Since you want the array in RGB order, you know that the series of G will always come in the middle (somewhere) of the sequence, with R on the left of the sequence, and B always on the right of the sequence.
So the goal is to simply swap R to the left of the middle, and B to the right of the middle. So basically you want a loop that incrementally changes the "middle" when needed, while swapping R's and B's to their appropriate position when they're detected.
The following code illustrates this:
#include <algorithm>
char *RGBorder(char *c_a, int num)
{
int middle = 0; // assume we only want the middle element
int low = 0; // before the G's
int high = num - 1; // after the G's
while (middle <= high)
{
if ( c_a[middle] == 'R' ) // if we see an 'R' in the middle, it needs to go before the middle
{
std::swap(c_a[middle], c_a[low]); // swap it to a place before middle
++middle; // middle has creeped up one spot
++low; // so has the point where we will swap when we do this again
}
else
if (c_a[middle] == 'B') // if we see a 'B' as the middle element, it needs to go after the middle
{
std::swap(c_a[middle], c_a[high]); // place it as far back as you can
--high; // decrease the back position for next swap that comes here
}
else
++middle; // it is a 'G', do nothing
}
return c_a;
}
Live Example
Here is another solution that uses std::partition.
#include <algorithm>
#include <iostream>
char *RGBorder(char *c_a, int num)
{
auto iter = std::partition(c_a, c_a + num, [](char ch) {return ch == 'R';});
std::partition(iter, c_a + num, [](char ch) {return ch == 'G';});
return c_a;
}
Live Example
Basically, the first call to std::partition places the R's to the front of the array. Since std::partition returns an iterator (in this case, a char *) to the end of where the partition occurs, we use that as a starting position in the second call to std::partition, where we partition the G values.
Note that std::partition also accomplishes its goal by swapping.
Given this solution, we can generalize this for an n-way partition by using a loop. Assume we want to place things in RGBA order (4 values instead of 3).
#include <algorithm>
#include <iostream>
#include <cstring>
char *RGBorder(char *c_a, int num, char *order, int num2)
{
auto iter = c_a;
for (int i = 0; i < num2 - 1; ++i)
iter = std::partition(iter, c_a + num, [&](char ch) {return ch == order[i];});
return c_a;
}
int main()
{
char ca[] = "AGBRRBARGGARRBGAGRARAA";
std::cout << RGBorder(ca, strlen(ca), "RGBA", 4);
}
Output:
RRRRRRRGGGGGBBBAAAAAAA
Sorry to put it blunt, but that code is a mess. And I don't mean the mistakes, those are forgivable for beginners. I mean the formatting. Multiple statements in one line make it super hard to read and debug the code. Short variable names that carry no immediate intrinsic meaning make it hard to understand what the code is supposed to do. using namespace std; is very bad practise as well, but I can imagine you were taught to do this by whoever gives that course.
1st problem
Your cases don't break, thus you execute all cases for R, and both G and default for G. Also your code will never reach the last 2 lines of your loop, as you continue out before in every case.
2nd problem
You have an endless loop. In both cases you have two situations where you'll end up in an endless loop:
In the else if( *prv_ptr == *ptr_ca ) branch you simply continue; without changing the pointer.
In the else branch you do ptr_ca--;, but then in default you call ptr_ca++; again.(Note that even with breaks you would still call ptr_ca++; at the end of the loop.)
In both cases the pointer doesn't change, so once you end up in any of those conditions your loop will never exit.
Possible 3rd problem
I can only guess, because it is not apparent from the name, but it seems that prv_ptr is supposed to hold whatever was the last pointer in the loop? If so, it seems wrong that you don't update that pointer, ever. Either way, proper variable names would've made it more clear what the purpose of this pointer is exactly. (On a side note, consistent usage of const can help identify such issues. If you have a variable that is not const, but never gets updated, you either forgot to add const or forgot to update it.)
How to fix
Format your code:
Don't use using namespace std;.
One statement per line.
Give your variables proper names, so it's easy to identify what is what. (This is not 1993, really, I'd rather have a thisIsThePointerHoldingTheCharacterThatDoesTheThing than ptr_xy.)
Fix the aforementioned issues (add breaks, make sure your loop actually exits).
Then debug your code. With a debugger. While it runs. With breakpoints and stepping through line by line, inspecting the values of your pointers as the code executes. Fancy stuff.
Good luck!
just count the number of 'R', 'G' and 'B' letters and fill the array from scratch.
much easier, no recursions.

Run-time error when using vectors to convert given expression into polish notation

My program aim is to convert given mathematical expression into polish notation.
Mathematical expression is stored in vectors and recursion is used.
I am getting run time error when compiling it.
Using debugger it shows segmentation fault (SIGSEGV).
It is assumed that input is of the form (a+b) and corresponding output should be ab+. (brackets mandatory)
Actually it is this problem of SPOJ.
My approach is as follows -
Use vectors to store expression
If expression size is greater than 1
then remove brackets which are always present at end of string using pop_back and vector::erase .
divide the vector into three parts - string 1 , operator and string 2 (string 1 and string 2 are vectors )
simplify vectors string 1 and string 2 to their polish notation using recursion
Clear original vector passed to function and add string 1 , operator and string 2 to it.
change() is used to accomplish all these things
Here is my program which converts a single statement to it's polish notation.
#include <iostream>
#include <vector>
void convert(std::vector <char> &vect)
{
if(vect.size()!=1&&vect.size()!=0)
{
vect.pop_back();
vect.erase(vect.begin());
std::vector<char> str1;
std::vector<char> str2;
char op;
int i=0;
int reqcount = 0;
while(1)
{
if(vect[i]=='(')
reqcount++ ;
if(vect[i]==')')
reqcount-- ;
str1.push_back(vect[i]);
if(!reqcount)
break;
i++;
}
op=vect[i];
while((i+1)!=vect.size())
{
str2.push_back(vect[i+1]);
i++;
}
vect.clear();
convert(str1);
convert(str2);
for(int i=0; i<str1.size(); i++ )
{
vect.push_back(str1[i]);
}
vect.push_back(op);
for(int i=0;i<str2.size();i++)
{
vect.push_back(str2[i]);
}
}
}
int main( void )
{
std::vector<char> testinput;;
char c;
std::cin>>std::noskipws;
while(std::cin>>c&&c!='\n')
testinput.push_back(c);
convert(testinput);
for(int i=0;i<testinput.size();i++)
std::cout<<testinput[i];
return 0;
}
You start with int i = 0 which will point to the overall brackets (). It will read the entire string as str1 minus the closing ')'. op will be ')' if I'm not mistaking and str2 will remain empty.
Then you recursively call 'convert(str1)' which doesn't have a closing braket so you'll try to go past the end of the array and get your SIGSEGV.
Make sure your split works correctly and double-check the boundary conditions to prevent it.
P.S. Your solution is O(N^2). You can do O(N).

Generating lexicographic permutations: Segmentation fault

I have this code to generate lexicographic permutations. The following logic is used:
Start from the increasing order arrangement of the chars in a given test string.
To generate next lexicographic permutation:
a) find the rightmost character which is smaller than its next character. SAY A.
b) to the right of A, find the next larger character. SAY B. and swap A & B.
c) to the right of the original position of A, sort characters in an increasing order.
Algorithm ends when we get the last permutation. i.e. reverse of given test string.
my test string s = "0123456789"
Edit:
On every single run of the program, i get a separate position of segmentation fault.
to get A:
int firstchar(string s){
int pos = s.length()-2;
for(int i=pos;i>=0;i--){
if(s[i]<s[i+1]){
pos = i;
break;
}
}
return pos;}
to get B and then recursive approach (qsort is a function from <cstdlib>):
int ceilchar(string s, int fc){
int ceil = fc+1;
int diff=27;
for(int i=ceil;i<s.length();i++){
if(s[i]>s[fc] && s[i]-s[fc]<diff){
ceil = i;
diff = s[i]-s[fc];
}
}
return ceil;}
starting func:
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
if(s!="9876543210"){
cout<<s<<"\n";
nextpermute(s);
}
else
cout<<s<<"\n";}
call from main: nextpermute(test);
If the test string is "01234567" or anything smaller than this, it works well. but if it is a string like
"012345678" or "0123456789" , then i get segmentation faults.
Please help!!
I suspect your stack size is crossing its limit. If you are running it on Linux, do "limit" and see your stacksize. There are two ways to avoid this situation
1) (Not Recommended) Do "limit stacksize unlimited" (only if you are on unix based system). And run the program again.
2) (Recommended).
Change
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
if(s!="9876543210"){
cout<<s<<"\n";
nextpermute(s);
}
else
cout<<s<<"\n";
}
to
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
cout <<s<<"\n";
}
and modify your main function as
int main()
{
string s = "0123456789";
while (s != "9876543210")
{
nextpermute(s);
}
}
Above change will do away with the recursion of "nextpermute" and hence your stacksize limit will never be crossed