Generating subsets of a set in C(Non recursive) - c

I am trying to generate all the subsets of a set in a non recursive manner. This is the code:
#include <stdio.h>
main() {
int no_of_element, no_of_subset, i, j, start, index, a[50], x;
printf("Enter the size of main set :");
scanf("%d", &no_of_element);
printf("Enter the elements of main set :");
for (x = 0; x < no_of_element; x++)
scanf("%d", &a[x]);
printf("The subsets are :\n");
for (no_of_subset = 1; no_of_subset <= no_of_element; no_of_subset++) {
for (start = 0; start <= no_of_element - no_of_subset; start++) {
if (no_of_subset == 1)
printf("%d\n", a[start]);
else {
index = start + no_of_subset - 1;
for (j = index; j < no_of_element; j++) {
for (i = start; i < index; i++) {
printf("%d\t", a[i]);
}
printf("%d\n", a[j]);
}
}
}
}
}
This is the output:
Enter the size of main set :4
Enter the elements of main set :1
2
3
4
The subsets are :
1
2
3
4
1 2
1 3
1 4
2 3
2 4
3 4
1 2 3
1 2 4
2 3 4
1 2 3 4
This code isn't generating the subset (1,3,4). Could someone please help me fix it ?

Just for fun, I dit it from scratch.
The trick is to let a counter go through all the possible subsets, each being a combination of its bits.
In case, use unsigned long int to handle sets of up to 64 elements:
#include <stdio.h>
void print_subset(int subset, int *set) {
int pos=0;
printf("Subset %d = ", subset);
while (subset) {
if (subset & 1) {
printf("%d ", set[pos]);
}
subset >>= 1;
pos++;
}
printf("\n");
}
int main()
{
int no_of_element,no_of_subset,x,a[50];
printf("Enter the size of main set :");
scanf("%d",&no_of_element);
printf("Enter the elements of main set :");
for(x=0;x<no_of_element;x++)
scanf("%d",&a[x]);
no_of_subset= (1 << no_of_element);
printf("There are %d subsets\n", no_of_subset);
for (; no_of_subset--;) {
print_subset(no_of_subset, a);
}
}
When run it produces
Enter the size of main set :4
Enter the elements of main set :1
2
3
4
There are 16 subsets
Subset 15 = 1 2 3 4
Subset 14 = 2 3 4
Subset 13 = 1 3 4
Subset 12 = 3 4
Subset 11 = 1 2 4
Subset 10 = 2 4
Subset 9 = 1 4
Subset 8 = 4
Subset 7 = 1 2 3
Subset 6 = 2 3
Subset 5 = 1 3
Subset 4 = 3
Subset 3 = 1 2
Subset 2 = 2
Subset 1 = 1
Subset 0 =

#include <stdio.h>
#include <stdlib.h>
void print(size_t n, int a[n]){
size_t i;
for(i=0; i < n; ++i){
if(i)
putchar(',');
printf("%d", a[i]);
}
putchar('\n');
}
void subset(size_t n, int a[n], size_t size){
int *out = malloc(size * sizeof(*out));
int *level = malloc((size+1)*sizeof(int));
int *index = malloc((size+1)*sizeof(int));
int sp = 0;
level[sp] = 0;
index[sp] = 0;
redo:
while(index[sp] < n){
out[level[sp]] = a[index[sp]];
level[sp+1] = level[sp] + 1;
index[sp+1] = index[sp] + 1;
if(level[++sp] == size){
print(size, out);
--sp;
} else
goto redo;//this means recursive call
++index[sp];
}
if(sp>0){
++index[--sp];
goto redo;
}
free(level);
free(index);
free(out);
}
int main(void){
int a[] = {1, 2, 3, 4};
size_t i, n = sizeof(a)/sizeof(*a);
for(i = 1; i <= n; ++i)
subset(n, a, i);
return 0;
}
result:
1
2
3
4
1,2
1,3
1,4
2,3
2,4
3,4
1,2,3
1,2,4
1,3,4
2,3,4
1,2,3,4

Related

Why this code is working for 1 and 2 yet fails for input that is more than 3?

