Printing two pyramids side by side (ASCII graphics) - c

I am able to crack it up till #symbol but not after that.
I am not aware of logic for implementing two pyramids side by side.
int main()
{
int i, space, n, j, l, k=0;
printf("Enter number excluding 1 and -ve numbers: ");
scanf("%d",&n);
for(i=1; i<=n-1; ++i, k=0)
{
for(j=0;j<(n/2);j++)
{
printf("\t");
}
for(space=1; space<=n-i; ++space)
{
printf(" ");
}
while(k != 2*i-1)
{
printf("* ");
++k;
}//End of upper star pyramid
printf("\n");
}
//logic for #
for(j=1;j<=(n-1);j++)
{
for(l=0;l<(n/2);l++)
{
printf("\t");
}
for(l=1; l<space; ++l)
{
printf(" ");
}
printf("#");
for(l=1; l<=n; l++)
{
printf(" ");
}
printf("#\n");
}
//after that I dont know how to work with two different pyramids side by side
return 0;
}

Here's an attempt...
Have used "#define"s for the characters to be printed.
Have utilized three do-while loops to break the task of printing the top pyramid, the "#"s and the bottom pyramid.
The solution would work for the examples provided or any "Odd" number, provided by the user.
For even numbers,the solution needs to be worked upon(either ways the top of the pyramid would not align at the center for even numbers).
Hope this is helpful.....feel free to play around with the code....
#include <stdio.h>
#define SPACE ' '
#define STAR '*'
#define AT '#'
int main(){
int num = 7;//input from the user, have used 7 as an example
int total_hor_length = num * 3;//# of characters to be printed on each line
int i = num;
int j = 0;
while(i > 0){//calculate the iterations
j++; //required for top and bottom
i -= 2; //Pyramids
}
int first_print = j; //# first loop iteration
int last_print = first_print; //# last loop iteration
int center_print = (num * 2 - 1)-(first_print + last_print);//# center loop
int pos = total_hor_length/2; //position of top of center pyramid
int count = 0;
int k;
i = 0;//re-initialize i for the first loop
//Logic for the Top Pyramid(first loop)
do{
for(k = 0;k < total_hor_length;++k){ //for input "n"
if((k < pos || k > pos+count)) //by the time this loop finishes
printf("%c",SPACE); //pos will be "n-1"
else //and count will be "n+1"
printf("%c",STAR);
}
putchar('\n');
pos--;
count+=2;
i++;
}while( first_print > i);
i = 0;//re-initialize i for the center loop
//Logic for the "#"s (second loop)
do{
for(k = 0;k < total_hor_length;++k){ //utilizing the values of "count"
if((k == count-1 || k == (count-1)+pos)) //and pos procured from the previous
printf("%c",AT); //loop to print the "#"s
else
printf("%c",SPACE);
}
putchar('\n');
i++;
}while(center_print > i);
i = 0;//re-initialize i for the center loop
//Logic for the Bottom Pyramids (Last loop)
do{
for(k = 0;k < total_hor_length;++k){
if(i == 0){
if((k <= pos-i) || (k > pos + num + i && k < total_hor_length - i))
printf("%c",STAR);
else if(k == pos+1||k == pos+num) //printing the line containing
printf("%c",AT); // asterisk and "#" symbols
else
printf("%c",SPACE);
}
else{
if((k >= i && k <= pos-i) || (k > pos + num + i && k < total_hor_length - i))
printf("%c",STAR); //printing the last lines
else
printf("%c",SPACE);
}
}
putchar('\n');
i++;
}while(i < last_print);
}

Related

I need to fix the for loop to print the same shape on the example screen

