I'm trying to write an iterative function that computes all the permutations of an array of numbers given in input.
Here is the code I've written so far.
void permute(int *a, int size){
int j=0, i, h=0, m;
bool flag=true;
int f = factorial(size);
int *arr, *res;
int counter=0;
arr = malloc(f*sizeof(int));
for(i=0; i<f; i++)
arr[i] = 0;
while (j < f) {
if(arr[j]<j)
{
if(j%2 == 0)
{
swap(a[0],a[j]);
} else {
swap(a[arr[j]], a[j]);
}
arr[j]++;
j=0;
} else{
arr[j] = 0;
j++;
}
printf("%d\n",a[j] );
}
}
The code doesn't compute well all the permutations and goes into a long loop. Can someone help me, please? Thanks to everyone.
Your code is close but includes some problems. For instance, the while loop
while (j < f) will assign j to a value out of bound of the array a.
Instead would you please try:
#include <stdio.h>
#include <stdlib.h>
int factorial(int x)
{
int i;
int y = 1;
for (i = 1; i <= x; i++) {
y *= i;
}
return y;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(int *a, int size)
{
int i, j = 0;
int f = factorial(size);
int *arr;
arr = calloc(f, sizeof(int)); // the members are initialized to 0
// print the original array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
while (j < size) {
if (arr[j] < j) {
if (j % 2 == 0) {
swap(a + 0, a + j);
} else {
swap(a + arr[j], a + j);
}
// print the rearranged array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
arr[j]++;
j = 0;
} else {
arr[j] = 0;
j++;
}
}
free(arr);
}
int main()
{
int a[] = {1, 2, 3}; // example
permute(a, sizeof a / sizeof a[0]); // the 2nd argument is the array length
return 0;
}
Output of the example:
1 2 3
2 1 3
3 1 2
1 3 2
2 3 1
3 2 1
Related
this is the program I made ,if I input [13,11,10,17,18] i get the output [12,13,17,11,10]. I do not understand what mistake I am making. somebody please help me understand.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d",&v);
ptr[i] = v;
}
i=0;
j=0;
while(i<5){
j++;
if (ptr[j]%2==0 && i%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (ptr[j]%2!=0 && i%2 !=0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (j==4){
i++;
j=0;
}
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
Ok, I tried to tell you how you should have written you program, but you didn't listen:
Make a https://stackoverflow.com/help/minimal-reproducible-example
A MCVE needs all the includes
No interactive stuff. You need to run and run and run your program in a debugger. You don't want to put data in manually every single time.
You want many tests, and you want to repeat them, so that when you fix one, you don't break another.
Make a function which does the job.
Free your memory!
Now to the solution: your idea of a solution was fine apart from the stuff about indexes. It's pretty similar to the one you will find down here. The only difference is that I put the odd numbers al the end to avoid checking elements multiple times.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void evenodd(int *v, size_t n)
{
for (size_t i = 0; i < n; ++i) {
while (i < n && v[i] % 2 == 0) {
++i;
}
--n;
while (i < n && v[n] % 2) {
--n;
}
if (i < n) {
int tmp = v[i];
v[i] = v[n];
v[n] = tmp;
}
}
}
bool is_evenodd(int *v, size_t n)
{
size_t i = 0;
while (i < n && v[i] % 2 == 0) {
++i;
}
while (i < n && v[i] % 2 != 0) {
++i;
}
return i == n;
}
void main_test(const int *v, size_t n)
{
int *v1 = memcpy(malloc(n * sizeof(int)), v, n * sizeof(int));
evenodd(v1, n);
if (is_evenodd(v1, n)) {
printf("Ok!\n");
}
else {
printf("Fail!\n");
}
free(v1);
}
int main(void)
{
main_test((int[]) { 1 }, 0);
main_test((int[]) { 1 }, 1);
main_test((int[]) { 2 }, 1);
main_test((int[]) { 1, 2 }, 2);
main_test((int[]) { 1, 3 }, 2);
main_test((int[]) { 2, 1 }, 2);
main_test((int[]) { 2, 4 }, 2);
main_test((int[]) { 1, 3, 2 }, 3);
main_test((int[]) { 1, 4, 2 }, 3);
size_t n = 1000;
int *a = malloc(n * sizeof *a);
for (size_t i = 0; i < n; ++i) {
a[i] = rand();
}
main_test(a, n);
free(a);
return 0;
}
You can try the following code :
int even_index = 0; //start index
int odd_index = 4; //end index
for(int i=0;i<5;i++){
if(ptr[i] % 2 == 0){
int temp = ptr[even_index];
ptr[even_index++] = ptr[i]; //swapping values and incrementing even_index
ptr[i] = temp;
}else{
int temp = ptr[odd_index];
ptr[odd_index--] = ptr[i];
ptr[i] = temp;
}
}
or you can also count the number of even numbers in the digits during input and assign odd_value = even_num // number of even digits
ok so I solved it....
see the even numbers always end up in even indexes so we need to set a pointer on those even index(current index) and search for any even number after the current index.
if we find any(even number) we swap the current index value with the even number.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d", &v);
ptr[i] = v;
}
i=0;
j=0;
while(i<n && j<n){
if (ptr[j]%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
i+=2;
j=i;
}
j++;
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
If this problem is to sort an array in order (descending) and then further place all even values before odd values I would recommend:
Sort the array
Swap and shift any odd numbers with the even numbers
Here's a naive implementation:
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (arr[i] < arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
int lastEven = 0;
for (int i = 0; i < len - 1; i++) {
if (arr[i] % 2 && (arr[i + 1] % 2 == 0)) {
tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
lastEven = i;
} else if (arr[i] % 2 == 0 && lastEven-i > 1) {
for (int j = i; j > lastEven; j--) {
tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}
lastEven++;
}
}
Given the input [13,11,10,17,18] this will first sort the array ([18,17,13,11,10]) then separate the evens and odds ([18,10,17,13,11])
Description of the problem :
Compute the number of all the sequences which go up down from some input n.
So the user input n; with that n then I create an array of numbers 1..n and then number the sequences with that property
Example: n = 4
1 3 2 4
1 4 2 3
2 3 1 4
2 4 1 3
3 4 1 2
Answer: 5
My program works but for some reason I sometimes get 0 instead of the answer.
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permute(int *array, int i, int length, int *count) {
if (length == 2) {
*count = 1;
return;
}
if (length == i) {
int v = 0, flag = 1;
while (v < length) {
if (v % 2 == 0) {
if (array[v] < array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
if (v % 2 != 0) {
if (array[v] > array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
}
if (flag == 1) {
/*
int a;
for (a = 0; a < length; a++)
printf("%d", array[a]);
printf("\n");
*/
*count = *count + 1;
}
}
int j = i;
for (j = i; j < length; j++) {
swap(array + i, array + j);
permute(array, i + 1, length, count);
swap(array + i, array + j);
}
return;
}
int main(int argc, char **argv) {
int n;
scanf("%d", &n);
int *arr = safeMalloc(n * sizeof(int));
int i;
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permute(arr, 0, n, &count);
printf("%d\n", count);
return 0;
}
You basically generate all permutations of the array elements and count the valid ones.
Your code has a minor flaw:
the loop while (v < length) { goes one step too far: you access tab[v + 1] so the loop should stop at v < length - 1. As currently coded, it has undefined behavior.
You can further simply the code:
there should be no need to special case length == 2.
flag useless as you always return when you clear it.
if (v % 2 != 0) is redundant: else would suffice.
Here is a fixed and simplified version:
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permutate(int *array, int i, int length, int *count) {
if (i == length) {
for (int v = 0; v < length - 1; v++) {
if (v % 2 == 0) {
if (array[v] >= array[v + 1]) {
return;
}
} else {
if (array[v] <= array[v + 1]) {
return;
}
}
}
*count = *count + 1;
} else {
for (int j = i; j < length; j++) {
swap(array + i, array + j);
permutate(array, i + 1, length, count);
swap(array + i, array + j);
}
}
}
int main(int argc, char **argv) {
int n;
if (scanf("%d", &n) == 1 && n > 0) {
int *arr = safeMalloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permutate(arr, 0, n, &count);
printf("%d\n", count);
}
return 0;
}
if you call tab(n,k) the number of updown sequence of length n with k being the last number in your sequence, you can write a recursive formula and implement it like that:
int N = 5+1;
int** tab = new int*[N];
for (int n = 0; n < N; n++) {
tab[n] = new int[N];
for (int k = 0; k < N; k++) {
tab[n][k] = 0;
}
}
tab[1][1] = 1;
for (int n = 2; n < N; n++) {
for (int k = 1; k <= n; k++) {
if (n % 2 == 0) {
for (int j = 0; j < k; j++) {
tab[n][k] += tab[n-1][j];
}
}
else {
for (int j = k; j < n; j++) {
tab[n][k] += tab[n-1][j];
}
}
}
}
int res = 0;
for (int j = 0; j < N; j++) {
res += tab[N - 1][j];
}
You can solve this without iterating through the permutations. Say you're trying to calculate f(n). Where can the new, high number go? It has to go in an 'up' position, which is an even position. You can have any valid sequence of odd length preceding it, and any valid sequence following it.
Let's say we're calculating f(n,k) where the highest val is in position k, zero indexed. This is zero for k even. For odd k we get:
f(n,k) = choose(n-1, k) * f(k) * f(n - k - 1)
To get f(n), sum f(n,k) over odd k < n.
We have to calculate the first few by hand.
f(0) = 1
f(1) = 1
f(2) = 1
f(3) = f(3,1) = choose(2,1) * f(1) * f(1) = 2 * 1 *1 = 2
f(4) = f(4,1) + f(4,3) = choose(3,1) * f(1) * f(2) + choose(3,3) * f(3) * f(0) = 3*1*1 + 1*2*1 = 5
f(5) = f(5,1) + f(5,3) = choose(4,1) * f(1) * f(3) + choose(4,3) * f(3) * f(1) = 4*1*2 + 4*2*1 = 16
Right now I am programming a thing that takes clues to mastermind and return how many guesses should be left to get the secret code correct. I have a small problem however, as it only works on the last guess that is input, so if only one guess is input, it is correct, but any more and it is not...
Here is my code right now:
#include <stdio.h>
#include <stdlib.h>
int bPegs(int *secret, int *sarr);
void frequency(int *array, int *freq);
int tPegs(int *freqA, int *freqG);
void perm(int list[],int k, int n);
int check(int ba, int bb, int wa, int wb);
int slots, colors, guesses;
int *guess;
int counter = 0;
int main() {
int runs, k;
scanf("%d", &runs);
for (k = 0; k < runs; k++) {
int i, j;
scanf("%d", &slots);
scanf("%d", &colors);
scanf("%d", &guesses);
guess = malloc(sizeof(int) * slots + 2);
int *list = malloc(sizeof(int) * slots);
for (i = 0; i < guesses; i++) {
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}
}
perm(list, 0, slots);
printf("%d", counter);
}
return 0;
}
int bPegs(int *secrets, int *sarr) {
int i;
int black = 0;
for (i = 0; i < slots; i++) {
if (secrets[i] == sarr[i]) {
black++;
}
}
return black;
}
void frequency(int *array, int *freq) {
int i;
for (i = 0; i < slots; i++) {
freq[array[i]]++;
}
}
int tPegs(int *freqA, int *freqG) {
int i, total = 0;
for (i = 0; i < colors; i++) {
if (freqG[i] > freqA[i]) {
total += freqA[i];
}
if (freqG[i] < freqA[i] && freqG[i] != 0) {
total += freqG[i];
}
if (freqG[i] == freqA[i] && freqA[i] != 0) {
total+=freqG[i];
}
}
return total;
}
int check(int ba,int bb, int wa, int wb) {
if (ba == bb && wa == wb) {
return 1;
} else {
return 0;
}
}
void perm(int list[], int k, int n) {
int j;
int *freqA = calloc(colors, sizeof(int));
int *freqG = calloc(colors, sizeof(int));
if (k == n) {
frequency(list, freqA);
frequency(guess, freqG);
int ba = bPegs(list, guess);
int ta = tPegs(freqA, freqG);
int wa = ta - ba;
int bb = guess[slots];
int wb = guess[slots + 1];
if (check(ba, bb, wa, wb)) {
counter++;
}
} else {
int i;
for (i = 0; i < colors; i++) {
list[k] = i;
perm(list, k + 1, n);
}
}
}
Here is some sample input / output:
input:
1
10 2 1
1 0 1 0 1 0 1 0 1 5 4
output:
200
this much is correct, for an example of it breaking:
input:
1
4 6 4
0 1 2 3 0 2
2 2 4 1 0 2
4 3 3 2 1 1
1 3 5 4 1 3
should give:
1
but it does give:
8
and I cannot figure out how to set this up for more than just one clue... any help would be great.
The main reading loop seems incorrect:
for (j = 0; j < slots + 2; j++) {
("%d", &guess[j]);
}
Did you mean this instead:
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}
I'm having some trouble with my sort function which also uses the swap function to work. I have been trying to find my mistake but cant find it. the rest of the code works perfectly, only the sort function doesn't work (it doesn't sort anything.)
I will leave the code here if anybody has any ideas of how to solve my problem please reply.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void sort(int *values, int n);
void swap(int arr[], int i);
void populate(int arr[]);
const int arraysize = 10;
int main()
{
srand((long int) time(NULL));
int ela[10] = {0};
populate(ela); // populates with random values
printf("before func\n");
for(int i = 0; i < arraysize; i++)
{
printf("%i\n", ela[i]);
}
sort(ela, arraysize); // this is the function that is not working
printf("\n\nafter func\n");
for(int i = 0; i < arraysize; i++)
{
printf("%i\n", ela[i]);
}
return 0;
}
void sort(int *values, int n)
{
int count = 1;
while(count != 0)
{
count = 0;
for (int i = 0; i < n; i++) {
if(values[i] > values[(i + 1)] && values[(i + 1)] != '\0')
{
swap(values, i);
count++;
}
if (count == 0) break;
}
}
}
void swap(int arr[], int i)
{
int save = arr[i];
arr[i] = arr[i+1];
arr[i + 1] = save;
return;
}
void populate(int arr[])
{
for(int i = 0; i < arraysize; i++)
{
arr[i] = (rand() % 15);
}
}
void sort(int *values, int n)
{
int count = 1;
while(count != 0)
{
count = 0;
for (int i = 0; i < n-1; i++) {
if(values[i] > values[(i + 1)] )
{
swap(values, i);
count++;
}
//if (count == 0) break;
}
}
}
I doubt this would never be true values[(i + 1)] != '\0' as the values are integers..So running the for loop until the condition i<n-1 would work fine as you are swapping i+1 element with i.
And also if (count == 0) break; inside your for loop should be removed as the loop would break if there is some input like 2 3 2 1 and so wouldn't sort .
Working Ideone: http://ideone.com/k1LJau
Here is an updated version of your sort() function:
void sort(int *values, int n)
{
int count = 1;
while(count != 0)
{
count = 0;
for (int i = 0; i < n; i++) {
if(values[i] > values[(i + 1)] && values[(i + 1)] != '\0')
{
swap(values, i);
count++;
}
}
}
}
Your if(count==0) break; statement would exit your for loop even when you would check initial values of the array. So for instance [5 6 9 8] would exit because count was 0 when it checked the first two items.
If you want to use sort() function, you have to add algorithm header file. But it will not work for c. If you add using namespace std;
Then it will work. And then you have to call like that.
sort(ela, ela+arraysize);
You can edit your sort function like below. Above answers are also nice.
void Sort(int *values, int n)
{
int cnt=0;
while(1)
{
cnt++;
if(cnt==n-1)
break;
for (int i = 0; i < n-cnt; i++)
{
if(values[i] > values[(i + 1)] && values[(i + 1)] != '\0')
{
swap(values, i);
}
}
}
}
Your bubble sort function is wrong.
Here is a demonstrative program that shows how the function can be written
#include <stdio.h>
void swap( int a[], size_t i )
{
int tmp = a[i];
a[i] = a[i+1];
a[i+1] = tmp;
}
void bubble_sort( int a[], size_t n )
{
for ( _Bool sorted = 0; n-- != 0 && !sorted; )
{
sorted = 1;
for ( size_t i = 0; i < n; i++ )
{
if ( a[i+1] < a[i] )
{
sorted = 0;
swap( a, i );
}
}
}
}
int main(void)
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
My teacher has assigned something I can't seem to figure out how to do without using qsort. We're given a 2x3 array, and he wants us to sort each row from min to max. I am not allowed to use qsort for the purposes of learning; in my opinion, this is difficult.
Here is what I have so far; currently, the program crashes. I assume this is because when it gets to the third column, there isn't anything in a fourth column [j+1], so it returns an error.
#include "stdafx.h"
#include <stdio.h>
int main() {
int x[2][3] = { { 2, 3, -1 }, { 0, -3, 5 } }; //2x3 matrix; 2 rows, 3 columns
void sortMinMax(int b[][3], int numRow, int numColumn); //function prototype
sortMinMax(x, 2, 3);
return 0;
}
void sortMinMax(int a[][3], int numRow, int numColumn) {
for (int i = 0; i < numRow; i++) {
for (int j = 0; j < numColumn - 1; j++) {
if (a[i][j + 1] < a[i][j]) { //swap values if the next number is less than the current number
int temp = a[i][j];
a[i][j] = a[i][j + 1];
a[i][j + 1] = temp;
}
printf("%i\t", a[i][j]);
}
printf("\n");
}
return;
}
I appreciate any and all help!
I believe int i = 0; i <= numRow; i++ should be int i = 0; i <
numRow; i++
Why do you have if(i==0) & if(i==1) if you are doing the same stuff?
It looks like you tried to implement bubble-sort-like algorithm, but you do only one pass over the data
Here is an example of bubble sort algorithm
for(int x=0; x<n; x++)
{
for(int y=0; y<n-1; y++)
{
if(array[y]>array[y+1])
{
int temp = array[y+1];
array[y+1] = array[y];
array[y] = temp;
}
}
}
Slightly better alternative might be found # http://www.sorting-algorithms.com/bubble-sort
for i = 1:n,
swapped = false
for j = n:i+1,
if a[j] < a[j-1],
swap a[j,j-1]
swapped = true
→ invariant: a[1..i] in final position
break if not swapped
end
#include <stdio.h>
int main() {
int x[2][3] = { { 2, 3, -1 }, { 0, -3, 5 } };
void sortMinMax(int b[][3], int numRow, int numColumn);
sortMinMax(x, 2, 3);
for(int i = 0;i<2;++i){
for(int j = 0;j<3;++j)
printf("%i\t", x[i][j]);
printf("\n");
}
return 0;
}
void swap(int *a, int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void sort3(int a[3]){
if(a[0] > a[1])
swap(&a[0], &a[1]);
if(a[0] > a[2])
swap(&a[0], &a[2]);
if(a[1] > a[2])
swap(&a[1], &a[2]);
}
void sortMinMax(int a[][3], int numRow, int numColumn) {
for (int i = 0; i < numRow; i++) {
sort3(a[i]);
}
}