So I am trying to print patterns in C.
For n = 2
Output:
2 2 2
2 1 2
2 2 2
for n = 3
Output:
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
and so on.
My Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d",&n);
int nn = n;
int *arr;
arr = (int*)malloc(n*sizeof(int));
int f = 0; //flag to check if I reached the mid of the pattern
int l = 2*n-1; //Lenght of square to be generated
int temp1 = 0;
int temp2 = l;
for(int i = 0;i<l;i++)
{
for(int j = temp1;j<temp2;j++) //change values in range temp1 to temp2
{
arr[j] = n;
}
for(int k = 0;k<l;k++)
{
printf("%d ",arr[k]);
}
printf("\n");
if(n == 1)
{
f = 1;
}
if(f==0) //For upper half of pattern
{
n=n-1;
temp1=temp1+1;
temp2=temp2-1;
}
else if(f==1) //For lower half of pattern
{
n=n+1;
temp1=temp1-1;
temp2=temp2+1;
}
}
return(0);
}
I am getting the correct output for n = 2 but when I am inputting anything above 2 the code is crashing.
I am not able to find what should be done. Can someone help me out and tell me what am I doing wrong?
It would be better to check distances by axis and take a maximum of them to be printed.
Something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int vertical_distance;
int horizontal_distance;
int n;
scanf("%d",&n);
for(int i = 0; i < n * 2 + 1; i++)
{
for(int j = 0; j < n * 2 + 1; j++)
{
vertical_distance = abs(n - i);
horizontal_distance = abs(n - j);
if (vertical_distance > horizontal_distance)
printf("%d ", vertical_distance);
else
printf("%d ", horizontal_distance);
}
printf("\n");
}
return(0);
}
Also, when I ran your code it worked nicely with large numbers (3, 7, 15).
I just pasted your code to onlinegdb.com/online_c_compiler and ran it. Can you please add the error message that you have got?
(sry for my English)
in this code piece
for(int j = temp1;j<temp2;j++) //change values in range temp1 to temp2
{
arr[j] = n;
}
j can be bigger than n. but arr malloc space is n. the array overflowed.
it will work with a small change
arr = (int*)malloc(2*n*sizeof(int));

counter to check if array X is subsequence of A not working (C)

