Print all n! permutations of the number 1,2,3,...,n.
Example: Input: 3
Output: 1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Following is my approach. My program is not working for inputs greater than 3. I understand the logic why it is not working , but I am unable to translate that logic into a code block to overcome that issue.
#include <stdio.h>
int permute(int n)
{
int a[n];
int i,j,k,store;
for(i=0;i<n;i++)
a[i]=i+1;
for(i=1;i<=n;i++)
{
for(j=0;j<n-1;j++)
{
store=a[j+1];
a[j+1]=a[j];
a[j]=store;
for(k=0;k<n;k++)
printf("%d ",a[k]);
printf("\n");
}
}
}
int main()
{
int n;
scanf("%d",&n);
permute(n);
return 0;
}
Following is the output for n as 4:
We can clearly see that some permutation are missing, and I know exactly the fault in my code. But I am unable to fix it.( I am a beginner , hence I don't know much advanced C libraries or functions)
One solution consists in calling the function recursively: you set the first number (n possible choices), then call the function for a size n-1.
Output, for n=4
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 3 1
2 4 1 3
3 2 1 4
3 2 4 1
3 1 2 4
3 1 4 2
3 4 1 2
3 4 2 1
4 2 3 1
4 2 1 3
4 3 2 1
4 3 1 2
4 1 3 2
4 1 2 3
#include <stdio.h>
#include <stdlib.h>
void swap (int *i, int *j) {
int temp = *i;
*i = *j;
*j = temp;
}
void permute(int index, int* arr, int n) {
if (index == n-1) {
for (int k = 0; k < n; ++k) {
printf ("%d ", arr[k]);
}
printf ("\n");
return;
}
for (int i = index; i < n; i++) {
swap (arr + index, arr + i);
permute (index+1, arr, n);
swap (arr + i, arr + index);
}
return;
}
int main()
{
int n;
if (scanf("%d",&n) != 1) exit (1);
int arr[n];
for (int i = 0; i < n; ++i) arr[i] = i+1;
permute(0, arr, n);
return 0;
}
Related
I want to count sequence of numbers together, by always adding the next number to the sum of numbers before. Then do it all again but start one number up. Like this. Then find duplicated sums.
1 5 2 4 2 2 2(sequence)
0..1: 1 5 sum=6
0..2: 1 5 2 sum=8
0..3: 1 5 2 4 sum=12
0..4: 1 5 2 4 2 sum=14
0..5: 1 5 2 4 2 2 sum=16
0..6: 1 5 2 4 2 2 2 sum=18
1..2: 5 2 sum=7
1..3: 5 2 4 sum=11
1..4: 5 2 4 2 sum=13
1..5: 5 2 4 2 2 sum=15
1..6: 5 2 4 2 2 2 sum=17
2..3: 2 4 sum=6
2..4: 2 4 2 sum=8
2..5: 2 4 2 2 sum=10
2..6: 2 4 2 2 2 sum=12
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int count = 0;
char temp;
int sekvence[10000];
int countedsequence[10000];
int duplication = 0;
//save user input
do
{
scanf("%d%c", &sekvence[count], &temp);
count++;
} while (temp != '\n');
sekvence[count];
//somehow count it and save to countedsequence
countedsequence[0] = sekvence[0];
countedsequence[0] = countedsequence[0] + sekvence[0 + 1];
for (int i = 1; i < count - 1; i++)
{
countedsequence[i] = countedsequence[i - 1] + sekvence[i + 1];
}
//find duplicated numbers in countedsequence
for (int i = 0; i < count - 1; i++)
{
for (int j = i + 1; j < count - 1; j++)
{
if (countedsequence[i] == countedsequence[j])
{
duplication++;
break;
}
}
}
//idk some printing for testing
for (int i = 0; i < count - 1; i++)
{
printf("%d ", countedsequence[i]);
}
printf("%d\n", duplication);
return 0;
}
I only managed to count from start to end how do I start counting again with one up to the end?
I usually revise op's code into an solution but the use of non-English variable mean that require unnecessary extra effort. The only working functionality is the interactive input handling but that gets in way during development.
To generate each range of the sequence using two loops (for start and end) and at third to generate the sum of said range (sequence_sum()).
With an unordered array of numbers we can find duplicates by a tweaked partition algorithm that that swap elements into 3 sections: one instance of each duplicates [0; i[, todo [i; sum_len - i[ and processed [ sum_len; [. This is an O(n^2) algorithm. A more efficient O(n) solution would use a hash map from sum to count at the cost of additional code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
size_t duplicate_sum(size_t sum_len, const int sum[sum_len], int duplicate[sum_len]) {
size_t i = 0;
memcpy(duplicate, sum, sum_len * sizeof(*sum));
for(; i < sum_len;) {
int found = 0;
for(size_t j = i + 1; j < sum_len; j++) {
if(duplicate[i] == duplicate[j]) {
found = 1;
swap(duplicate + j, duplicate + sum_len - 1);
sum_len--;
}
}
if(found) {
i++;
} else {
swap(duplicate + i, duplicate + sum_len - 1);
sum_len--;
}
}
return i;
}
void sequence_sum(size_t len, const int sequence[len], int sum[len * (len - 1) / 2]) {
for(size_t i = 0, s = 0; i < len - 1; i++) {
for(size_t j = i + 1; j < len; j++, s++) {
sum[s] = 0;
printf("%zu..%zu: ", i, j);
for(size_t k = i; k <= j; k++) {
printf(" %d", sequence[k]);
sum[s] += sequence[k];
}
printf("%*.0ssum=%d\n", (int) (2 * len - 2 * (j - i)), "", sum[s]);
}
}
}
int main(void) {
int sequence[] = { 1,5,2,4,2,2,2 };
size_t sequence_len = sizeof sequence / sizeof *sequence;
size_t sum_len = sequence_len * (sequence_len - 1) / 2;
int sum[sum_len];
sequence_sum(sequence_len, sequence, sum);
int duplicate[sum_len];
printf("duplicates: ");
size_t duplicate_len = duplicate_sum(sum_len, sum, duplicate);
for(size_t i = 0; i < duplicate_len; i++) {
printf(" %d", duplicate[i]);
}
printf("\n");
and the output:
0..1: 1 5 sum=6
0..2: 1 5 2 sum=8
0..3: 1 5 2 4 sum=12
0..4: 1 5 2 4 2 sum=14
0..5: 1 5 2 4 2 2 sum=16
0..6: 1 5 2 4 2 2 2 sum=18
1..2: 5 2 sum=7
1..3: 5 2 4 sum=11
1..4: 5 2 4 2 sum=13
1..5: 5 2 4 2 2 sum=15
1..6: 5 2 4 2 2 2 sum=17
2..3: 2 4 sum=6
2..4: 2 4 2 sum=8
2..5: 2 4 2 2 sum=10
2..6: 2 4 2 2 2 sum=12
3..4: 4 2 sum=6
3..5: 4 2 2 sum=8
3..6: 4 2 2 2 sum=10
4..5: 2 2 sum=4
4..6: 2 2 2 sum=6
5..6: 2 2 sum=4
duplicates: 6 8 12 10 4
I'm trying to take a N*N 2-D array, have each process be responsible for a number of columns, carry out an action on the elements and gather them back together into a single 2-D array again.
I have managed to divide the columns among the processes, carry out the action and bring them back together using MPI subarrays and Gatherv. However, when I give the program a number of processes that doesn't equally divide into the number of columns, the returned data is misplaced.
With the master matrix being 12x12, I provide four processes and get the correct result back:
FINAL MATRIX
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
1 1 1 2 2 2 3 3 3 4 4 4
When the matrix is still 12x12 and I provide five processes, I get this output:
FINAL MATRIX
1 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 3 3 4 4 5 5
5 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
1 1 1 2 2 2 0 0 0 0 0 0
Can someone inform me as to what I've configured incorrectly for this to be the result? Ultimately, after resolving this, I wish to switch the Gatherv to Allgatherv so that each process has the entire 2-D array locally for further alterations.
Update (11/04/2021)
As suggested by Gilles I have attempted to use column vectors instead but could not find a way in which to recombine with Gatherv. I believe my issue with my current solution may be due to displacements as manually altering these causes changes in the output (populating some of the zero cells).
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void print_matrix (double ** X, int rows, int cols)
{
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j)
printf ("%.0f ", X[i][j]);
printf ("\n");
}
}
double **alloc_2d_array(int m, int n) {
double **x;
int i;
x = (double **)malloc(m*sizeof(double *));
x[0] = (double *)calloc(m*n,sizeof(double));
for ( i = 1; i < m; i++ )
x[i] = &x[0][i*n];
return x;
}
void main(int argc, char *argv[]) {
int n = 12;
int ndims = 2;
int rank, size;
int root_rank = 0;
MPI_Datatype sendsubarray, recvsubarray, resizedrecvsubarray;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Report active to console
printf("Rank: %d, reporting!\n", rank);
// Make master matrix
double ** master_matrix = alloc_2d_array(n, n);
// Set starting values in master matrix
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
master_matrix[i][j] = 0;
}
}
// Calculate sub matrices no. of columns and displacements
int interval, modulus, section_end, section_start, section_length;
int counts[size];
int displs[size];
interval = n/size;
modulus = n % size;
for (int i=0; i < size; i++) {
if (modulus != 0) {
counts[i] = interval+1;
modulus--;
} else {
counts[i] = interval;
}
displs[i] = (i == 0) ? 0 : displs[i-1]+counts[i-1];
}
// Calculate subarray info
int master_size[2] = {n, n};
int subsize[2] = {n, counts[rank]};
int startat[2] = {0, displs[rank]};
// Populate sub matrix in main matrix
for (int i = startat[0]; i < startat[0] + subsize[0]; i++)
for (int j = startat[1]; j < startat[1] + subsize[1]; j++)
master_matrix[i][j] = rank + 1;
// Print adjusted matrix
// printf("ADJUSTED MATRIX\n");
// print_matrix(master_matrix, n, n);
// Create the subarray type for use by each send node (incl. the root):
MPI_Type_create_subarray(ndims, master_size, subsize, startat, MPI_ORDER_C,
MPI_DOUBLE, &sendsubarray);
MPI_Type_commit(&sendsubarray);
// Create the subarray type for use by the receive node (the root):
if (rank == 0) {
MPI_Type_create_subarray(ndims, master_size, subsize, startat, MPI_ORDER_C,
MPI_DOUBLE, &recvsubarray);
MPI_Type_commit(&recvsubarray);
MPI_Type_create_resized(recvsubarray, 0, 1 * sizeof(double),
&resizedrecvsubarray);
MPI_Type_commit(&resizedrecvsubarray);
}
// Gather the send matrices into the receive matrix:
MPI_Gatherv(master_matrix[0], 1, sendsubarray,
master_matrix[0], counts, displs, resizedrecvsubarray,
0, MPI_COMM_WORLD);
if (rank == 0) {
printf("FINAL MATRIX\n");
print_matrix(master_matrix, n, n);
}
MPI_Finalize();
}
Given a number — 4 — I have to output
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
The main code I wrote has an error for direction. According to me, I wrote the correct code, but it only works for 1 and 3 and loops between it — 1 3 1 3 1 3.... it is supposed to work 0 1 2 3 0 1 2 3 0 1.... accordingly in a spiral manner. I would really appreciate if you could help me!
The code I wrote is as follows:
int main()
{
int n;
scanf("%d", &n);
int x=n+(n-1);
int size=x*x;
int t,b,l,r;
t=0;l=0;
b=x-1;
r=x-1;
int i,j;
int res[size];
int index=0;
int dir=0;
while(t<=b && l<=r){
if(dir==0){
for(i=l;i<r;i++){
res[index]=n;
index++;
}
t++;
dir=1;
}
else if (dir==1) {
for(i=t;i<b;i++){
res[index]=n;
index++;
}
r--;
dir=2;
}
else if (dir==2) {
for(i=r;i>l;i--){
res[index]=n;
index++;
}
b--;
dir=3;
}
else if(dir==3){
for(i=b;i>l;i++){
res[index]=n;
index++;
}
l++;
dir=0;
}
n--;
dir=(dir+1)%4;
// printf("%d",dir); if u want to check
}
/* yet to proceed
for(i=0;i<x;i++){
for(j=i;j<x;j=j+x){
printf("%d ",res[j]);
}
printf("\n");
}
*/
return 0;
}
I need to print all possible series that their sum is equal to N;
for example is n == 4 the output should be:
[1, 1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[1, 3]
[2, 1, 1]
[2, 2]
[3, 1]
[4]
My way of thinking to solve this problem was:
print the series that the number i is not in the series
print the series that the number i is in the series, now need to find the sum of N-i.
my code:
#include <stdio.h>
#include <stdlib.h>
void printArr(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
printf(" %d ", arr[i]);
}
printf("\n");
}
void printAllHelper(int* a,int size, int sum, int used,int index) {
if (sum == 0) {
a -= used;
printArr(a, used);
}
else if (sum < 0 || index == size)
{
return;
}
else {
for(int i = 1 ; i <= size ; i ++)
{
printAllHelper(a, size, sum, used, index + 1);
if (i <= sum)
{
*a = i;
}
printAllHelper(a+1, size, sum -i, used +1, index + 1);
}
}
}
void printAll(int num) {
int* myArray = (int*)malloc(num * sizeof(int));
printAllHelper(myArray,num,num,0,0);
}
void main() {
printAll(4);
}
my output:
3 1
3 1
3 1
3 1
3 1
3 1
3 1
3 1
3 1
4
1 3
4
2 2
4
3 1
4
4
1 3
1 1 2
1 3
1 2 1
1 3
1 3
1 3
4
1 3
4
2 2
4
3 1
4
4
2 2
2 1 1
2 2
2 2
2 2
2 2
4
1 3
4
2 2
4
3 1
4
4
3 1
3 1
3 1
3 1
3 1
4
1 3
4
2 2
4
3 1
4
4
4
4
Please try to explain to me your way of thinking, and how you approach this kind of problem, I want to be the very best like no one ever was :(.....
Your reasoning is not quite correct, but your code is almost right. The loop in your else part should be
for(int i = 1 ; i <= sum ; i ++) {
*a = i;
printAllHelper(a+1, size, sum-i, used+1, index+1);
}
With this, I get the output
1 1 1 1
1 1 2
1 2 1
1 3
2 1 1
2 2
3 1
4
The idea is basically: "The numbers sum to sum if the first number i is any number from 1 to sum and the rest of the numbers sum to sum - i."
Also, note that your code shows some room for improvement, e.g. the used and index variables seem a bit redundant. And with not adding numbers larger than sum or smaller than 1, the check whether sum < 0 || index == size is not necessary, either. Thus you also do not need the size parameter. Your printAllHelper could be simplified to something like this:
void printAllHelper(int* a, int sum, int index) {
if (sum == 0) {
printArr(a, index);
} else {
for(int i = 1 ; i <= sum ; i++) {
a[index] = i;
printAllHelper(a, sum-i, index+1);
}
}
}
(Note: C is not my native language, if you see more things to improve, please comment.)
I am trying to get my program to count down after counting up to ten. I have tried to alter the code from counting up to make it count down to no avail.
#include <stdio.h>
void count(int k)
{
if (k > 0) {
count(-k + 1);
printf("%d", k);
}
else {
if (k == 0)
{
printf("%d,", k);
}
else {
count(k + 1);
printf("%d,", -k);
}
}
}
int main(int argc, char ** argv)
{
count(10);
getchar();
return 0;
}
Here is a simple example of the recursion which does this, illustrating Eugene's comment:
#include <stdio.h>
void count(int n) {
if (n > 10) {
printf("\n");
return;
}
printf("%d ", n);
count(n+1);
printf("%d ", n);
}
int main() {
count(0);
printf("\n");
return 0;
}
it counts up on the way into recursion and counts down while it exits it. Actually on the way down it only re-prints the state which it was before diving into the next level:
0 1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1 0
The function can be easy implemented if to use a static local variable inside it. For example.
#include <stdio.h>
void count(unsigned int n)
{
static unsigned int m;
printf("%u ", m);
if (n != m)
{
++m;
count(n);
--m;
printf("%u ", m);
}
}
int main( void )
{
const unsigned int N = 10;
unsigned int i = 0;
do
{
count(i);
putchar('\n');
} while (i++ != N);
return 0;
}
The program output is
0
0 1 0
0 1 2 1 0
0 1 2 3 2 1 0
0 1 2 3 4 3 2 1 0
0 1 2 3 4 5 4 3 2 1 0
0 1 2 3 4 5 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 0
Within the function the static variable m behaves as an index in a for loop (or there will be more suitable a do-while loop).
At first it is initialized implicitly by zero (as any static variable)
static unsigned int m;
You can use the initializer explicitly if you want
static unsigned int m = 0;
then it is changed from 0 to n and afterward backward from n again to 0.
++m; // changing from 0 to n
count(n);
--m; // changing from n to 0