Multiple Ternary in C with comma? - c

so I saw this code
b[2080];
main(j) {
for (;;) {
printf("\x1b[H");
for (j = 1; j < 2080; j++)
b[j] = j < 2000 ? (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5 : rand() % 4 ? 0 : 512, j < 1840 ? putchar((j % 80) == 79 ? '\n' : " .:*#$H#" [b[j] >> 5]) : 0;
usleep(20000);
}
}
so I tried to rewrite it, why even divide 32?
The array got to declare as global else it won't work. any idea?
also why 512?
here is my attempt so far, any problem?
for (int j = 1; j < 2080; j++)
{
if (j < 2000) {
b[j] = (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5;
}
else if (rand() % 4 != 0) { // Generate random integers in range 0 to 4
b[j] = 0;
}
else
{
b[j] = 512;
}
}
}

Here's the functionally equivalent code with the ternary operators converted into if/else statements:
if (j < 2000) {
b[j] = (b[j + 79] + b[j + 80] + b[j] + b[j - 1] + b[j + 81]) / 5;
} else if (rand() % 4) {
b[j] = 0;
} else {
b[j] = 512;
}
if (j < 1840) {
if ((j % 80) == 79) {
putchar('\n');
} else {
putchar(" .:*#$H#"[b[j] / 32]);
}
}
As for the question of what does the right shift >> 5 do, it divides by 32 (25), and then indexes the array " .:*#$H#" with that divided value.
edit: As for why the array is global, it's probably just to get it initialised to zero without extra code (the whole thing seems to be written as short as possible, e.g., using implicit int types and j from the argument).
Note that there is an access out of bounds bug in the (original) code: b[j + 81] can be accessed when j is 1999 (since that is < 2000), but 1999 + 81 == 2080, and b[2080] is out of bounds. You can replace the array with a local int b[2081] = { 0 }; but it changes the output slightly while fixing the bug.

Related

Matrices and coordinate system

How can I draw the function x+y=n with n not greater than 10 and the coordinate system using only matrices without any functions or libraries? I am a beginner and I hope you could help me.The only problem is that my code prints spaces above the line x+y=n and it should not.
#include <stdio.h>
int
main()
{
int n, i, j;
scanf("%d", &n);
char m[12][63] = { " " };
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
m[i][j] = ' ';
if (i == 0 && j == 1)
m[i][j] = '0';
if (i == 11 && j == 61)
m[i][j] = '2';
if (j == 0 && i != 0 && i != 11)
m[i][j] = '0' + 10 - i;
if (j == 2 && i != 11)
m[i][j] = '+';
if (i == 11 && j % 3 == 2)
m[i][j] = '0' + ((j - 2) / 3) % 10;
if (i == 11 && j % 3 == 1 && j > 29 && j < 59)
m[i][j] = '1';
if (i == 10 && j % 3 == 2)
m[i][j] = '+';
}
}
for(i=1;i<n+1;i++){
if((10-n+i)!=10 && (2+3*i)!=1)
m[10-n+i][2+3*i]='*';
}
m[0][0]='1';
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
printf("%c", m[i][j]);
}
printf("\n");
}
}
//n=5
10+
9 +
8 +
7 +
6 +
5 +
4 + *
3 + *
2 + *
1 + *
0 + + + + + + + + + + + + + + + + + + + + +
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
So first of all its quite difficult for me to understand your logic behind the if statements in the for loop.
With that said, to get the desired 10+ on the y-axis i set m[0][0] = '1'; which seems to work.
As for drawing the line, it seems that:
if (j == 3 * (n + i - 10) && i > 2 && j > 2) m[i][j] = '*';
was causing the issues. I replaced it with:
m[10 - n][2] = '*';
for (i = 1; i < n+1; i++)
{
m[10 - n + i][2 + 3 * i] = '*';
}
and it works fine and in a more understandable way hopefully!
So in the end the code should look like this:
#include<stdio.h>
int main()
{
int n, i, j;
scanf("%d", &n);
char m[12][63] = { " " };
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
m[i][j] = ' ';
if (i == 0 && j == 1) m[i][j] = '0';
if (i == 11 && j == 61) m[i][j] = '2';
if (j == 0 && i != 0 && i != 11) m[i][j] = '0' + 10 - i;
if (j == 2 && i != 11) m[i][j] = '+';
if (i == 11 && j % 3 == 2) m[i][j] = '0' + ((j - 2) / 3) % 10;
if (i == 11 && j % 3 == 1 && j > 29 && j < 59) m[i][j] = '1';
if (i == 10 && j % 3 == 2) m[i][j] = '+';
// if (j == 3 * (n + i - 10) && i > 2 && j > 2) m[i][j] = '*';
}
}
m[10 - n][2] = '*'; // sets + on y-axis to *
for (i = 1; i < n+1; i++)
{
m[10 - n + i][2 + 3 * i] = '*'; // draws * diagonally jumping 3 characters (thus 3*i)
}
m[0][0] = '1'; // to have 10 instead of 0 at the top left
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
printf("%c", m[i][j]);
} printf("\n");
}
}
For n=7 for example you get the desired:
10+
9 +
8 +
7 *
6 + *
5 + *
4 + *
3 + *
2 + *
1 + *
0 + + + + + + + * + + + + + + + + + + + + +
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
To not delete the + by the * just offset the line to the right:
m[10 - n][3] = '*';
for (i = 1; i < n+1 ; i++)
{
m[10 - n + i ][3 + 3 * i] = '*'; // draws * diagonally jumping 3 characters (thus 3*i)
}
m[0][0] = '1'; // to have 10 instead of 0 at the top left
So the n=7 example should now look:
10+
9 +
8 +
7 +*
6 + *
5 + *
4 + *
3 + *
2 + *
1 + *
0 + + + + + + + +* + + + + + + + + + + + + +
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
In order to not print chars above or after the line try this:
#include <stdio.h>
int main()
{
int n, i, j;
scanf("%d", &n);
char m[12][63] = { " " };
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
m[i][j] = ' ';
if (i == 0 && j == 1)
m[i][j] = '0';
if (i == 11 && j == 61)
m[i][j] = '2';
if (j == 0 && i != 0 && i != 11)
m[i][j] = '0' + 10 - i;
if (j == 2 && i != 11)
m[i][j] = '+';
if (i == 11 && j % 3 == 2)
m[i][j] = '0' + ((j - 2) / 3) % 10;
if (i == 11 && j % 3 == 1 && j > 29 && j < 59)
m[i][j] = '1';
if (i == 10 && j % 3 == 2)
m[i][j] = '+';
}
}
for (i = 1; i < n + 1; i++) {
if ((10 - n + i) != 10 && (2 + 3 * i) != 1)
m[10 - n + i][2 + 3 * i] = '*';
}
m[0][0] = '1';
for (i = 0; i < 12; i++)
{
for (j = 0; j < 63; j++)
{
if ((i < 10 - n) || (j > 2 + 3 * n))
{
m[i][j] = '\0';
}
}
}
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
printf("%c", m[i][j]);
}
printf("\n");
}
}
and for n=5 you get:
5 +
4 + *
3 + *
2 + *
1 + *
0 + + + + + +
0 1 2 3 4 5
Hope this helps!