I've tried following this program by hand, but I still can't get it to work.
I have an array A = [4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1] and array X = [1,2,3].
I need to find the max number i for X^i that is a subsequence of A, and do this by binary search.
Since size of A is 20, and size of X is 3, the max possible i = 20/3 = 6. So my search will start at i = 3, which means that X^3 = [1,1,1,2,2,2,3,3,3].
This is not a subsequence of A, so binary search repeats for i = 1, X^1 = [1,2,3].
This is a subsequence of A, meaning it should pass and binary search should try again for i = 2.
However, my condition to see if the iteration passes or not is not working properly.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void create_initial_arrays(int size_a, int *A, int size_x, int *X);
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i);
int main(){
int size_a, size_x;
scanf("%d", &size_a);
scanf("%d", &size_x);
int max_i = size_a / size_x;
int min_i = 0;
printf("Max: %d\n", max_i);
int *A = (int*) malloc(size_a *sizeof(int));
int *X = (int*) malloc(size_x *sizeof(int));
create_initial_arrays(size_a, A, size_x, X);
printf("Old X: ");
for(int i = 0; i < size_x; i++){
printf("%d ", X[i]);
}
printf("\n");
binary_search(size_a, A, size_x, X, max_i, min_i);
free(X);
free(A);
}
void create_initial_arrays(int size_a, int *A, int size_x, int *X){
int i, throwaway;
for(i = 0; i < size_a; i++){
scanf("%d", &A[i]);
}
scanf("%d", &throwaway);
for(i = 0; i < size_x; i++){
scanf("%d", &X[i]);
}
scanf("%d", &throwaway);
}
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int j, k, max_repeat = 0;
while(min_i <= max_i){
int i = 0, count = 0, repeats = (max_i + min_i)/2;
printf("\n");
int * temp = (int*) malloc(size_x * sizeof(int) * repeats);
for(k = 0; k < size_x; ++k){
for(j = 0; j < repeats; ++j){
temp[k * repeats + j] = X[k];
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", temp[i]);
}
printf("A: ");
for (i = 0; i < size_a; i++){
printf("%d ", A[i]);
}
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
printf("Count: %d", count);
if (count >= size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
max_repeat++;
}
else{
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
free(temp);
}
printf("Max repeat: %d", max_repeat);
}
And this is the section that I think must be problematic:
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
I've output both Arrays to make sure they are populated correctly (they are) and the counter after each iteration. Here is my code output:
Old X: 1 2 3
New X: 1 1 1 2 2 2 3 3 3 A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 3 High 6 Fails
New X: 1 2 3 A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 1 High 2 Fails
New X: A: 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 Count: 0Low: 0 Mid 0 High 0 Passes
Max repeat: 1
Notice that count remains 0 throughout. On the first iteration for X^3 = [1,1,1,2,2,2,3,3,3], the condition is true 5 times ([1,1,1,2,2] is a subsequence of A, so count should be 5, but 5 is not >= size_x * repeats(3 * 3), so it fails as expected. Binary search reduces to Low 0 Mid 1 High 2, so i = repeats = 1.
X^1 = [1,2,3] is a subsequence of A, and count should be 5 on this iteration ([1,2,3] plus two extra counts of 3) which is >= size_x * repeats (3*1), so it should pass, and redo the search for i = 2. However, count remains zero and fails.
Why is count not updating? I know I need to keep it in the loop because I need it reset to 0 for each iteration, but I don't really understand why A[j] == temp[i] is not ever passing.

Algorithms: To determine whether a given set has two subsets which are disjoint such that sum of elements in both subsets is same?

Here is the code that I have written:-
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int ctr = 0;
void partition(int arr[], int n) {
int i, j, k = 0, r, in = 0, te, flag = 0;
int *sum;
sum = (int*)malloc(sizeof(int) * pow(2, n));
for (i = 0; i < pow(2, n); i++) {
printf("{");
for (j = 0; j < n; j++) {
if (i & (1 << j)) {
printf("%d ", arr[j]);
sum[k] = sum[k] + arr[j];
}
}
k++;
printf("}");
printf("\n");
}
printf("\n \n");
int *temp;
for (k = 0; k < pow(2, n) - 1; k++) {
in = 0;
temp = (int*)malloc(sizeof(int));
for (r = k + 1; r < pow(2, n); r++) {
if (sum[k] == sum[r]) {
printf("\n Printing solution for sum %d", sum[k]);
for (i = 0; i < pow(2, n); i++) {
if (i == k || i == r) {
printf("{");
for (j = 0; j < n; j++) {
if (i & 1 << j) {
for (te = 0; te < in; te++) { //Disjointness
if (temp[te] == arr[j])
flag = 1;
}
if (flag == 1)
break;
temp[in++] = arr[j];
temp = (int*)realloc(temp, sizeof(int));
printf("%d ", arr[j]);
}
}
printf("}");
printf("\n");
}
}
break;
}
}
free(temp);
}
}
void main() {
int *arr, n, i;
printf("\n Enter the number of elements in the set \n");
scanf("%d", &n);
arr = (int*)malloc(sizeof(int) * n);
printf("\n Enter the set elements \n");
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
partition(arr, n);
}
It works perfectly for the input {1,2,3}. For {1,2,3,4}, it gives the correct output as well.
For {1,2,3,4}, the output is:
Printing solution for sum 3{1 2 }
{3 }
Printing solution for sum 4{1 3 }
{4 }
Printing solution for sum 5{2 3 }
{1 4 }
Printing solution for sum 6{1 2 3 }
{}
Printing solution for sum 7{}
{}
But if the input is {1,5,11,5}, the output is:
Printing solution for sum 5{5 }
{}
Printing solution for sum 6{}
{}
Printing solution for sum 11{}
{}
Printing solution for sum 16{}
{}
Printing solution for sum 17{}
{}
Since {1,5,5} and {11} is a solution, in this case, the expected output should be Printing Solution for sum 11 {1,5,5} and {11} but it's not displaying that.
What is the problem and how can I fix it?
Your algorithm is too complicated. You start on the correct path, computing the sum of all subsets of the set, but you do not correctly compute all possible disjoint subsets to try and find one with the same sum.
Here is a simpler approach:
enumerate all subsets
for each subset, compute the sum and store a structure with the subset signature and its sum into an array.
sort the array by the value of the sum
iterate over the sorted array:
for each element, iterate over the subsequent elements with the same sum, if one of them has a disjoint subset signature, you have a match, print it.
the space complexity is O(2N) and the time complexity is even worse at O(2N+1), which is very bad, but manageable for small sets.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct s { int sig, sum; };
int compare(const void *p1, const void *p2) {
int sum1 = ((const struct s*)p1)->sum;
int sum2 = ((const struct s*)p2)->sum;
return (sum1 > sum2) - (sum1 < sum2);
}
void print_set(int arr[], size_t sig) {
printf("{");
while (sig) {
if (sig & 1)
printf(" %d", *arr);
arr++;
sig >>= 1;
}
printf(" } ");
}
void partition(int arr[], int n) {
size_t i, j, count = 1ULL << n;
struct s *array = calloc(sizeof(*array), count);
int b, sum;
if (array != NULL) {
for (i = 1; i < count; i++) {
sum = 0;
for (b = 0; b < n; b++) {
if (i & (1ULL << b))
sum += arr[b];
}
array[i].sig = i;
array[i].sum = sum;
}
qsort(array, count, sizeof(*array), compare);
for (i = 0; i < count; i++) {
for (j = i + 1; j < count && array[i].sum == array[j].sum; j++) {
if ((array[i].sig & array[j].sig) == 0) {
printf("solution with sum=%d: ", array[i].sum);
print_set(arr, array[i].sig);
print_set(arr, array[j].sig);
printf("\n");
}
}
}
free(array);
}
}
int main() {
int *arr, n, i;
printf("Enter the number of elements in the set: ");
if (scanf("%d", &n) == 1) {
arr = (int*)malloc(sizeof(int) * n);
if (arr != NULL) {
printf("Enter the set elements: ");
for (i = 0; i < n; i++) {
if (scanf("%d", &arr[i]) != 1)
return 1;
}
partition(arr, n);
free(arr);
}
}
return 0;
}
Output:
Enter the number of elements in the set: 3
Enter the set elements: 1 2 3
solution with sum=3: { 3 } { 1 2 }
Enter the number of elements in the set: 4
Enter the set elements: 1 2 3 4
solution with sum=3: { 1 2 } { 3 }
solution with sum=4: { 4 } { 1 3 }
solution with sum=5: { 2 3 } { 1 4 }
Enter the number of elements in the set: 4
Enter the set elements: 1 5 11 5
solution with sum=5: { 5 } { 5 }
solution with sum=11: { 11 } { 1 5 5 }
You may find the following to be a place to start. What this sample program does is to take a set of values and then generate as possible disjoint subsets where the sum of the elements of each subset are equal between the two subsets.
I am not sure if this actually answers your question. The requirements specified are quite loose. The source you provide does not compile with Visual Studio and when a few basic compile errors were corrected the resulting program crashed. I also find your example output confusing.
The criteria for disjoint subsets as created by this program are:
values in one subset can not appear in the other
membership is ordered and tracked via an index assigned to each element of the superset
a subset may have duplicate values but not duplicate indexed elements
the empty set is not considered to be a valid disjoint subset since it has no elements
there must be at least two subsets that can be formed from the set
only two subsets are considered and there may be more (e.g. {1, 2, 3, 4, 5} could have {2,3}, {1,4}, {5}).
The source code follows. This is from a single C source code file that is part of a Visual Studio C++ solution with the C++ main() calling the C source code entry point of mymain2(). I did it that way because it was easier for me.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int *pSet; // array of values. array is malloced when max number is known.
int nSetMax; // max number of array elements, amount malloced.
int nSetCur; // current number of in use array elements.
} SetType;
static void generateSet (int i, int arr[], int n, SetType *temp)
{
int j;
temp->nSetCur = 0;
for (j = 0; j < n; j++)
{
if ( i & (1 << j))
{
int te;
int flag = 0;
for (te = 0; te < temp->nSetCur; te++)
{
// we compute disjoint property by the order of the elements in
// the set using element index in order to allow duplicate values per
// request of the question. Exampe 1, 5, 11, 5 as list of values.
if (temp->pSet[te] == j)
flag = 1;
}
if (flag == 1)
continue;
temp->pSet[temp->nSetCur] = j;
temp->nSetCur++;
}
}
}
static void printItems (int arr[], const SetType temp)
{
if (temp.nSetCur > 0) {
int j;
int sum = 0;
printf(" {");
for (j = 0; j < temp.nSetCur; j++) {
printf("%2d ", arr[temp.pSet[j]]);
sum += arr[temp.pSet[j]];
}
printf("} = %3d\n", sum);
} else
printf (" {}\n");
}
// determine if the two sets are disjoint by comparing the element indexes
// of the elements in each subset. the element index is the position of the
// subset element in the set from which the subset was drawn.
static int checkSetsByIndex (const SetType tempI, const SetType tempR)
{
int i;
for (i = 0; i < tempI.nSetCur; i++) {
int j;
for (j = 0; j < tempR.nSetCur; j++) {
if (tempI.pSet[i] == tempR.pSet[j])
return 0;
}
}
return 1;
}
// determine if the two sets are disjoint by comparing the element values
// of the elements in each subset. the element value is the value of the
// subset element in the set from which the subset was drawn.
// we may have duplicate values but as long as they are not in two different
// subsets then we allow it.
static int checkSetsByValue (int arr[], const SetType tempI, const SetType tempR)
{
int i;
#if 1
// following code does a check that the two sets are disjoint by value
// meaning they do not share any values. however a set may have multiple
// elements with the same value.
// if not needed then you can turn it off with Preprocessor check.
for (i = 0; i < tempI.nSetCur; i++) {
int j;
for (j = 0; j < tempR.nSetCur; j++) {
if (arr[tempI.pSet[i]] == arr[tempR.pSet[j]])
return 0;
}
}
#endif
return 1;
}
static void partition(int arr[], int n)
{
int i;
int iPow2n = pow(2, n);
int *sum = calloc(iPow2n, sizeof(int));
printf ("Generate and list sums\n");
for(i = 0; i < iPow2n; i++)
{
int j;
printf(" {");
for (j = 0; j < n; j++)
{
if (i & (1 << j))
{
printf("%2d ", arr[j]);
sum[i] = sum[i] + arr[j];
}
}
printf("} = %3d\n", sum[i]);
}
printf("\n\nGenerate list of disjoint sets for each sum.\n");
for (i = 0; i < iPow2n - 1; i++)
{
int r;
SetType tempI = {calloc(iPow2n, sizeof(SetType)), iPow2n, 0};
SetType tempR = {calloc(iPow2n, sizeof(SetType)), iPow2n, 0};
for(r = i + 1; r < iPow2n; r++)
{
if(sum[i] == sum[r])
{
generateSet (i, arr, n, &tempI);
generateSet (r, arr, n, &tempR);
// check disjoint subsets by looking at the index of the
// subset elements where the index is the index of the original
// set from which the subset is drawn.
if (checkSetsByIndex (tempI, tempR)) {
// check that the two subsets are disjoint by element values
// as well. this means that while a subset may have duplicate
// values, the elements of each subset must be disjoint can not
// have elements whose values are the same.
// so if we have a set {1, 5, 11, 5} then subsets of
// {5}, {5} is invalid but {1, 5, 5}, {11} is valid.
if (checkSetsByValue (arr, tempI, tempR)) {
printf("\n Printing solution for sum %d\n", sum[i]);
printItems (arr, tempI);
printItems (arr, tempR);
break;
}
}
}
}
free(tempI.pSet);
free(tempR.pSet);
}
}
int mymain2(void)
{
int n;
printf("\n Enter the number of elements in the set \n");
scanf("%d",&n);
if (n > 0) {
int i;
int *arr = malloc(sizeof(int) * n);
printf("\n Enter the set elements \n");
for (i = 0; i < n; i++)
{
scanf("%d",&arr[i]);
}
partition(arr,n);
free (arr);
}
return 0;
}
For a set of 4 values whose elements are {1, 2, 3, 4} it generates the following output:
Enter the number of elements in the set
4
Enter the set elements
1 2 3 4
Generate and list sums
{} = 0
{ 1 } = 1
{ 2 } = 2
{ 1 2 } = 3
{ 3 } = 3
{ 1 3 } = 4
{ 2 3 } = 5
{ 1 2 3 } = 6
{ 4 } = 4
{ 1 4 } = 5
{ 2 4 } = 6
{ 1 2 4 } = 7
{ 3 4 } = 7
{ 1 3 4 } = 8
{ 2 3 4 } = 9
{ 1 2 3 4 } = 10
Generate list of disjoint sets for each sum.
Printing solution for sum 3
{ 1 2 } = 3
{ 3 } = 3
Printing solution for sum 4
{ 1 3 } = 4
{ 4 } = 4
Printing solution for sum 5
{ 2 3 } = 5
{ 1 4 } = 5
For a set of 4 values {1, 5, 11, 5} it generates the following output:
Enter the number of elements in the set
4
Enter the set elements
1 5 11 5
Generate and list sums
{} = 0
{ 1 } = 1
{ 5 } = 5
{ 1 5 } = 6
{11 } = 11
{ 1 11 } = 12
{ 5 11 } = 16
{ 1 5 11 } = 17
{ 5 } = 5
{ 1 5 } = 6
{ 5 5 } = 10
{ 1 5 5 } = 11
{11 5 } = 16
{ 1 11 5 } = 17
{ 5 11 5 } = 21
{ 1 5 11 5 } = 22
Generate list of disjoint sets for each sum.
Printing solution for sum 11
{11 } = 11
{ 1 5 5 } = 11
For a set of 5 values {1, 2, 3, 4, 5} it generates the following output:
Enter the number of elements in the set
5
Enter the set elements
1 2 3 4 5
Generate and list sums
{} = 0
{ 1 } = 1
{ 2 } = 2
{ 1 2 } = 3
{ 3 } = 3
{ 1 3 } = 4
{ 2 3 } = 5
{ 1 2 3 } = 6
{ 4 } = 4
{ 1 4 } = 5
{ 2 4 } = 6
{ 1 2 4 } = 7
{ 3 4 } = 7
{ 1 3 4 } = 8
{ 2 3 4 } = 9
{ 1 2 3 4 } = 10
{ 5 } = 5
{ 1 5 } = 6
{ 2 5 } = 7
{ 1 2 5 } = 8
{ 3 5 } = 8
{ 1 3 5 } = 9
{ 2 3 5 } = 10
{ 1 2 3 5 } = 11
{ 4 5 } = 9
{ 1 4 5 } = 10
{ 2 4 5 } = 11
{ 1 2 4 5 } = 12
{ 3 4 5 } = 12
{ 1 3 4 5 } = 13
{ 2 3 4 5 } = 14
{ 1 2 3 4 5 } = 15
Generate list of disjoint sets for each sum.
Printing solution for sum 3
{ 1 2 } = 3
{ 3 } = 3
Printing solution for sum 4
{ 1 3 } = 4
{ 4 } = 4
Printing solution for sum 5
{ 2 3 } = 5
{ 1 4 } = 5
Printing solution for sum 5
{ 1 4 } = 5
{ 5 } = 5
Printing solution for sum 6
{ 2 4 } = 6
{ 1 5 } = 6
Printing solution for sum 7
{ 3 4 } = 7
{ 2 5 } = 7

Print only those arrays with 3 digits whose sum is 10 - C program

Output:
1 2 3 4
1 2 7
1 3 6
1 4 5
1 9
2 3 5
2 8
3 7
4 6
10
Expected Output:
1 2 7
1 3 6
1 4 5
2 3 5
I want only those pairs of digits whose sum is 10 and also has only 3 digits i.e, the pair of 3 distinct digits whose sum is 10 should be displayed, rest all other pairs get skip or not displayed.
Below is my full source code which I have written for this problem.
#include <stdio.h>
#include <stdlib.h>
void partition(int part) {
int *parts, *ptr, i, idx = 0, tot = 0, cur = 1, max = 1;
while ((max * (max + 1)) / 2 <= part)
max++;`
ptr = parts = malloc(sizeof(int) * max);
for (;;) {
if ((tot += *ptr++ = cur++) < part)
continue;
if (tot == part) {
for (i = 0; i < ptr-parts; i++) {
printf("%d ", parts[i]);
}
printf("\n");
}
do {
if (ptr == parts) {
free(parts);
return;
}
tot -= cur = *--ptr;
} while (++cur + tot > part);
}
}
int main(int argc, char*argv[]) {
int n;
scanf("%d", &n);
partition(n);
return 0;
}
Your code seems way too complicated. Here is a simple solution:
#include <stdio.h>
#define SUM 10
int main(void) {
for(int a = 1; a < SUM; a++) {
for(int b = a + 1; b < SUM; b++) {
for(int c = b + 1; c < SUM; c++) {
if(a + b + c == SUM) {
printf("%d %d %d\n", a, b, c);
}
}
}
}
}
Program output:
1 2 7
1 3 6
1 4 5
2 3 5
This could be more efficient but it is a simple form.
Your code is too generic for this problem: you do not need to enumerate all possible partitions and select those with 3 numbers. Just enumerate all possible triplets without duplicates.
Here is a simpler and much faster solution for your problem:
#include <stdio.h>
void partition(int sum) {
/* enumerate a, b, c such that:
a < b < c
a + b + c = sum
*/
int a, b;
for (a = 1; 3 * a + 2 <= sum; a++) {
for (b = a + 1; a + 2 * b + 1 <= sum; b++) {
printf("%d %d %d\n", a, b, sum - a - b);
}
}
}
int main(void) {
int n;
if (scanf("%d", &n) == 1)
partition(n);
return 0;
}

Print a pattern in C

I wish to print a pattern in C language like this:
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
Currently I have this:
int main()
{
int i,j;
for(i=1;i<=5;i++)
{
for(j=1;j<=5;j++)
{
if(i>=j)
{
printf(" %d ",j+i-1);
}
}
printf("\n");
}
printf("\n");
}
I am not getting the desired result.Please can anybody help
Basically if you analyze the difference between numbers at each row:
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
^ ^ ^ ^
diff 4 3 2 1
Then for each column (except the first one which is equal to the row) the formula is:
col_value = val(row, col-1) + (5-col))
For example, the last row:
5 9 12 14 15
9 = 5 + (5-1)
12 = 9 + (5-2)
14 = 12 + (5-3)
15 = 14 + (5-4)
Code:
#include<stdio.h>
int main()
{
int i,j,k;
for(i=1;i<=5;i++)
{
k = i;
for(j=1;j<=i;j++)
{
printf("%d ", k);
k += 5-j;
}
printf("\n");
}
return 0;
}
Check this :
int main()
{
int i,j;
for(i=1;i<=5;i++)
{
int temp = 4;
int sum = 0;
for(j=1;j<=i;j++)
{
if (j == 1)
sum = i;
else{
sum = sum + temp --;
}
printf("%d ",sum);
}
printf("\n");
}
}
int main () {
int k,i, j;
for (i = 1; i <=5; i++) {
k = i;
for (j = 1; j <= i; j++) {
printf ("%d ", k);
k = k + (5-j);
}
printf ("\n");
}
}
The logic is quite straight forward.
1) The number of elements in a row equals the row number. Hence use the inner loop with j = 1 to j <= i
2) If you see the pattern you observe that every row starts with the number equals to the row index, the next number is +4 and then +3 and so on.
3) Hence use k = k + (5-j)
int main()
{
int i,j,temp=0,l;
for(i=1;i<=5;i++)
{
l=4;
temp = i;
for(j=1;j<=i;j++)
{
if(j>1)
{
printf("%d\t",temp+l);
temp = temp+l;
l=l-1;
}
else
printf("%d\t",i);
}
printf("\n");
}
getch();
return 0;
}

Resources