Finding subset sum recursively producing incorrect output - c

Followed this method (pdf) to implement a recursive solution, but I think it is buggy. I have exactly implemented it as described in the pdf file.
The output of the code below is wrong. It shows the target locations. The target array contains bit representation of the numbers that should be added to get the sum.
Placing the binary[i] = 1 in else if condition fixes the problem, but it doesn’t make sense.
Is it possible to clarify what is the right solution?
#define SIZE(a) sizeof(a)/sizeof(a[0])
int binary[100];
void foo(int target, int i, int sum, int *a, int size) {
binary[i] = 1;
if (target == sum+a[i]) {
int j;
for (j=0;j<size;j++)
printf("%d\n", binary[j]);
return;
} else if ((i+1 < size) && (sum + a[i] < target)) {
foo(target, i+1, sum + a[i], a, size);
}
if ((i+1 < size) && (sum +a[i+1] <= target)) {
binary[i] = 0;
foo(target, i+1, sum, a, size);
}
}
int main()
{
int i, target =10,a[] = {1, 2, 3, 5, 100};
foo(target, 0, 0, a, SIZE(a));
}
Current output: 0 1 1 1 1
Expected output: 0 1 1 1 0

#include <stdio.h>
#define SIZE(a) sizeof(a)/sizeof(a[0])
int binary[100];
void show(int* p, int size) {
int j;
for (j = 0; j < size; j++)
printf("%d\n", p[j]);
}
void foo(int target, int i, int sum, int *a, int size) {
if (sum == target) {
// solution found
show(binary, size);
} else if (sum < target && i < size) {
// try both branches
// 1. current value used
binary[i] = 1;
foo(target, i + 1, sum + a[i], a, size);
// 2. current value skipped
binary[i] = 0;
foo(target, i + 1, sum, a, size);
} else {
// no solution on this path
}
}
int main() {
int target = 10;
int a[] = {1, 2, 3, 5, 100};
foo(target, 0, 0, a, SIZE(a));
}
Explanation:
Let's speak only about i, sum and binary because everything else is constant from this algorithm's perspective.
Our aim is to select individual elements from a whose sum is equal to target. When we reach this situation we are done and our only work is to show the solution.
The algorithm can proceed only if our current sum is still below the target, and we haven't reached the end of a yet.
There are always two possibilities: Use the current element or skip it. Both are investigated recursively.
The procedure must leave zero in the appropriate position of binary, otherwise it would provide misleading results at various levels of backtracking. For this reason the use branch is investigated first.

Related

Determine the three maximum and two minimum values of the array

