Inverted number pyramid - c

I'm trying to do an inverted triangle with numbers using C. I think the number part of the code is right, but the spacing isn't working.
#include <stdio.h>
//Declare function
int triangle(int n);
//Main
int main(void){
int height;
do{
printf("height:");
scanf("%d", &height);
}while (height < 1 && height > 9);
triangle(height);}
//Function
int triangle(int n)
{
int x,j,linhas, spaces;
//Number of lines
for(linhas = 0; linhas < n; linhas++){
//Print spaces NOT FUC****** WORKING!!!
for(spaces =0; spaces < (linhas + 1); spaces ++){
printf(" ");}
//Fill in the numbers
do{
//Increasing part till n
for (x = 0; x < n; x++){
printf(" %d ", (x+1));}
//Decreasin part from n
for (j = 0; j < (n-1) ; j++){
printf(" %d ", ((n-1) -j));}
//New line after each line
printf("\n");
n--;
}while(n > 0);}}
the output is :
height:5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Anybody can help on the spacing the output should be:
height:5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1

So, the problem are in do loop. You decrease the count (variable n), stay in loop until n>0 and the 'spaces for' do one time. Try doing like this.
int triangle(int n)
{
int x,j,linhas, spaces, m;
//Number of lines
m=n;
for(linhas = 0; linhas < n; linhas++){
for(spaces =0; spaces < linhas; spaces ++){
printf(" ");
}
//do{
for (x = 0; x < m; x++){
printf(" %d ", (x+1));
}
for (j = 0; j < (m-1) ; j++){
printf(" %d ", ((m-1) -j));
}
printf("\n");
m--;
//}while(n > 0);
}
}

Your code is messed up. It should have 2 nested loops, like this:
while (n > 0)
{
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
Then you stuff your spaces inside the 1st nesting layer:
while (n > 0)
{
for (...) // print spaces
{
}
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
However, you have 3 nested layers!
for (linhas ...) // useless code - you should remove it!
{
for (...) // this code is misplaced
{
}
while (n > 0)
{
for (...) // print decreasing
{
}
for (...) // print increasing
{
}
}
}
The outer loop does just on iteration (because on the second iteration n is 0, and it exits). This code is unneeded and confusing - remove it, and then you will see where to place your code that prints spaces.

My five cents.:)
You can output the first digit separatly using symbol * as the field width in the format specifier and an appropriate number.
For example
printf( "%*u", 2 * i + 1, j );
^^^
Here is a demonstrative program
#include <stdio.h>
int main( void )
{
while ( 1 )
{
printf( "Enter the height of the pyramid (0- exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
printf( "\n" );
for ( unsigned int i = 0; i < n; i++ )
{
unsigned int j = 1;
printf( "%*u", 2 * i + 1, j );
while ( !( n - i < j + 1 ) ) printf( " %u", ++j );
while ( --j != 0 ) printf( " %u", j );
printf( "\n" );
}
}
return 0;
}
If to enter sequentially
9 8 7 6 5 4 3 2 1 0
then the program output is
Enter the height of the pyramid (0- exit): 9
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 8
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 7
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 6
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 5
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 4
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 3
1 2 3 2 1
1 2 1
1
Enter the height of the pyramid (0- exit): 2
1 2 1
1
Enter the height of the pyramid (0- exit): 1
1
Enter the height of the pyramid (0- exit): 0

you should try (keeping most of your code)
//Function
int triangle (int n)
{
int x, j, linhas, spaces;
int orig_n = n;
//Number of lines
for (linhas = 0; linhas < n; linhas++)
{
do
{
for (spaces = 0; spaces < (orig_n - n) * 3; spaces++)
{
printf (" ");
}
//Fill in the numbers
//Increasing part till n
for (x = 0; x < n; x++)
{
printf (" %d ", (x + 1));
}
//Decreasin part from n
for (j = 0; j < (n - 1); j++)
{
printf (" %d ", ((n - 1) - j));
}
//New line after each line
printf ("\n");
n--;
}
while (n > 0);
}
}

Related

MPI Gatherv ordering data incorrectly when different 2-D array sizes

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();
}

Printing all permutations of n numbers

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;
}

Is it possible to create a user input number pyramid whereby the pyramid only display from 0 - 9?

