Backtracking algorithm crashes with hard cases (C) - c

I am actually making an algorithm that takes as an input a file containing tetriminoses (figures from tetris) and arranges them in smallest possible square.
Still I encounter a weird problem :
The algorithm works for less than 10 tetriminoses (every time) but start crashing with 11, 12... (I concluded that it depends on how complicated the solution is, as it finds some 14 and 15 solutions).
But the thing is, if I add an optimisation flag like -Ofast (the program is written in C) it works for every input I give him no matter how much time it takes (sometimes more than a hour..).
First I had a lot of leaks (I was using double linked list) so I changed for an Int Array, no more leaks, but same problem.
I tried using the debugger but it makes no sense (see picture) :
Debugger says my variables do not exist anymore but all I do is increment or decrement them.
For this example it just stopped while everything is fine (values of variables are correct)
Here is the link of my main function (the one that do the backtracking):
https://github.com/Caribou123/fillitAG/blob/master/19canplace/solve.c
The rest of program (same repository) consist of functions to put tetriminoses in my array, remove them from it, or print the result.
Basically I try placing a tetri, if I have enough space, I place the next one, otherwise I remove the last one and place it to the next available position etc..
Also I first thought that I were trying to place something outside of the Array, so now my Array is way bigger than it should be and filled with -1 for invalid cases (so in the worst case I just rewrite a -1), 0 for free ones, and integers values from 1 to 26 for figures.
The fact that the program works with the flag -Ofast really troubles me, as the algorithm seems to work perfectly, what could cause my program to crash ?
Here is how I tracked the number of recursions, by adding two static variables
And here is the output
(In case you want to test it yourself, use the 19canplace folder, and compile with : gcc *.c libft/libft.a)
Thanks in advance for your time,
Artiom

Related

Multithreading in C with CLion (Windows)