Basically i have a school task to make a C program that asks user for width input = n and makes the shape of a parallelogram/diamond.
Enter width: 4
/\
/ \
/ \
/ \
\ /
\ /
\ /
\/
This is my output:
Enter width: 4
/
/ \
/ \
/ \
\ /
\ /
\
This is my current code:
#include <stdio.h>
int main() {
int n, i, j, l;
printf("Enter width: ");
scanf("%d", &n);
for (i = 1; i <= n; i++) {
for (j = i; j <= n; j++) {
printf(" ");
}
for (l = 1; l <= 2 * i - 1; l++) {
if (l == 1)
printf("/");
else if (l == (2 * i - 1))
printf("\\");
else
printf(" ");
}
printf("\n"); // novi red
}
for (i = n - 1; i >= 1; i--) {
for (j = n; j >= i; j--) {
printf(" ");
}
for (l = 1; l <= 2 * i - 1; l++) {
if (l == 1)
printf("/");
else if (l == (2 * i - 1))
printf("\\");
else
printf(" ");
}
printf("\n"); // novi red
}
return 0;
}
But it does not print it like the one on the example output. I really tried to fix the problem but i just cant seem to make it work. I think the problem is somewhere in the second for loop just under the middle comment // novi red
Well, working and optimized code:
#include <stdio.h>
void printSpaces(int count);
int main() {
int n;
printf("Enter width: ");
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
printSpaces(n-i);
printf("/");
printSpaces(2*i-2);
printf("\\");
printf("\n"); // new line
}
for (int i = n; i >= 1; i--) {
printSpaces(n-i);
printf("\\");
printSpaces(2*i-2);
printf("/");
printf("\n"); // new line
}
return 0;
}
void printSpaces(int count){
for(int i = 0; i < count; i++){
printf(" ");
}
}
But don't just copy-paste it, read my explanation and tips, because you need to learn few things.
Firstly when you do something more times in your code, than extract that part of code to a function and than call it every time you need that code. This is the principle of functional programming and it makes your code much cleaner and save you a lot of time. In this case I created function to print spaces, because there were many for-loops just to print spaces.
The second main change I did in your code was your for-loop to print a line. I completely replaced it with my code and I will try to explain you why. When you think of your for-loop, it prints / at the first run, than prints spaces and at the end it prints one . And it doesn't really make sense when you do something only at the first run of the loop, because you can just write it before the loop and you get the same result. So instead of:
for(int i = 0; i<n; i++){
if(i==0){
//doSomething
}else{
//doSomethigElse
}
}
Do:
//doSomething
for(int i = 1; i<n; i++){
//doSomethigElse
}
This is much more readable, logical and also faster.
So when I did this correction to your code, I end up with:
for (int i = 1; i <= n; i++) {
printSpaces(n-i);
printf("/");
for (int j = 2; j <= 2 * i - 1; j++) {
printf(" ");
}
printf("\\");
printf("\n"); // new line
}
And because now the for-loop is just printing spaces, I called my printSpaces function instead:
for (int i = 1; i <= n; i++) {
printSpaces(n-i);
printf("/");
printSpaces(2*i-2);
printf("\\");
printf("\n"); // new line
}
But where was your mistake? Well, it was somewhere in the second condition of your if-else, but it doesn't matter that much. Much more important is to write clean and logical code, because than you can find errors and mistakes much more easily. Hope I helped you with your coding style.

Checking monotonic sequences - C programming

