I'm trying to write a program to display Pascal's triangle up to a user-inputted number of levels. We aren't allowed to use the factorial method. My current code is this:
#include <stdio.h>
void trianglePrint(const int numLevels);
int main() {
int numLevels;
printf("Please enter how many levels of Pascal's Triangle you would
like to see: ");
scanf("%d", &numLevels);
trianglePrint(numLevels);
return 0;
}
void trianglePrint(const int numLevels) {
int pascalTriangle[28][28];
int i, j;
for (i = 0; i < numLevels; ++i) {
for (j = 0; j <= i; ++j) {
if (i == 0 || i == 1 || j == 0 || j == numLevels) {
pascalTriangle[i][j] = 1;
printf("%d ", pascalTriangle[i][j]);
}
else {
pascalTriangle[i][j] = pascalTriangle[i - 1][j - 1] +
pascalTriangle[i - 1][j];
printf("%d ", pascalTriangle[i][j]);
}
}
printf("\n");
}
}
We're only supposed to be able to go up to 28 levels, which is why I am using an array of size 28 in both dimensions.
This works fine for about 6 levels of the triangle, but for larger levels it gives really large integers. I assumed it was due to uninitialized arrays, but I'm not sure. Does anyone know where the error is?
If you change
if (i == 0 || i == 1 || j == 0 || j == numLevels)
to
if (i == 0 || i == 1 || j == 0 || j == i)
(thanks to Melpomene), then all accesses to your array end up on already intiailised members.
That solves the strange numbers.
Output:
Please enter how many levels of Pascal's Triangle you would like to see: 6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Process returned 0 (0x0) execution time : 2.264 s
Press any key to continue.
Note:
Also initialising an array is a wise precaution. You could initialise with values which help finding an error, instead of hiding it, e.g. 42.
The problem is that you haven't set pascalTriangle[i - 1][j] before you use it to compute pascalTriangle[i][j] in the else clause.
Try the code
void Pascal(int n)
{
int arr[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
// First and last values in every row are 1
if (i == j || j == 0)
arr[i][j] = 1;
else // Other values are sum of values just above and left of above
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
Related
You are allowed to enter only 0 and 1 as values in the arrays. Then in place of all elements having a value of 0, enter the number of elements with a value of 1 around that element in all eight directions. And on the end print the 2d array and the values with 1 change to *.
Here is an example how it's supposed to look like:
Here is my code
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,m;
scanf("%d%d", &n, &m);
int a[n][m];
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
scanf("%d", &a[i][j]);
if(a[i][j]==1){
a[i][j]=9;
}
}
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
int counter=0;
if(a[i][j]==9){
printf("*\t");
}else if(a[i][j]==0){
if(a[i+1][j+1]==9 && i!=n && j!=m) counter++;
if(a[i-1][j-1]==9 && i!=0 && j!=0) counter++;
if(a[i+1][j-1]==9 && i!=n && j!=0) counter++;
if(a[i-1][j+1]==9 && i!=0 && j!=m) counter++;
if(a[i][j+1]==9 && j!=m) counter++;
if(a[i][j-1]==9 && j!=0) counter++;
if(a[i+1][j]==9 && i!=n) counter++;
if(a[i-1][j]==9 && i!=0) counter++;
a[i][j]=counter;
counter=0;
printf("%d\t", a[i][j]);
}
}
printf("\n");
}
return 0;
}
You have UB (undefined behavior).
With (e.g.):
if (a[i + 1][j + 1] == 9 && i != n && j != m)
Then, a is always fetched, even if i or j is out of range.
To fix this, reorder the terms:
if (i != n && j != m && a[i + 1][j + 1] == 9)
Now, if either i or j is out of range, then the if will be "short circuited": (i.e. _short circuit evaluation) and the a value will not be fetched.
But, your program output is incorrect. You're coding everything out longhand. It makes it hard to debug (i.e. which lines have a bug).
What wasn't explicitly described was that you are summing the non-zero values in a 3x3 kernal around a given zero point.
The hardcoding doesn't scale too well. Suppose the kernal had to be 100x100. Would we code up 10,000 lines of code?
It's much easier to debug if we refactor to use for loops. And, to use more descriptive names instead of i/j/m/n:
n hgt
m wid
i y*
j x*
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc,char **argv)
{
int hgt, wid;
int counter;
FILE *xf;
--argc;
++argv;
if (argc > 0)
xf = fopen(*argv,"r");
else
xf = stdin;
if (xf == NULL) {
perror(*argv);
exit(1);
}
fscanf(xf,"%d%d", &hgt, &wid);
int a[hgt][wid];
for (int ycur = 0; ycur < hgt; ycur++) {
for (int xcur = 0; xcur < wid; xcur++) {
int val;
fscanf(xf,"%d", &val);
if (val == 1)
val = 9;
a[ycur][xcur] = val;
}
}
for (int yctr = 0; yctr < hgt; yctr++) {
for (int xctr = 0; xctr < wid; xctr++) {
if (a[yctr][xctr] == 9) {
printf("*\t");
continue;
}
counter = 0;
for (int yoff = -1; yoff <= 1; yoff++) {
int ycur = yctr + yoff;
if (ycur < 0)
continue;
if (ycur >= hgt)
continue;
for (int xoff = -1; xoff <= 1; xoff++) {
int xcur = xctr + xoff;
if (xcur < 0)
continue;
if (xcur >= wid)
continue;
counter += (a[ycur][xcur] == 9);
}
}
printf("%d\t",counter);
}
printf("\n");
}
return 0;
}
Here is the program output for your sample input:
* 1 1 2 *
2 2 2 * 3
* 1 2 * 2
Not sure what the question is, but there are bugs in the code -
you are accessing out of array boundaries by doing, for example, this:
if(a[i-1][j-1]==9 && i!=0 && j!=0)
When i and j are zeros you are reading the value of a[-1][-1]. Changing the order of conditions and checking i and j first would guard against such an access.
Same happens when you access the "borders" of the matrix.
And, the "i!=n && j!=m" condition is always true within the loops - you iterate as long as i<n and j<m.
But aside of that, some of these accesses in fact read from within the array, but from a wrong location.
Here is an example that shows that:
Given the matrix of 2x2
0 1
1 0
This is the result your code produced:
2 *
* 3
Where obviously, '3' is wrong.
Why it happened?
The 2D array is in fact stored as a 1D array in memory, like this:
0 1 1 0 // this is your data
0 1 2 3 // this is the index in the array (offset from the array start)
And each element is located at an offset of row*columns+column from the array start (i.e. this is the formula to find the index in 1D array given i and j).
When you count the '1'-neighbours for the last element (a[1][1] in this example), you count the two obvious results (at a[1][0] and a[0][1]), but then you hit this condition:
if(a[i-1][j+1]==9 && i!=0 && j!=m)
For this last cell, i is 1 and j is 1, so the second part of the condition is true.
But what about a[i-1][j+1]==9 ?
This references a memory at row*columns+column, right? I.e. (i-1)*2+(j+1), because that's what you tried to access. Substituting i and j with 1 and 1, and you get offset 2 in the 1D array above.
Which is 1 in the input matrix (or actually 9 since you've replaced it).
So you count it twice.
Guarding better against "stepping out" of the matrix (but not necessarily out of the actual array) will solve this bug.
Im a beginner programmer and i needed some help with making the result of the following exercise look a bit better.
As i said in the title i want to make the exercise look nicer by removing the 0-s from the array and leaving just the numbers.
The exercise goes like this:
We enter an array of integers and we copy into the 2nd array the integers that are positive and negative and multiples of 3 and in the 3rd array the negative elements that are odd and not multiples of 3. This is the code that I did:
#include <stdio.h>
#include <stdlib.h>
#define N 5
int main()
{
int v[N];
int v2[N] = {0, };
int v3[N] = {0, };
int i;
printf("Please enter the elements of the 1st array: ");
for (i = 0; i < N; i++)
{
scanf("%d", &v[i]);
}
printf("\nThe elements of the 2nd array are: ");
for (i = 0; i < N; i++)
{
if ((v[i] >= 0 || v[i] <= 0) && v[i] % 3 == 0)
{
v2[i] = v[i];
}
}
for (i = 0; i < N; i++)
{
printf("%d ", v2[i]);
}
printf("\nThe value of the 3rd array are : ");
for (i = 0; i < N; i++)
{
if (v[i] <= 0 && v[i] % 2 != 0 && v[i] % 3 != 0)
{
v3[i] = v[i];
}
}
for (i = 0; i < N; i++)
{
printf("%d ", v3[i]);
}
return 0;
}
For future use if possible how to do I post a code copied for code blocks directly into here without using space 4 times on every line?
Thanks in advance
Another option is to insert a condition in the output loop:
for (i = 0; i < N; i++)
{
if (v2[i] != 0)
{
printf("%d ",v2[i]);
}
}
Apologies for the title, but I could not find a similar question that has already been posed. As implied, my question is how to implement a counter which starts at an initial value and increments upwards until a specific point is reached, then decrements back down to the original value. Allow me to provide an example to better suggest showcase what I mean
#include <stdio.h>
int main(void) {
int i = 0;
for(i = 0; i <= 10; i++) {
printf("i = %d\n", i);
if(i == 5) {
int j = i;
for(j = i; j >= 0; j--) {
printf("j = %d\n", j);
}
}
}
return 0;
}
When run, the program will print values 0-5 for i, then print 5-0 for j and then finish printing 6-10 for i. Instead of this, I just want to have the program print 0-5 for i and then 5-0 for i (or j if another variable is needed).
You could use two separate loops like Rafalon in the comments suggested.
If you want one loop you can do something like this (modified it with the information from OPs comment):
int ctr_dir = 80;
int upper_value = 500;
for(int i = 0; i >= 0; i += ctr_dir)
{
printf("%d", i);
if (i > upper_value)
ctr_dir = -80;
}
You are making this needlessly complicated.
for(int i=0; i<6; i++) // print 0 to 5
{
printf("%d\n", i);
}
for(int i=0; i<6; i++) // print 5 to 0
{
printf("%d\n", 5-i);
}
Whilst I don't fully understand the reasons behind the way you've written the code, the missing ingredient from it is a break inside the if statement which will exit the loop rather than continuing on and printing out 6 to 10.
for(i = 0; i <= 10; i++) {
printf("i = %d\n", i);
if(i == 5) {
int j = i;
for(j = i; j >= 0; j--) {
printf("j = %d\n", j);
}
break; // Exit the loop
}
}
I think simple is best, but you said "my problem is more complex" (I don't know how much more !?), I wrote a more "complex" version...
You can do this something like this,
But the problem with this code is overshoots. i.e. if step is more than 1, you can pass maximum value. :)
#include <stdio.h>
void WaveGenerator(int start, int step, int max, int times)
{
int value = start;
times *= 2;
printf("%d", value);
while(times)
{
value += step;
if ((value <= start) || (value >= max))
{
step *= -1;
times--;
}
printf("%d", value);
}
}
int main()
{
int i;
WaveGenerator(1, 1, 5, 2);
return 0;
}
There have been many different solutions here, including the one I already posted as a comment.
Let me add another one here, similar to #izlin's but yet different:
int i=0;
int j=0;
int max=10;
for(i=0;i<=max;i++)
{
printf("%d\n", j);
if(i<max/2)
j++;
else
j--;
}
// max=10 > 0 1 2 3 4 5 4 3 2 1 0
// max=11 > 0 1 2 3 4 5 4 3 2 1 0 -1
Note that depending on the parity of max, this will go down to either 0 or -1.
This can be tweaked this way:
int i=0;
int j=0;
int max=10;
for(i=0;i<=max;i++)
{
Console.WriteLine(j);
if(i<max/2)
j++;
else if(i>(max-1)/2)
j--;
}
// max=10 > 0 1 2 3 4 5 4 3 2 1 0
// max=11 > 0 1 2 3 4 5 5 4 3 2 1 0
so it writes the top number twice if max is odd, and once if it is even, but always starts and ends with 0.
I would however still use 2 loops instead, as I suggested in my comment:
int i=0;
int max=5;
for(i=0;i<=max;i++)
{
printf("%d\n", i);
}
// 0 1 2 3 4 5
for(i=max;i>=0;i--)
{
printf("%d\n", i);
}
// 5 4 3 2 1 0
Since the work you want to perform is the same whether you are going up or down, you don't want to use separate loops as you'd be repeating yourself.
You can do this in a single loop by using a flag that indicates whether you've hit the upper limit. If the flag isn't set you increment, if it is you decrement.
int increment = 5, limit = 50;
int i = 0, go_back = 0;
while (i>=0) {
printf("%d\n", i);
if (i >= limit) {
go_back = 1;
}
if (go_back) {
i -= increment;
} else {
i += increment;
}
}
My function:
int checkSE(disk board[][SIZE], disk hypotheticalDisk)
{
int i;
int j;
int row;
int col;
int player;
int opponent;
int checkSEflag;
player = hypotheticalDisk.type;
(player == 0) ? (opponent = 1) : (opponent = 0);
row = hypotheticalDisk.pos.row;
col = hypotheticalDisk.pos.col;
checkSEflag = 0;
for (i = row + 2, j = col + 2; ((i < SIZE) && (j < SIZE) && (checkSEflag == 0)); i++, j++)
{
if (board[i][j].type == player)
{
for (--i, --j; board[i][j].type == opponent; i--, j--)
{
if (i == row && j == col)
{
checkSEflag = 1;
break;
}
}
}
printf("\n%d and %d and %d", i, j, checkSEflag);
}
return checkSEflag;
}
My output:
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
2 and 3 and 0
.
.
.
And it keeps on going...
I want both i and j to increase until they are equal to SIZE (SIZE predefined to be 8) or until checkSEflag is assigned to be equal to 1.
It looks like the values of i and j just aren't being changed...
I tried taking them out of the loop conditions and instead placed them
in the loop body, though that didn't change anything.
I doubt the post increment operators just decided to not work so I must be doing something wrong, any ideas of what that may be?
These two lines:
for(i = row+2, j = col+2; ((i < SIZE) && (j <SIZE) && (checkSEflag == 0)); i++, j++)
...
for(--i, --j; board[i][j].type == opponent; i--, j--)
so, you are both incrementing and decrementing (i,j); try sprinkling printfs around these and see if you are both incrementing and decrementing i,j on each iteration...
Recently, someone asked me to make a C program that "groups" (his words, not mine!) numbers into pairs.
Here's how it works.
First, the user inputs the maximum range:(let's say) 10
Now, user inputs a number: (let's say) 4.
Then, the program groups 4 and 5 together. (ie. n and n+1)
Next User Input: 8
The program groups 8 and 9 as well.
Now, this goes on.
Exceptions: If the user enters a number that has already been grouped, like 4,5,8 or 9. Then the group which it belongs to gets removed altogether. Also, the program invalidates inputs that require pairing with numbers that are already paired. Eg. If 4 and 5 are paired, 3 is not a valid input.
Also, entering the extremes (here, 1 and 10) is not allowed.
I made the above program in C, using Visual Studio 2013. I have provided the code below.
My questions are:
A) How could I have made my code considerably better?(Apart from initializing the array AFTER accepting the max input)
B) More importantly, can someone tell me what this algorithm is? Is this a standard problem? Does it have any real world application/implementation? Or is it just some random idea?
#include<stdio.h>
#inlcude<conio.h>
#define array_size 10
int group[array_size][2] = { 0 };
int n = 0, max=0, search = 0, max_mem = 0;
int tcount = 2;
void sort(int x[][2]);
void print_groups();
void test_print();
void main()
{
group[0][0] = 0;
group[0][1] = 1;
printf("Enter a number:");
scanf_s("%d", &max);
max_mem = (max/2)+1;
if (max_mem > array_size)
{
printf("Not enough memory assigned!");
return;
}
else
{
group[max_mem-1][0] = max;
}
print_groups();
test_print();
while (1)
{
printf("Enter a number:");
scanf_s("%d", &n);
if ((n <= 1) || (n >= max-1))
{
printf("Invalid entry!");
continue;
}
search = 0;
for (int i = 1; i < max_mem; i++)
{
for (int j = 0; ((j < 2)&&(search!=1)); j++)
{
if (n == group[i][j])
{
group[i][0] = 0;
group[i][1] = 0;
search = 1;
}
if (group[i][0]==n+1)
{
printf("Already group exists -> (%d,%d)", group[i][0], group[i][1]);
//getch();
search = 1;
}
}
}
if (search != 1)
{
group[1][0] = n;
group[1][1] = n + 1;
}
printf("\nSorting!\n");
sort(group);
//clrscr();
print_groups();
test_print();
}
}
void sort(int x[][2])
{
int i, j, t[1][2];
for (i = 1; i <= max_mem - 2; i++)
for (j = 2; j <= max_mem-1 - i; j++)
if (x[j - 1][0] >= x[j][0])
{
t[0][0] = x[j - 1][0];
x[j - 1][0] = x[j][0];
x[j][0] = t[0][0];
t[0][1] = x[j - 1][1];
x[j - 1][1] = x[j][1];
x[j][1] = t[0][1];
}
}
void print_groups()
{
printf("The group is:\n%d ", group[0][1]);
for (int i = 1; i < max_mem-1; i++)
{
if (group[i][0] != 0)
{
printf("(");
printf("%d,", group[i][0]);
printf("%d", group[i][1]);
printf(")");
}
}
printf(" %d.", group[max_mem - 1][0]);
printf("\n");
}
void test_print()
{
printf("Array Formation:\n");
for (int i = 0; i < array_size; i++)
{
printf(" %d,%d ", group[i][0], group[i][1]);
}
printf("\n");
}
Sounds like it's just some random idea. You can simplify your code by using a one-dimensional array, where each entry in the array is
0 for numbers not in a group
1 for the first number of a group
2 for the second number of a group
For example, if array[4] is 1 and array[5] is 2, then 4 and 5 are a group.
When the user enters a new number, it's easy to update the array. Here's an example in pseudo-code of how the array would be updated if the user enters the number 7
if (array[7] == 0 and array[8] == 0)
array[7] = 1, array[8] = 2
else if (array[7] == 0 and array[8] == 1)
input is invalid
else if (array[7] == 1)
array[7] = 0, array[8] = 0
else if (array[7] == 2)
array[6] = 0, array[7] = 0