How to delete spaces in matrix?

My task is to draw a coordinate system and line y+x=n, for n<=10.My code gives the correct result, but there is a condition that spaces or any other signs cannot be drawn after the line x+y=n. That is the only problem I have in solving this task and I hope you could help. I am a beginner.
(The only problem is that my code prints spaces above the line x+y=n and it should not)
#include <stdio.h>
int
main()
{
int n, i, j;
scanf("%d", &n);
char m[12][63] = { " " };
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
m[i][j] = ' ';
if (i == 0 && j == 1)
m[i][j] = '0';
if (i == 11 && j == 61)
m[i][j] = '2';
if (j == 0 && i != 0 && i != 11)
m[i][j] = '0' + 10 - i;
if (j == 2 && i != 11)
m[i][j] = '+';
if (i == 11 && j % 3 == 2)
m[i][j] = '0' + ((j - 2) / 3) % 10;
if (i == 11 && j % 3 == 1 && j > 29 && j < 59)
m[i][j] = '1';
if (i == 10 && j % 3 == 2)
m[i][j] = '+';
}
}
for(i=1;i<n+1;i++){
if((10-n+i)!=10 && (2+3*i)!=1)
m[10-n+i][2+3*i]='*';
}
m[0][0]='1';
for (i = 0; i < 12; i++) {
for (j = 0; j < 63; j++) {
printf("%c", m[i][j]);
}
printf("\n");
}
}
//n=5
10+
9 +
8 +
7 +
6 +
5 +
4 + *
3 + *
2 + *
1 + *
0 + + + + + + + + + + + + + + + + + + + + +
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Sounds like you want to not print the trailing spaces on each line. So you need to find and skip those trailing spaces rather than printing them:
for (i = 0; i < 12; i++) {
int eol = 63;
while (eol > 0 && m[i][eol-1] == ' ') --eol;
for (j = 0; j < eol; j++) {
printf("%c", m[i][j]);
}
printf("\n");
}