I am doing a problem about checking monotonic sequences. The problem is inputting a sequence and then print "YES" if it is monotonic, "NO" if it is not.
This is my code:
#include <stdio.h>
int main()
{
//Inputting the sequence
int n;
scanf("%d", &n);
int a[n];
for (int i = 1; i <= n; i++)
{
scanf("%d ", &a[i]);
}
//Checking monotonic sequence
for (int i = 1; i <= n; i++)
{
if ((a[i] > a[i-1]) && (a[i] > a[i+1]))
{
printf("NO");
return;
}
else if ((a[i] < a[i-1]) && (a[i] < a[i+1]))
{
printf("NO");
return;
}
}
printf("YES");
return 0;
}
I have failed 2 test case with sequences [1, 2, 3] and [10, 6, 4, 2, 1, -100]; and passed one test case with [1, 2, 3, 3, 2, 1]. Can anyone please point out the problem in my code? I would truly appreciate that. Thank you.
Remove trailing " ". It obliges additional input (or end-of-file) after the number is entered before scanf() returns.
// scanf("%d ", &a[i]);
scanf("%d", &a[i]);
In addition to index problems in 2 places, code needs to look for overall monotonic and not just local monotonic behavior.
bool up = true;
bool down = true;
// for (int i = 1; i <= n; i++)
for (int i = 1; i < n; i++) {
if (a[i] > a[i-1]) down = false;
if (a[i] < a[i-1]) up = false;
}
printf((up || down) ? "YES" : "NO");
Additional code to short-circuit loop.
// for (int i = 1; i < n; i++) {
for (int i = 1; i < n && (up || down); i++) {
Further there is lack of the coding goal clarity on tie cases. May need
if (a[i] >= a[i-1]) down = false;
if (a[i] <= a[i-1]) up = false;
a has indices from 0 to n-1; you code references a[0] (which never gets assigned to) and a[n] (which is outside the bounds of the array).
You are checking with invalid array index. here you are declaring an array size of n but you are checking with i+1 that means n+1 for the last case. This is out of bound for your array. First of all you are storing data in array from 1 to n . But when you declare a array size n then it has index from 0 to n-1.so you can store data from 0 to n and start the check from 1 and end in n-1.
this one will work for you:
#include <stdio.h>
int
main ()
{
//Inputting the sequence
int n;
scanf ("%d", &n);
int a[n];
for (int i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
int inc = 0;
int dec = 0;
//Checking monotonic sequence
for (int i = 1; i < n ; i++)
{
if (a[i] > a[i - 1])
{
inc = 1;
}
else if (a[i] < a[i - 1])
{
dec = 1;
}
}
if (inc == 1 && dec == 1)
{
printf ("NO");
}
else
{
printf ("YES");
}
return 0;
}

How can I fill a 2D array spirally in C? Example/problem

so I've been struggling with this example for a good hour now and I can't even begin to process how should I do this.
Write a program that, for given n and m, forms a matrix as described.
The matrix should be m x m, and it's filled "spirally" with it's
beginning in the upper left corner. The first value in the matrix is
the number n. It's repeated until the "edge" of the matrix, at which
point the number increments. After the number 9 goes 0. 0 ≤ n ≤ 9, 0 ≤
m ≤ 9
Some time ago I had made a function to display the numbers 1 to n on an odd-sized grid.
The principle was to start from the center and to shift by ;
x = 1
x box on the right
x box on the bottom
x++
x box on the left
x box at the top
x++
With this simple algorithm, you can easily imagine to maybe start from the center of your problem and decrement your value, it seems easier to start from the center.
Here is the code that illustrates the above solution, to be adapted of course for your problem, it's only a lead.
#define WE 5
void clock(int grid[WE][WE])
{
int count;
int i;
int reach;
int flag;
int tab[2] = {WE / 2, WE / 2}; //x , y
count = 0;
flag = 0;
i = 0;
reach = 1;
grid[tab[1]][tab[0]] = count;
for (int j = 0; j < WE - 1 && grid[0][WE - 1] != pow(WE, 2) - 1; j++)
for (i = 0; i < reach && grid[0][WE - 1] != pow(WE, 2) - 1; i++, reach++)
{
if(flag % 2 == 0)
{
for(int right = 0 ; right < reach ; right++, tab[0]++, count++, flag = 1)
grid[tab[1]][tab[0]] = count;
if(reach < WE - 1)
for(int bottom = 0; bottom < reach; bottom++, count++, tab[1]++)
grid[tab[1]][tab[0]] = count;
}
else
{
for(int left = 0; left < reach; left++, count++, tab[0]--, flag = 0)
grid[tab[1]][tab[0]] = count;
for(int top = 0; top < reach; top++, tab[1]--, count++)
grid[tab[1]][tab[0]] = count;
}
}
}
I finally solved it. If anybody's interested, here's how I did it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Fills the row number "row" with the number n
int fillRow(int m, int n, int arr[m][m], int row)
{
int j;
for(j=0;j<m;j++)
{
if(arr[row][j] == -1 || arr[row][j] == n-1) arr[row][j] = n;
}
}
//Fills the column number "col" with the number n
int fillCol(int m, int n, int arr[m][m], int col)
{
int i;
for(i=0;i<m;i++)
{
if(arr[i][col] == -1 || arr[i][col] == n-1) arr[i][col] = n;
}
}
int main()
{
int n, m, i, j, r=1, c=1, row=-1, col=-1;
scanf("%d %d",&n, &m);
int arr[m][m];
//Fill array with -1 everywhere
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
arr[i][j] = -1;
}
}
//Calculate which row/column to fill (variables row/col)
//Fill row then column then row than column...
for(i=0;i<2*m;i++)
{
if(i%2==0)
{
row = (r%2==0) ? m-r/2 : r/2;
fillRow(m, n, arr, row);
n++;
r++;
}
else if(i%2==1)
{
col = (c%2==0) ? c/2-1 : m-c/2-1;
fillCol(m, n, arr, col);
n++;
c++;
}
}
//If an element is larger than 9, decrease it by 10
//Prints the elements
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
if(arr[i][j]>9) arr[i][j] -=10;
printf("%d ",arr[i][j]);
}
printf("\n");
}
return 0;
}