Task:
Given a natural number N (set arbitrarily as a preprocessor constant) and one-dimensional array A0, A1, …, AN-1 of integers (generate positive and negative elements randomly, using the <stdlib.h> library function rand()). Perform the following actions: Determine the three maximum and two minimum values of this array.
Code with search for two minimum values:
#include <stdio.h>
#include <stdlib.h>
#define N 9
int main() {
int M[N], i, a[N], fbig, sbig, tbig, min, smin;
for (i = 0; i < N; i++) {
M[i] = rand() % 20 - 10;
printf("%i\t", M[i]);
}
printf("\n");
for (i = 0; i < N; i++) {
if (a[i] < min) {
smin = min;
min = a[i];
} else
if (a[i] < smin && a[i] != min)
smin = a[1];
}
printf("\nMinimum=%d \nSecond Minimum=%d", min, smin);
return 0;
}
I tried to compare array elements with each other but here is my result:
-7 -4 7 5 3 5 -4 2 -1
Minimum=0
Second Minimum=0
I would be very grateful if you could help me fix my code or maybe I'm doing everything wrong and you know how to do it right. Thank you for your time
I will revise my answer if op address what to do about duplicate values. My answer assume you want possible duplicate values in the minimum and maximum arrays, while other answers assume you want unique values.
The easiest solution would be to sort the input array. The minimum is the first 2 values and the maximum would be the last 3:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 3
#define MIN_N 2
#define N 9
void generate(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
a[i] = rand() % 20 - 10;
}
void print(size_t n, int a[n]) {
for(size_t i = 0; i < n - 1; i++)
printf("%d, ", a[i]);
if(n) printf("%d\n", a[n-1]);
}
int cmp_asc(const void *a, const void *b) {
if(*(int *) a < *(int *) b) return -1;
if(*(int *) a > *(int *) b) return 1;
return 0;
}
int main() {
int t = time(0);
srand(t);
printf("%d\n", t); // essential for debugging
int a[N];
generate(N, a);
print(N, a);
qsort(a, N, sizeof *a, cmp_asc);
print(MIN_N, a);
print(MAX_N, a + (N - MAX_N));
}
If you cannot use sort then consider the following purpose built algorithm. It's much easier to use arrays (min and max) rather than individual values, and as a bonus this allows you to easily change how many minimum (MIN_N) and maximum (MAX_N) values you want. First we need to initialize the min and max arrays, and I use the initial values of the input array for that. I used a single loop for that. To maintain the invariant that the min array has the MIN_N smallest numbers we have seen so far (a[0] through a[i-1]) we have to replace() largest (extrema) of them if the new value a[i] is smaller. For example, if the array is min = { 1, 10 } and the value we are looking at is a[i] = 5 then we have to replace the 10 not the 1.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 3
#define MIN_N 2
#define N 9
void generate(size_t n, int a[n]) {
for(size_t i = 0; i < n; i++)
a[i] = rand() % 20 - 10;
}
void print(size_t n, int a[n]) {
for(size_t i = 0; i < n - 1; i++)
printf("%d, ", a[i]);
if(n) printf("%d\n", a[n-1]);
}
int cmp_asc(const void *a, const void *b) {
if(*(int *) a < *(int *) b) return -1;
if(*(int *) a > *(int *) b) return 1;
return 0;
}
int cmp_desc(const void *a, const void *b) {
return cmp_asc(b, a);
}
void replace(size_t n, int a[n], int v, int (*cmp)(const void *, const void *)) {
int *extrema = &a[0];
for(size_t i = 1; i < n; i++) {
if(cmp(extrema, &a[i]) < 0) {
extrema = &a[i];
}
}
if(cmp(extrema, &v) > 0)
*extrema = v;
}
void min_max(size_t n, int a[n], size_t min_n, int min[n], size_t max_n, int max[n]) {
for(size_t i = 1; i < n; i++) {
if(i < min_n)
min[i] = a[i];
else
replace(min_n, min, a[i], cmp_asc);
if(i < max_n)
max[i] = a[i];
else
replace(max_n, max, a[i], cmp_desc);
}
}
int main() {
int t = time(0);
srand(t);
printf("%d\n", t); // essential for debugging
int a[N];
generate(N, a);
print(N, a);
int min[MIN_N];
int max[MAX_N];
min_max(N, a, MIN_N, min, MAX_N, max);
print(MIN_N, min);
print(MAX_N, max);
}
and here is example output. The first value is a the seed in case you have to reproduce a run later. Followed by input, min and max values:
1674335494
-7, 0, -2, 7, -3, 4, 5, -8, -9
-9, -8
7, 5, 4
If MIN_N or MAX_N gets large, say, ~1,000+, then you want sort the min and max arrays and use binary search to figure out where to inserta[i]. Or use a priority queue like a heap instead of arrays.
There are multiple problems in your code:
min and smin are uninitialized, hence the comparisons in the loop have undefined behavior and the code does work at all. You could initialize min as a[0] but initializing smin is not so simple.
there is a typo in smin = a[1]; you probably meant smin = a[i];
Note that the assignment is somewhat ambiguous: are the maximum and minimum values supposed to be distinct values, as the wording implies, or should you determine the minimum and maximum elements of the sorted array?
For the latter, sorting the array, either fully or partially, is a simple solution.
For the former, sorting is also a solution but further testing will be needed to remove duplicates from the sorted set.
Here is a modified version to print the smallest and largest values:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 9
#define N_MIN 2
#define N_MAX 3
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
int a[N], i, j, e, dup;
int smallest[N_MIN], nsmall = 0;
int largest[N_MAX], nlarge = 0;
srand(time(NULL));
for (i = 0; i < N; i++) {
a[i] = rand() % 20 - 10;
printf("%i\t", a[i]);
}
printf("\n");
for (i = 0; i < N; i++) {
e = a[i];
dup = 0;
for (j = 0; j < nsmall; j++) {
if (e == smallest[j]) {
dup = 1;
break;
}
if (e < smallest[j]) {
swap(&e, &smallest[j]);
}
}
if (!dup && nsmall < N_MIN) {
smallest[nsmall++] = e;
}
e = a[i];
dup = 0;
for (j = 0; j < nlarge; j++) {
if (e == largest[j]) {
dup = 1;
break;
}
if (e > largest[j]) {
swap(&e, &largest[j]);
}
}
if (!dup && nlarge < N_MAX) {
largest[nlarge++] = e;
}
}
printf("smallest values: ");
for (i = 0; i < nsmall; i++) {
printf(" %d", smallest[i]);
}
printf("\n");
printf("largest values: ");
for (i = nlarge; i --> 0;) {
printf(" %d", largest[i]);
}
printf("\n");
return 0;
}
As already noted, the most direct way to do this would be to simply sort the array. (In fact, if all you need is an output of five integers then your array only need be five elements long.) But I will presume that that is not the point of this homework.
Your goal isn’t super efficiency or a pretty algorithm. It is simply to solve the tasks. Do them one at a time.
First question: How would you find the largest value?
Answer: Loop through the array, keeping track of the largest element found so far.
int largest = array[0]; // why start with this value?
for (int n = 0; n < size; n++)
if (array[n] > largest)
largest = array[n];
Second question: How would you find the smallest value?
Answer: Almost the same way, with only a simple change: Instead of testing if (array[n] > largest) we want to test if (array[n] < smallest), right?
int smallest = largest; // why start with this value?
for (int n = 0; n < size; n++)
if (...) // new condition goes here
smallest = array[n];
Third question: How would you find the second smallest value?
Answer: It should not surprise you that you just need to change the if condition in that loop again. An element would be the second smallest if:
it is the smallest value greater than the smallest.
Think about how you would change your condition:
int second_smallest = largest; // why start with this value?
for (int n = 0; n < size; n++)
if (... && ...) // what is the new test condition?
second_smallest = array[n];
Remember, this time you are testing two things, so your test condition needs that && in it.
Fourth question: can you write another loop to find the second-largest? How about the third-largest?
At this point you should be able to see the variation on a theme and be able to write a loop that will get you any Nth largest or smallest value, as long as you already have the (N-1)th to work against.
Further considerations:
Is it possible that the third-largest is the same as the second-smallest?
Or the smallest?
Is it possible for there to not be a third-largest?
Does it matter?
Put all these loops together in your main() and print out the results each time and you are all done!
...
int main(void)
{
int array[SIZE];
// fill array with random numbers here //
int largest = array[0];
for (...)
if (...)
...
int smallest = largest;
for (...)
if (...)
...
int second_smallest = largest;
for (...)
if (...)
...
int second_largest = smallest;
for (...)
if (...)
...
int third_largest = smallest;
for (...)
if (...)
...
printf( "The original array = " );
// print original array here, then: //
printf( "largest = %d\n", largest );
printf( "2nd largest = %d\n", second_largest );
printf( "3nd largest = %d\n", third_largest );
printf( "2nd smallest = %d\n", second_smallest );
printf( "smallest = %d\n", smallest );
return 0;
}
Example outputs:
{ 1 2 3 4 }
smallest = 1
2nd smallest = 2
3rd largest = 2
2nd largest = 3
largest = 4
{ 5 5 5 5 5 }
smallest = 5
2nd smallest = 5
3rd smallest = 5
largest = 5
{ 1 2 }
smallest = 1
2nd smallest = 2
3rd smallest = 2
largest = 2
Bonus: be careful with variable names. There has been no need to use short abbreviations since before the early nineties. Prefer clarity over brevity.