I tried editing the loop for counter so that the last line of printf is non negative but I'm not too sure which part of the loop to edit.
#include <stdio.h>
void printPatternHere(int height);
int main() {
int height;
printf("Enter the number of rows: ");
scanf("%d", &height);
printf("printPattern: \n");
printPatternHere(height);
return 0;
}
void printPatternHere(int height) {
int n, c, row, t = 1;
int counter = 0;
for (row = 1; row <= height; row++) {
for (c = 1; c <= height - row; c++)
t = row; // start each line with row number
for (c = 1; c <= row; c++) {
counter++;
if (counter > 9) {
t = t % 10;
}
printf("%d ", t);
t++;
}
for (c = 1 ; c < row; c++) {
t--; //reset row number
}
printf("\n");
}
}
If userinput is 14, its output should be something like this:
1
2 3
3 4 5
4 5 6 7
5 6 7 8 9
6 7 8 9 0 1
7 8 9 0 1 2 3
8 9 0 1 2 3 4 5
9 0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 0 1
2 3 4 5 6 7 8 9 0 1 2 3
3 4 5 6 7 8 9 0 1 2 3 4 5
4 5 6 7 8 9 0 1 2 3 4 5 6 7
Your function is cluttered too much, for loops are more than enough. Code below will be enough. Better to debug to grasp the idea.
// in "main"
printPattern3(height); // wrong function name!
printPatternHere(height); // corrected.
void printPatternHere(int height) {
int c, row;
for (row = 1; row <= height; row++) {
for (c = 0; c < row; c++) {
printf("%d ", (c + row) % 10);
}
printf("\n");
}
}
Your code is too complicated. The output of the pyramid can be done simpler.
For example this loop
for (c = 1; c <= height - row; c++)
t = row; // start each line with row number
does not make a sense.
Here you are.
#include <stdio.h>
int main(void)
{
while ( 1 )
{
const unsigned int Base = 10;
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
for ( unsigned int i = 0; i < n; i++ )
{
for ( unsigned int j = 0; j < i + 1; j++ )
{
printf( "%u ", ( j + i + 1 ) % Base );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
The program output might look like
Enter a non-negative number (0 - exit): 14
1
2 3
3 4 5
4 5 6 7
5 6 7 8 9
6 7 8 9 0 1
7 8 9 0 1 2 3
8 9 0 1 2 3 4 5
9 0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 0 1
2 3 4 5 6 7 8 9 0 1 2 3
3 4 5 6 7 8 9 0 1 2 3 4 5
4 5 6 7 8 9 0 1 2 3 4 5 6 7
Enter a non-negative number (0 - exit): 0
If you want to write a separate function that will output the pattern then the program can look the following way.
#include <stdio.h>
FILE * display_pyramid( unsigned int n, FILE *fp )
{
const unsigned int Base = 10;
for ( unsigned int i = 0; i < n; i++ )
{
for ( unsigned int j = 0; j < i + 1; j++ )
{
fprintf( fp, "%u ", ( j + i + 1 ) % Base );
}
fputc( '\n', fp );
}
return fp;
}
int main(void)
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
putchar( '\n' );
fputc( '\n', display_pyramid( n, stdout ) );
}
return 0;
}

I am stuck with C programming question based on arrays

The question is:
Given a 2-D array A of size M x N . Write a program in C to print A in spiral form starting from bottom right corner in anti-clockwise direction. There must be space after each element. Note the following
1<=M
N<=20
0<=Aij<=1000
Example:
Input
1 8
1 2 3 4 5 6 7 8
Output
8 7 6 5 4 3 2 1
Input
3 3
1 2 3
4 5 6
7 8 9
Output
9 6 3 2 1 4 7 8 5
I have tried it....can anyone help me with this.
#include<stdio.h>
int main()
{
int m,n;
scanf("%d%d",&m,&n) ;
int matrix[m][n] ;
int last_row = (m-1) ;
int last_column = (n-1) ;
int first_row = 0;
int first_column = 0;
int i=0,j=0,r=0,c=0;
while(i<m)
{
while(j<n)
{
scanf("%d",&matrix[i][j]) ;
++j;
} j=0;
++i;
}
while(first_column <=last_column && first_row <= last_row)
{ for( r=last_row ; r>=first_row ; --r)
{ c=last_column;
printf("%d ",matrix[r][c]) ;
} --last_column;
for (c=last_column; c>=first_column ; --c)
{
r=first_row;
printf("%d ",matrix[r][c]) ;
} ++first_row ;
for(r=first_row; r<=last_row; r++)
{
c=first_column;
printf("%d ",matrix[r][c]) ;
} ++first_column;
for(c=first_column ; c<=last_column ; c++)
{
r=last_row;
printf("%d ",matrix[r][c]) ;
} --last_row;
}
return 0;
}
The current output which I am getting is :
Input
8 1
1
2
3
4
5
6
7
8
Output
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
Input
1 8
1 2 3 4 5 6 7 8
Output
8 7 6 5 4 3 2 1 2 3 4 5 6 7

how to use recursion to count down after counting up

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

Resources