I want to print c pattern as upper triangle

I want to print some C pattern for upper triagnle which sholud print numeric value 1 to 10.
Now my code is like this:-
#include <stdio.h>
int main() {
int j = 1, k, l, i;
for (i = 4; i >= 1; i--) {
for (k = i - 1; k >= 0; k--) {
printf(" ");
}
for (l = 4; l >= i; l--) {
printf("%2d", j);
j++;
}
printf("\n");
}
return 0;
}
Its output is fine but when my value reach near 10 it's space is missing.
How can I resolve it?
My output looks like
1
2 3
4 5 6
7 8 910
It should be:
1
2 3
4 5 6
7 8 9 10
You can change the alignment by using the - sign. This makes it left-justified.
Replace
printf("%2d",j);
with
printf("%-2d",j);
Live demo
If you want the bottom of the pyramid to be completely to the left with no space you can replace
for (k = i - 1; k >= 0; k--)
with
for (k = i - 1; k > 0; k--)
EDIT:
As #chqrlie pointed out this will leave a trailing blank space in every line except the last one, this can be fixed like:
//...
for (i = 4; i >= 1; i--)
{
for (k = i - 1; k > 0; k--) // change from k >= 0 to k > 0
{
printf(" ");
}
for (l = 4; l >= i; l--)
{
printf(" %d", j); // change from "%2d" to " %d"
j++;
}
printf("\n");
}
//...
Live demo
For this problem, with n lines of output, you need to produce n - i spaces at the beginning of line i and i numbers each preceded by a space. Instead of "%2d", use " %d" and output one less space at the start of each line. You can use printf to output an arbitrary number of spaces using %*s and an empty string.
Here is a modified version:
#include <stdio.h>
int main() {
int i; // line number
int j = 1; // starting number
int n = 4; // number of lines
int k;
for (i = 1; i <= n; i++) {
printf("%*s", n - i, ""); // output n - i spaces
for (k = 0; k < i; k++) {
printf(" %d", j);
j++;
}
printf("\n");
}
return 0;
}
Output:
1
2 3
4 5 6
7 8 9 10
It can be solved in two ways:
One way to resolve this is by simply add spacing (padding) for each character you are printing.
#include<stdio.h>
int main()
{
int j=1,k,l,i;
for(i=4;i>=1;i--){
for(k=i-1;k>=0;k--){
printf(" ");
}
for(l=4;l>=i;l--){
printf(" %2d ",j); //Padding added
^ ^
j++;
}
printf("\n");
}
return 0;
}
Secondly you can change the alignment by using - sign
#include<stdio.h>
int main()
{
int j=1,k,l,i;
for(i=4;i>=1;i--){
for(k=i-1;k>=0;k--){
printf(" ");
}
for(l=4;l>=i;l--){
printf("-%2d",j); //Left justified
^
j++;
}
printf("\n");
}
return 0;
}
Amongst the other good answers, another way is to use printf("%d ", j); instead of printf("%2d", j); - Note the white space ' ' behind the %d format specifier. - This method has the disadvantage that you have a trailing white space after 10 but it accomplishes the (obvious) desired output:
Online example
#include <stdio.h>
int main (void)
{
int j = 1, k, l, i;
for (i = 4; i >= 1; i--){
for (k = i - 1; k >= 0; k--) {
printf(" ");
}
for(l = 4; l >= i; l--) {
printf("%d ", j);
j++;
}
printf("\n");
}
return 0;
}
Output:
1
2 3
4 5 6
7 8 9 10