Is there an O(n) algorithm to find the first missing number in an array?

Given an array of n integers, not necessarily sorted, is there an O(n) algorithm to find the least integer that is greater than the minimum integer in the array but that is not in the array?
The following algorithm has a complexity O(n).
I will assume here that the missing element must be selected after the minimum value.
The algorithm can be easily modified if the minimum possible value is fixed, for example equal to 0.
Once we have determined the minimum value a (in O(n) or in O(1) if the value is known in advance),
then we know that the missing value is less or equal a + n, if n is the array size.
Then we simply have to use an array of size n+1, present[n+1], initialised to 0,
and then to look at all values arr[i]:
if (arr[i] <= a+n) present[arr[i] - a] = 1;
Finally, in a third step we simply have to examine the array present[.], and seach for the first index k such that present[k]==0.
The first missing number is equal to a + k.
#include <stdio.h>
#include <stdlib.h>
int find_missing (int *arr, int n) {
int vmin = arr[0];
int *present = calloc (n+1, sizeof(int));
for (int i = 1; i < n; ++i) {
if (arr[i] < vmin) {
vmin = arr[i];
}
}
int vmax = vmin + n;
for (int i = 0; i < n; ++i) {
if (arr[i] <= vmax) {
present[arr[i] - vmin] = 1;
}
}
int k = 0;
for (k = 0; k <= n; ++k) {
if (present[k] == 0) break;
}
free(present);
return vmin + k;
}
int main() {
int arr[] = {2, 3, 5, 6, 8};
int n = sizeof(arr)/sizeof(arr[0]);
int missing = find_missing (arr, n);
printf ("First missing element = %d\n", missing);
return 0;
}
Given an array of n integers, without negative numbers, not
necessarily sorted, is there an O(n) algorithm to find the least
integer that is greater than the minimum integer in the array but that
is not in the array?
This can be solved with O(N) time complexity, with N being the number of element in the array. Let us call that array a1, the algorithm is as follows:
Find the smallest value in a1 (i.e, min);
Create a new array a2 with size equals to N;
Initialized the array a2 with a value to signal missing element, for instance min - 1;
Iterate through the array a1, and for each position, take the element in that position e1 = a1[i], and only if e1 is not greater than min - N mark the corresponded position on a2 as visited, for instance using the element itself, namely a2[e1 - min] = e1; If e1 is greater than min - size then it clearly does not belong to the sequence, and can be ignored because in the worst-case scenario the first missing value will be the value min + N + 1.
Lastly, iterate through the array a2, and get the first element = -1; it will be your first missing element.
Steps 1, 3, 4, and 5, all of them take in the worst-case scenario N. Hence, this algorithm takes 4N, which is O(N) time complexity;
The code will be straight forward to implement; for instance something as follows (for an array {5, 3, 0, 1, 2, 6}):
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
int find_min(int *array, int size){
int min = array[0];
for(int i = 0; i < size; i++)
min = (array[i] < min) ? array[i] : min;
return min;
}
void fill_array(int *array, int size, int missing_value){
for(int i = 0; i < size; i++)
array[i] = missing_value;
}
void mark_existing_values(int *s, int size, int *d, int min){
for(int i = 0; i < size; i++){
int elem = s[i];
if(elem - min < size)
d[elem - min] = elem;
}
}
int find_first_missing_value(int *array, int size, int min){
int missing_value = min - 1;
for(int i = 0; i < size; i++){
if(array[i] == missing_value){
return i + min;
}
}
return missing_value;
}
int main(){
int array_size = 6;
int array_example [] = {5, 3, 0, 1, 2, 6};
int min = find_min(array_example, array_size);
int *missing_values = malloc(array_size * sizeof(int));
fill_array(missing_values, array_size, min - 1);
mark_existing_values(array_example, array_size, missing_values, min);
int value = find_first_missing_value(missing_values, array_size, min);
printf("First missing value {%d}\n", value);
free(missing_values);
return 0;
}
OUTPUT:
First missing value {4}
This algorithm works also for negative numbers, for instance if int array_example [] = {-1, -3, 0, 3, 5, 6, 7, 8, 10};, then the output would be:
First missing value {-2}
The code can be simplified if in step 3 and step 4 instead of min - 1 and a2[e1 - min] = e1, respectively, we use two flags to signal missing (e.g., 0) and existing values (e.g., 1). Just like showcase in #Damien code. The downside is that we are using two flags instead of one. The benefit is that it simplifies the code, and in case the smallest value in the array is the smallest value that can be represented in C we will not underflow with min - 1.
You can use the technique of bitwise XOR.
This method has O(n) time complexity and it is working on unsorted arrays too.
Also, keep in mind, this works only if one element is missing from the array.
#include <stdio.h>
int main()
{
int arr[] = { 1, 2, 4, 5, 6, 7 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
int x = arr[0]; //XOR together all of the array elements
for (int i = 1; i < arr_size; i++)
{
x ^= arr[i];
}
int y = 1; //XOR together the numbers from 1 to size of array + 1
for (int i = 2; i <= arr_size + 1; i++)
{
y ^= i;
}
int missing = x ^ y; //The missing number is going to be the XOR of the previous two.
printf("%d", missing);
return 0;
}

C implementation of quick sort produces garbage value at arr[0]

Consider the following algorithm:
void qsort(int arr[], int left, int right) {
if (left < right) {
int index = partition(arr, left, right);
qsort(arr, left, index - 1);
qsort(arr, index + 1, right);
}
}
int partition(int arr[], int left, int right) {
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (arr[j] <= pivot) {
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[right]);
return i + 1;
}
inline void swap(int* i, int* j) {
int temp = *i;
*i = *j;
*j = temp;
}
After I fixed the segfaults, I noticed that the algorithm always produces a garbage value at arr[0]. So if the input array is: 5 5 1 3 7 0 0 0 3 , the output is -858993460 0 0 0 1 3 3 5 5. I've ran this through a debugger numerous times and nevertheless I still have no idea where the garbage value comes from. What's more interesting is that in Java pretty much the same algorithm works perfectly.
edit
The initial function is called like this: qsort(arr, 0, 9); where 9 is the length of the array - 1.
I suspect you have an off-by-one error in how you initialize arr or how you call qsort(). Likely it gets called with a garbage (uninitialized) element either at the start or at the end of the array. This also likely explains why the largest value, 7, is missing from the output.
If I were to speculate further, I'd guess that in Java, the array gets initialized with zeros and so you get an extra zero in the output (that perhaps you're overlooking amongst the other zeros?)
edit: The initial function is called like this: qsort(arr, 0, 9); where 9 is the length of the array - 1.
The 9 is clearly not correct for your example, so here is one error. It would account for the garbage element but not for the missing element.
My next hypothesis is that, having sorted a ten-element array (9 real + 1 garbage) you then only print out the first nine elements. This would account for the missing 7 in your output (it's the largest and so gets placed in the final spot, which is the spot that doesn't get printed out).
P.S. If I may offer some unsolicited advice for future questions, posting a Minimal, Complete, and Verifiable example would make all this debugging-by-conjecture completely unnecessary as we'd be able to see right away what exactly is going on with your code. :)
If you invoke the function with the size instead of the index of the right-most element (which is the size - 1), you access the array out of bounds.
This code works:
#include <stdio.h>
static
inline void swap(int *i, int *j)
{
int temp = *i;
*i = *j;
*j = temp;
}
static
int partition(int arr[], int left, int right)
{
int pivot = arr[right];
int i = left - 1;
for (int j = left; j < right; j++)
{
if (arr[j] <= pivot)
{
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[right]);
return i + 1;
}
static
void qsort(int arr[], int left, int right)
{
if (left < right)
{
int index = partition(arr, left, right);
qsort(arr, left, index - 1);
qsort(arr, index + 1, right);
}
}
static void dump_array(const char *tag, int size, int *arr)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", arr[i]);
putchar('\n');
}
int main(void)
{
int arr[] = { 5, 5, 1, 3, 7, 0, 0, 0, 3, };
enum { ARR_SIZE = sizeof(arr) / sizeof(arr[0]) };
dump_array("Before", ARR_SIZE, arr);
qsort(arr, 0, ARR_SIZE - 1);
dump_array("After", ARR_SIZE, arr);
return 0;
}
Output:
Before (9): 5 5 1 3 7 0 0 0 3
After (9): 0 0 0 1 3 3 5 5 7