I have a section of code which is really time-consuming (~2s), and can be executed without the last one have finished.
for (x = last; x <= end && !found; x++) {
found = combine(combinaciones, x, end, &current);
}
Note that combine() it's the function I was talking about. But before the loop starts again (this for it's inside another loop) all the functions must have finished.
Also, combine() receives some arguments, combinaciones it's a pointer, and current an integer (by reference). The integer gets modified over time (and must get modified on the other active functions) and combinaciones it's a linked list (size of which is current-1). The 2nd and 3rd argument are just integers. The return it's a boolean that terminates the loop, but I don't matter if they make some extra operations.
I stress the importance of current. If current is equal to 5, combinaciones's 5th element will be the created, and then current will be 6. I mean that if two functions are allocating memory they souldn't allocate to the same position.
If that can't be done I can make the operations in parallel, and then allocate the memory on the main().
So, I started searching about multithreading and I found <pthread.h>, but it only worked on Linux (not on CLion). I found something caled fork, I don't know either if can be used. Would you tell me a Windows multithreading API, with an example, and the CLion implementation?
The code is huge and I don't think that would help a lot, with I have said should be enought. However, if something is unclear let me know. The code itself it's published on GitHub, but the (few) comments it has are in Spanish.
Thanks for your help!
Using Wsl (as #Singh said) I could use pthread.h. Then I just adapted my code. A very annoying bug that I had was that "IDs" (current variable) were assigned non-continuously (the first thread had "3", and the second one had "2"). I was able to fix it by using a global variable (pthread_mutex_t) and pthread_mutex_lock(), pthread_mutex_unlock(). For more information you can still check my code on GitHub.

How do I generate a string array in MatLab 2016b? [duplicate]

When trying to run my code, for example
for ii= 1:10
output(ii)=rand(3);
end
I get the error
In an assignment A(:) = B, the number of elements in A and B must be the same
or
In an assignment A(I) = B, the number of elements in B and I must be the same.
What does this error mean? What is the approach to get rid of it?
This error comes because you are trying to fill a variable chunk with more (or less) values than its size. In other words, you have a statement A(:)=B on where size(A(:)) is different to size(B).
In the example in the question, rand(3) returns a 3x3 matrix, however, output(ii) is just a single value (even if output may be bigger, output(ii) is just a single value of output), thus the value returned by rand(3) does not fit inside output.
In order to solve this problem, you need to change the the size of the output variable, so you have space to fit all the result.
There are 2 ways of doing this. One of them is by creating a Matrix that fits the return, e.g. output=zeros(3,3,10).
Then we can change the code to
for ii= 1:10
output(:,:,ii)=rand(3);
end
Alternatively, you can fill the output as a cell array. This is particularly useful when the return of the function changes sizes each time, e.g. rand(ii);
In that case, the following would work
for ii= 1:10
output{ii}=rand(ii);
end
It is probable that unlike in the example in the question, in the real case you do not know the size of what the output returns, thus you do not know which of the two options to use to fix your code.
On possible way of learning that, is activating debugging help when the code errors, by typing dbstop if error in your command line. This will trigger a debugging stop when MATLAB throws an error, and you can type size(rand(ii)) and size(output(ii)) to see the sizes of both.
Often, reading the documentation of the function being used also helps, to see if different sizes are possible.
That said, the second option, cell arrays, will always ensure everything will fit. However matrices are generally a faster and easier to use in MATLAB, thus you should aim for the matrix based solution if you can.

Value in C variable disappears

I have a C program that is giving me trouble. It is a plugin for the X-Plane flight simulator. You can view the whole code here. The basic function is pulling some information from curl, running and recording information about a flight, and then finally compiling a report of the flight.
The problem is that there is one variable that is misbehaving. I declare it at the beginning of the code because it is needed across multiple functions.
char fltno[9];
The content is set using a plugin function to get the value from a text box. It takes the value from the FltNoText widget, 8 characters long, and assigns it to the fltno variable.
XPGetWidgetDescriptor( FltNoText, fltno, 8);
I build some messages using the following method that include the fltno variable.
messg = malloc(snprintf(NULL, 0, "Message stuff %s", fltno) + 1);
sprintf(messg, "Message stuff %s", fltno);
This works just fine throughout the running of the program. Right up until the last time it is needed. This is the section that begins with:
if (inParam1 == (long)SendButton)
This will run at the end. When running this section, the fltno variable returns no text. There are many other variables which I am using in the same way, and they all seem to work fine. I ran the program over a short flight and it worked fine, but the two times I have run it on a longer flight, the variable has returned blank in that section.
Let me know if I need to explain more. You can probably tell I haven't written much C so suggestions are appreciated.
More Info
It was suggested that the adjacently decalared variables could be overflowing into fltno.
The Ppass[64] variable is copied from Ppass_def, which is set in the code and is definitely smaller than 64.
strcpy(Ppass, Ppass_def);
The tailnum[41] variable is read from a plugin function.
XPLMGetDatab( tailnum_ref, tailnum, 0, 40 );
Both of these variables are set at the beginning of the program, so it doesn't make sense that fltno only misbehaves at the very end.
Update 1
Thanks for the comments. As suggested by rodrigo, I replaced the longest malloc/sprintf instance with calls to some functions. Not sure if what I did is what you had in mind, but it seems to work at least as well as it did before. You can see the new code on the Github link.
I also did more testing and narrowed down a bit where the problem could be. The fltno variable is fine when run the last time at line 1193, but by the end of the case at line 1278, it is blank. I will try to do more testing later to narrow it down further.
Update 2
After more testing I narrowed it down to line 1292. Before that line the fltno is fine, after that it becomes blank.
strcpy(INlon, dlon);
The dlon variable is declared within the if statement where the switch is.
char dlon[12];
This variable is set every time that section runs, so it's strange that there are no problems until the end. It's set from a function that takes the decimal degrees latitude or longitude and returns a string like "N33 45.9622".
strcpy(dlon, degdm(lon, 1));
The INlon variable is declared at the beginning of the program, and this is the only time it is set.
char INlon[12];
Any ideas about why this part messes up the fltno variable?
Update 3
Thanks for the suggestions about strncpy and an alternative to the double sprintf calls. I changed a few other things and it seems to work now, I will do a full test later to be sure.
A key part that I really should have caught before now is that the latitude/longitude strings were only 12 long, which is too short. When the longitude is over 100 degrees, the string could be "W100 22.5678", which is 12 characters. This caused the end NULL to be cut off and was the source of some of my problems.
char INlat[13];
I noticed this when I was getting something like "W100 22.5678ABC1234" from those variables, where "ABC1234" is the fltno variable.
I used a pointer for dlat to avoid size problems, and use strncpy to make sure to not spill over to other variables.
strncpy(INlat, dlat, sizeof(INlat));
Finally, I found the asprintf function to replace the double instances of sprintf. I understand this won't work on all systems but it's a simple fix for now.
char * purl = NULL;
asprintf(&purl, "DATA1=%s&DATA2=%s", DATA1v1, DATA2);
So thanks for your help in fixing my code (assuming that it's working now). I feel like I knew enough to be able to fix it (once I was pointed in the right direction) but I'm still not sure exactly what was going on. If anyone wants to post an explanation of what was going wrong (as far as you can tell) I would be happy to accept an answer.

Is printing a char* faster than printing a char one at a time?

I have to write a simple program in C that prints to the standard output triangle with two equal edges for given number n. Meaning that for n=3 the output would be:
x
xx
xxx
Now I'm supposed to do two version of this program:
1. Memory conservative.
2. Time conservative.
Now I'm not entirely sure, but I think that the first version would just print x one at a time, and the second would expand the char table one at a time and then print it.
But is printing a char* faster than printing multiple single chars?
You may not be able to observe but building the entire string in memory and then printing it at once is definitely faster in theory. Reason being you will be making less calls to printf function. Each time you call a function there are multiple things that happen in the background like pushing all the current method variables and current location to stack and popping them back after returning.
However as I mentioned you may not be able to observe this difference for smaller inputs because the time needed for each of these operations are small unless you use a computer from 1960s.

To find all possible permutations of a given string

This is just to work out a problem which looks pretty interesting. I tried to think over it, but couldn't find the way to solve this, in efficient time. May be my concepts are still building up... anyways the question is as follows..
Wanted to find out all possible permutation of a given string....... Also, share if there could be any possible variations to this problem.
I found out a solution on net, that uses recursion.. but that doesn't satisfies as it looks bit erroneous.
the program is as follows:-
void permute(char s[], int d)
{
int i;
if(d == strlen(s))
printf("%s",s);
else
{
for(i=d;i<strlen(s);i++)
{
swap(s[d],s[i]);
permute(s,d+1);
swap(s[d],s[i]);
}
}
}
If this program looks good (it is giving error when i ran it), then please provide a small example to understand this, as i am still developing recursion concepts..
Any other efficient algorithm, if exists, can also be discussed....
And Please,, this is not a HW........
Thanks.............
The code looks correct, though you only have the core of the algorithm, not a complete program. You'll have to provide the missing bits: headers, a main function, and a swap macro (you could make swap a function by calling it as swap(s, d, i)).
To understand the algorithm, it would be instructive to add some tracing output, say printf("permute(%s, %d)", s, d) at the beginning of the permute function, and run the program with a 3- or 4-character string.
The basic principle is that each recursive call to permute successively places each remaining element at position d; the element that was at position d is saved by putting it where the aforementioned remaining element was (i.e. the elements are swapped). For each placement, permute is called recursively to generate all desired substrings after the position d. So the top-level call (d=0) to permute successively tries all elements in position 0, second-level calls (d=1) try all elements in position 1 except for the one that's already in position 0, etc. The next-to-deepest calls (d=n-1) have a single element to try in the last position, and the deepest calls (d=n) print the resulting permutation.
The core algorithm requires Θ(n·n!) running time, which is the best possible since that's the size of the output. However this implementation is less efficient that it could be because it recomputes strlen(s) at every iteration, for a Θ(n²·n!) running time; the simple fix of precomputing the length would yield Θ(n·n!). The implementation requires Θ(n) memory, which is the best possible since that's the size of the input.
For an explanation of the recursion see Gilles answer.
Your code has some problems. First it will be hard to implement the required swap as a function in C, since C lacks the concept of call by reference. You could try to do this with a macro, but then you'd either have to use the exclusive-or trick to swap values in place, or use a temporary variable.
Then your repeated use of strlen on every recursion level blows up your complexity of the program. As you give it this is done at every iteration of every recursion level. Since your string even changes (because of the swaps) the compiler wouldn't even be able to notice that this is always the same. So he wouldn't be able to optimize anything. Searching for the terminating '\0' in your string would dominate all other instructions by far if you implement it like that.

Resources