How to write Ackermann Function iteratively?

I wrote a recursive version of Ackermann Function, and it worked properly:
int ackermann_r(int m, int n) {
if(m == 0) {
return n + 1;
} else if(n == 0) {
return ackermann_r(m - 1, 1);
} else {
return ackermann_r(m - 1, ackermann_r(m, n - 1));
}
}
Then I tried to rewrite the code iteratively:
(I don't know how to use 2D array using malloc, so you could feel the code is dirty...)
int ackermann_i(int m, int n) {
int* A = (int*) malloc((m+1) * (n+1) * sizeof(int));
for(int i = 0; i <= m; i++) {
for(int j = 0; j <= n; j++) {
if(i == 0) {
A[i*(n+1) + j] = j + 1;
} else if(j == 0) {
A[i*(n+1) + j] = A[(i-1)*(n+1) + 1];
} else {
A[i*(n+1) + j] = A[(i-1)*(n+1) + A[i*(n+1) + (j-1)]];
}
}
}
return A[m*(n+1) + n];
}
But the iterative version printed a wrong answer. For example:
m: 3
n: 2
recursive: 29
iterative: 3
Why my iterative code doesn't work?
Undefined behaviour
Unfortunately, your code shows undefined behaviour due to access on an uninitialized value and out-of-bounds access. The simplest test that shows this behaviour is m = 1, n = 0. This indicates only two iterations of the outer loop and one iteration of the inner loop and thus is easier to analyze:
int ackermann_i(int m, int n) {
int* A = (int*) malloc((m+1) * (n+1) * sizeof(int));
for(int i = 0; i <= m; i++) {
for(int j = 0; j <= n; j++) {
if(i == 0) {
A[i*(n+1) + j] = j + 1; // (1)
} else if(j == 0) {
A[i*(n+1) + j] = A[(i-1)*(n+1) + 1]; // (2)
} else {
A[i*(n+1) + j] = A[(i-1)*(n+1) + A[i*(n+1) + (j-1)]]; // (3)
}
}
}
return A[m*(n+1) + n];
}
So let's iterate by hand:
i = 0, j = 0. We enter (1) and set A[0 + 0] = 1.
i = 1, j = 0. We enter (2) and set A[2 + 0] = A[0 + 1].
there's always at least j == 0, so we don't care about (3).
But there's the issue: we never set A[0 + 1]. That value might be zero, it might as well be something else at random; undefined behaviour ensues. Even worse, our A is not large enough: (m+1)*(n+1) is only 2 here, so A[2] is an out-of-bound array access.
This indicate two issues:
our allocated memory isn't large enough and may never be, as the inner term in a(m, a(m-1,n)) can grow much larger than n.
if we had a solution for that, we'd need to handle the trivial cases first, e.g.
for(int j = 0; j <= (n+1); ++j) {
A[0 + j] = j + 1; // set all A[i,j] where i = 0
}
A deeper issue with the algorithm
There is however one deeper issue. Your code implies that the Ackermann function can be calculated in θ(m * n). That's however impossible. Instead, you need at least a stack or something similar that can grow in size to calculate the result. This implementation in Java provides some inspiration.

Triplet problem : Solve it and remove the error

#include<stdio.h>
#include<stdbool.h>
#include<malloc.h>
// function called
long long good_triplets (int* arr, int n) {
int count=0;
if(1<=n<=100000)
{
for(int i=0;i<=n;i++)
{
if((((arr[i]+arr[i+1]+arr[i+2])%arr[i ])==0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i+1])!=0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i+2])!=0) )
count=count + 6;
if((((arr[i]+arr[i+1]+arr[i+2])%arr[i+1])==0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i ])!=0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i+2])!=0) )
count=count + 6;
if((((arr[i]+arr[i+1]+arr[i+2])%arr[i+2])==0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i+1])!=0) &&
(((arr[i]+arr[i+1]+arr[i+2])%arr[i])!=0) )
count=count + 6;
}
}
return count;
}
//main funtion
int main() {
int n;
scanf("%d", &n);
int i_arr;
int *arr = (int *)malloc(n * sizeof(int));
for(i_arr=0; i_arr<n; i_arr++)
scanf("%d", &arr[i_arr]);
long long out_ = good_triplets(arr, n);
printf("%lld", out_);
}
'remove floating point exception'
'it is a hacker earth que'
'1.Remove floating point exception
2.help quickly please'
QUESTION: why am I getting the Floating Point Exception and how do I fix it?
if(1<=n<=100000) is wrong. It does not work this way in C. My proposition for that is to use logical and statement (&&) by writing:
if (1 <= n && n <= 100000)
You try to limit the loop to n in line: for(int i=0;i<=n;i++) but you should have < sign instead of <=. Try to use: for (int i=0; i<n; i++) to limit it to n.
Additionally, When you are limitting it to n then you should not use arr[i+1] or arr[i+2], because you are accessing values out of the array bounds (from memory which is just after the array). This is a reason of that exception. If you have some non-zero trash, then most probably your code will not have a floating point exception. Because you are using arr[i+1] and arr[i+2] in modulo operation and in some way they could be zero, then according to standard you can have the undefined behavior.
Try to use (according to your code; I do not know a purpose of it):
long long good_triplets(int *arr, int n) {
int count = 0;
if (3 <= n && n <= 100000) {
for (int i = 0; i < (n - 2); i++) {
if ((((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i]) == 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 1]) != 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 2]) != 0))
count = count + 6;
if ((((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 1]) == 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i]) != 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 2]) != 0))
count = count + 6;
if ((((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 2]) == 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i + 1]) != 0) &&
(((arr[i] + arr[i + 1] + arr[i + 2]) % arr[i]) != 0))
count = count + 6;
}
}
return count;
}

Check if 2d array is sorted ascending or descending

I'm trying to check if a 2d array is sorted like this way:
for (i = 0; i <= nl - 2; i++)
{
for (j = 0; j <= nc - 2; j++)
{
if (M[i][j] > M[i + 1][j + 1])
cr++;
else if (M[i][j] < M[i + 1][j + 1])
dc++;
}
}
if (cr == nl - 1)
printf("Sorted\n");
if (dc == nl - 1)
printf("Sorted\n");
But doesn't work well sometimes, i would like to get your help!

Resources