Is there a way to iterate over order?

How can one iterate through order of execution?
I am developing a piece of software that have several steps to compute over some data, and i was thinking in may changing the order of those steps pragmatically so i can check what would be the best order for some data.
Let me exemplify: I have let's say 3 steps (it's actually more):
stepA(data);
stepB(data);
stepC(data);
And I want a contraption that allow me to walk thought every permutation of those steps and then check results. Something like that:
data = originalData; i=0;
while (someMagic(&data,[stepA,stepB,stepC],i++)){
checkResults(data);
data = originalData;
}
then someMagic execute A,B then C on i==0. A, C then B on i==1. B, A then C on i==2 and so on.
You can use function pointers, maybe something like the following:
typedef void (*func)(void *data);
int someMagic(void *data, func *func_list, int i) {
switch (i) {
case 0:
func_list[0](data);
func_list[1](data);
func_list[2](data);
break;
case 1:
func_list[0](data);
func_list[2](data);
func_list[1](data);
break;
case 2:
func_list[1](data);
func_list[0](data);
func_list[2](data);
break;
default: return 0;
}
return 1;
}
func steps[3] = {
stepA,
stepB,
stepC
}
while (someMagic(&data, steps, i++)) {
....
}
The key is to find a way to iterate over the set of permutations of the [0, n[ integer interval.
A permutation (in the mathematical meaning) can be seen as a bijection of [0, n[ into itself and can be represented by the image of this permutation, applied to [0, n[.
for example, consider the permutation of [0, 3[:
0 -> 1
1 -> 2
2 -> 0
it can be seen as the tuple (1, 2, 0), which in C, translate naturally to the array of integers permutation = (int []){1, 2, 0};.
Suppose you have an array of function pointers steps, then for each permutation, you'll then want to call steps[permutation[i]], for each value of i in [0, n[.
The following code implements this algorithm:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static void stepA(int data) { printf("%d: %s\n", data, __func__); }
static void stepB(int data) { printf("%d: %s\n", data, __func__); }
static void stepC(int data) { printf("%d: %s\n", data, __func__); }
static void (* const steps[])(int) = {stepA, stepB, stepC,};
static int fact(int n) { return n == 0 ? 1 : fact(n - 1) * n; }
static int compare_int(const void *pa, const void *pb)
{
return *(const int *)pa - *(const int *)pb;
}
static void get_next_permutation(int tab[], size_t n)
{
int tmp;
unsigned i;
unsigned j;
unsigned k;
/* to find the next permutation in the lexicographic order
* source: question 4 (in french, sorry ^^) of
* https://liris.cnrs.fr/~aparreau/Teaching/INF233/TP2-permutation.pdf
. */
/* 1. find the biggest index i for which tab[i] < tab[i+1] */
for (k = 0; k < n - 1; k++)
if (tab[k] < tab[k + 1])
i = k;
/* 2. Find the index j of the smallest element, bigger than tab[i],
* located after i */
j = i + 1;
for (k = i + 1; k < n; k++)
if (tab[k] > tab[i] && tab[k] < tab[j])
j = k;
/* 3. Swap the elements of index i and j */
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
/* 4. Sort the array in ascending order, after index i */
qsort(tab + i + 1, n - (i + 1), sizeof(*tab), compare_int);
}
int main(void)
{
int n = sizeof(steps) / sizeof(*steps);
int j;
int i;
int permutation[n];
int f = fact(n);
/* first permutation is identity */
for (i = 0; i < n; i++)
permutation[i] = i;
for (j = 0; j < f; j++) {
for (i = 0; i < n; i++)
steps[permutation[i]](i);
if (j != f - 1)
get_next_permutation(permutation, n);
}
return EXIT_SUCCESS;
}
The outer loop in main, indexed by j, iterates over all the n! permutations, while the inner one, indexed by i, iterates overs the n steps.
The get_next_permutation modifies the permutation array in place, to obtain the next permutation in the lexicographical order.
Note that it doesn't work when the permutation in input is the last one (n - 1, ..., 1, 0), hence the if (j != f - 1) test.
One could enhance it to detect this case (i isn't set) and to put the first permutation (0, 1, ..., n - 1) into the permutation array.
The code can be compiled with:
gcc main.c -o main -Wall -Wextra -Werror -O0 -g3
And I strongly suggest using valgrind as a way to detect off-by-one errors.
EDIT: I just realized I didn't answer the OP's question precisely. The someMagic() function would allow a direct access to the i-th permutation, while my algorithm only allows to compute the successor in the lexicographic order. But if the aim is to iterate on all the permutations, it will work fine. Otherwise, maybe an answer like this one should match the requirement.
I've come to a solution that is simple enough:
void stepA(STRUCT_NAME *data);
void stepB(STRUCT_NAME *data);
void stepC(STRUCT_NAME *data);
typedef void (*check)(STRUCT_NAME *data);
void swap(check *x, check *y) {
check temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(check *a, int l, int r,STRUCT_NAME *data) {
int i, j = 0, score;
HAND_T *copy, *copy2, *best_order = NULL;
if (l == r) {
j = 0;
while (j <= r) a[j++](data);
} else {
for (i = l; i <= r; i++) {
swap((a + l), (a + i));
permute(a, l + 1, r, data);
swap((a + l), (a + i));
}
}
}
check checks[3] = {
stepA,
stepB,
stepC,
};
int main(void){
...
permute(checks,0,2,data)
}

palindrome checker algorithm

i'm having problems writing this excercise.
this should evaluate if a given array contains a palindrome sequence of numbers, the program builds correctly but doesn't run (console remains black). where am i wrong on this? thanks for all help!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
//i'm using const int as exercise demand for it
//should i declare size as int when giving it to function? also if it's been declared?
//i'm a bit confused about that
int palindrome(const int a[], int p, int size);
int main()
{
int a[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0};
int p = 1; //i'm not using boolean values, but i think should work anyway, right?
p = palindrome(a, p, SIZE);
if (p)
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");
return 0;
}
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
while (p) {
for (j = 0; j < (SIZE / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]) //i think i might be wrong on this, but don't know where i'm in fault
p = 0;
}
}
return p;
}
p.s.
how can i activate debugger "watches" on Code Blocks to look at others function variables? (i put a stop on main function)
You don't need while (p) { loop. It is possible to have infinite loop here (and you have it!), because if you don't change p, this loop never stops.
You mix size and SIZE in the implementation of palindrome() (mid is half of size, but the whole loop is from 0 to SIZE-1).
Also it is better to move int p = 1; in the beginning of implementation of palindrome() (and to remove int p from list of it's parameters).
Just try this:
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
for (j = 0; j < (size / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]);
p = 0;
break;
}
}
return p;
}
here's an alternative without p where palindrome returns 0 or 1
int palindrome(const int a[], int size)
{
int j , k , ret;
for (j = 0 , k = size - 1 ; j < k; j++ , k--)
{
if (a[j)] != a[k])
{
ret = 0;
break;
}
}
if(j >= k)
ret = 1;
return ret;
}
you can call palindrome in the if statement in main like this :
if(palindrome(a , SIZE))
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");

Resources