Program suddenly has a spike in cpu usage and looks like it is paused

I have added 2 functions:
int aiCheckScore(char arr[7][7], int inp, int height, Player player)
int aiFindMostRelevant(char arr[7][7], Player player)
The first makes a score for a given position in a 2D array. The score is equal to how many of the same kind elements we would have in a row (vertically, horizontally or diagonally and it keeps the best one of those 3) if we added one in this position (excluding the one we add just now)
The second function checks 7 positions at a time and finds the one with the best score and returns that. I tried to add a little randomness and make it so that if 2 positions have the same score the program would choose the last one 30% of the time (so that it wouldn't always take the first one).
Without the bit where I add the randomness the code runs just fine. As soon as I add it the program halts right after it calls for the 12th time the first function. Furthermore, the CPU usage from the program suddenly spikes and remains at 50% from below 5% it was before.
I have modified the code which creates the randomness a couple of times but nothing seems to change. I can't even comprehend why it would cause such an issue.
My 2 functions are:
int aiCheckScore(char arr[7][7], int inp, int height, Player player) {
int i, j;
int score[4] = { 0 };
//check horizontal score
for (i = inp - 1; i >= 0; i--) { //everything left
if (arr[height][i] != player.symb)
break;
++score[0];
}
for (i = inp + 1; i <= 6; i) { //everything right
if (arr[height][i] != player.symb)
break;
++score[0];
}
//check vertical score (we only have to check down)
for (i = height + 1; i <= 6; i++) {
if (arr[i][inp] != player.symb)
break;
++score[1];
}
//check diagonal (which starts left and above and goes down and right)
j = height - 1;
for (i = inp - 1; i >= 0 && j >= 0; i--) { //above and left
if (arr[j][i] != player.symb)
break;
++score[2];
--j;
}
j = height + 1;
for (i = inp + 1; i <= 6 && j <= 6; i++) { //down and right
if (arr[j][i] != player.symb)
break;
++score[2];
++j;
}
//check diagonal (which starts left and down and goes up and right)
j = height + 1;
for (i = inp - 1; i >= 0 && j <= 6; i--) { //down and left
if (arr[j][i] != player.symb)
break;
++score[3];
++j;
}
j = height - 1;
for (i = inp + 1; i <= 6 && j >= 0; i++) { //up and right
if (arr[j][i] != player.symb)
break;
++score[3];
--j;
}
int bestscore = score[0];
for (i = 0; i <= 3; i++) {
if (score[i] > bestscore)
bestscore = score[i];
}
printf("%d", bestscore);
return bestscore;
}
int aiFindMostRelevant(char arr[7][7], Player player) {
int i, height;
int score[7] = { 0 };
for (i = 0; i <= 6; i++) {
height = findHeight(arr, i);
if (height == -1) {//skip the columns that are full
score[i] = -100; //and give them a very bad score
}
else {
score[i] = aiCheckScore(arr, i, height, player);
}
}
int bestscore = score[0];
int bestposition = 0;
int num;
for (i = 0; i <= 6; i++) {
num = (int)rand() % 10;
if (score[i] == bestscore) { //if 2 positions have the same score
if (num >= 7) { //there is a 30% chance the ai will take the new one to add some variety
bestposition = i;
}
}
if (score[i] > bestscore) { //always take the position with the best score
bestscore = score[i];
bestposition = i;
}
}
return bestposition;
}
Any help solving this problem would be greatly appreciated and any suggestions to generally improve my code are welcome
Looks like there is no increment in one of the loops.
Change:
for (i = inp + 1; i <= 6; i) to for (i = inp + 1; i <= 6; ++i)
and see if it helps.

Resources