How to calculate the number of triangles that can be formed - c

The code below should have counted the number of triangles that can be formed out of every triplet of 3 distinct integers from the given range 1...N. However, when I input 5, it gives me 34, while the right answer is 3: the only possible triangles are (2, 3, 4), (2, 4, 5) and (3, 4, 5).
// C code to count the number of possible triangles using
#include <stdio.h>
int main()
{ int N, count=0;
setvbuf(stdout, NULL, _IONBF, 0);
printf("Please input the value of N: \n");
scanf("%d", &N );
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
// The innermost loop checks for the triangle
// property
for (int k = 1; k < N; k++) {
// Sum of two sides is greater than the
// third
if (i + j > k && i + k > j && k + j > i)
{
count++;
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
return 0;
}

You do not ensure that the numbers are distinct.
You can do this be chosing your loop limits correctly:
for (int i = 1; i <= N-2; i++) {
for (int j = i+1; j <= N-1; j++) {
for (int k = j+1; k <= N; k++) {
Start each inner loop one higher than current counter of outer loop. It also does not make any sense to run each loop up to N. If they must be distinct, you can stop at N-2, N-1, N
This creates triples where numbers are increasing.
If you consider triangles (3,4,5) and (4,3,5) to be different, we must also account for permuations of these triples.
As all values are distinct, we have 6 possible permutations for each triple that was found in the inner loop.

I'm sorry, I can't go for a comment so let's go for an answer.
I don't really get what you wish to do. As I am understanding it, you wish to print this :
1, 2, 3, 4, 5-> [2, 3, 4], [2, 4, 5], [3, 4, 5] -> 3
Except, with your code, you'll never check your N since you go out of your loop when i turns into N.
Also, your "j" and "k" don't have to move starting 1 since you already tried that position with "i", so you'll only get doublons doing that.
EDIT : some changes for a smarter code (I removed my +1 but go check for "<=", which I personnaly dislike :) ):
// since [1, 2, 3] can't bring any triangle
if (N < 4) return 0;
// since there is no possible triangle with 1 as a border, start at 2
for (int i = 2; i <= N-2; i++) {
for (int j = i+1; j <= N-1; j++) {
// The innermost loop checks for the triangle
// property
for (int k = j+1; k <= N; k++) {
// Sum of two sides is greater than the
// third
// simplified as suggested by S M Samnoon Abrar
if (i + j > k)
{
count++;
}
}
}

You need to do the following:
run first loop through 1 to N, i.e.: 1 <= i <= N
don't start each nested loop from index 1. So, you need to run first nested loop in range i+1 <= j <= N and second nested loop in range j+1 <= k <=N.
Explanation
First, if you run all 3 loops from 1 to N, then you are not doing distinct counting because all numbers in the range will be iterated 3 times. So it would give an incorrect result.
Secondly, since we need to count distinct numbers only, it is efficient to count +1 from the previous outer loop each time. In this way, we are ensuring that we are not iterating over any number twice.
Check the following code:
// C code to count the number of possible triangles using
#include <stdio.h>
int main()
{ int N, count=0;
setvbuf(stdout, NULL, _IONBF, 0);
printf("Please input the value of N: \n");
scanf("%d", &N );
for (int i = 1; i <= N; i++) {
for (int j = i+1; j <= N; j++) {
// The innermost loop checks for the triangle
// property
for (int k = j+1; k <= N; k++) {
// Sum of two sides is greater than the
// third
if (i + j > k && i + k > j && k + j > i)
{
count++;
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
return 0;
}

Spot the extra line of code that enforces the constraint that the 3 numbers are "distinct" (read "unique"). Funny what a little "print debugging" can turn up...
printf("Please input the value of N: ");
scanf("%d", &N );
for (int i = 1; i < N; i++) {
for (int j = 1; j < N; j++) {
for (int k = 1; k < N; k++) {
if (i + j > k && i + k > j && k + j > i) {
if( i != j && j != k && k != i ) {
printf( "%d %d %d\n", i, j, k );
count++;
}
}
}
}
}
printf ("Total number of triangles possible is %d ",count);
Output
Please input the value of N: 5
2 3 4
2 4 3
3 2 4
3 4 2
4 2 3
4 3 2
Total number of triangles possible is 6
The OP code was counting (1,1,1) or (2,3,3) in contravention of "distinct" digits.
AND, there is now ambiguity from the OP person as to whether, for instance, (4,2,3) and (4,3,2) are distinct.
printf() - the coder's friend when things don't make sense...

Related

how to list all pairs of sexy primes

How can i write a program that lists all sexy prime pairs that exist in n numbers.
For example if n = 10 the output should be (5, 11) and (7, 13)
My idea was to generate all primes within n and then add 6 to each and check if the i + 6 is a prime. But it doesnt work, there's no output and the program ends.
#include <stdio.h>
int main() {
int i, j, n, k, isprime = 1, prime2, flag = 0;
scanf("%d", &n);
for (i = 3; i <= n; i++){
for (j = 2; j <= i; j++){
if (i % j == 0)
break;
}
if (i == j){
prime2 = i + 6;
for (k = 3; k <= prime2; k++){
if (prime2 % k == 0){
flag++;
break;
}
}
if (flag == 0){
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Any ideas of what im doing wrong or any tips on how to solve it? (with loops only)
As there're a lot of resources about finding a prime number, I'm not going to discuss that. Rather I'll try to point out the bug in your code.
First problem:
for (k = 3; k <= prime2; k++)
Here you need to run the loop till prime2 - 1. Also you should start checking from 2 rather than 3, just like you did previously. That means,
for (k = 2; k < prime2; k++)
or
for (k = 2; k <= prime2 - 1; k++)
Reason: when k = prime2, prime2 % k will be 0. For finding out whether a number is prime we don't need to check if that number is divisible by 1 and that number itself.
Note: Now you might think why the first prime number loop for (j = 2; j <= i; j++) is working .
It's working because you've given an additional condition if (i == j) after it.
Second problem:
You need to declare the flag variable within the first loop.
for (i = 2; i <= n; i++)
{
int flag = 0;
.... (rest of the code)
....
}
Reason: Basically with the flag value, you're trying to find out whether prime2 is a prime number.
Every time you'll get a prime number from the first loop, you'll have a new value of prime2. In your code, once you're incrementing the value of flag, you're never resetting the flag value.
That's why once your code detects a prime2 which is not a prime, it'll never detect the second prime number again (prime2 which is actually prime).
Overall code:
#include <stdio.h>
int main()
{
int i, j, n, k, isprime = 1, prime2;
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
int flag = 0; // changing point
for (j = 2; j <= i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
prime2 = i + 6;
for (k = 2; k < prime2; k++) // changing point
{
if (prime2 % k == 0)
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Few resources to know more about finding out prime numbers:
Prime Numbers
C Program to Check Whether a Number is Prime or not
Sieve of Eratosthenes
You can use Sieve to speed up the program. It can generate all pairs in O(N log N) time. Here's the Algorithm.
Now, you have a boolean array, is_prime where is_prime[i] is true if i is a prime, false otherwise.
Now, iterate from i = 1 to i = N and check if is_prime[i] && is_prime[i + 6], if the condition is true, output the pair.

Calculate Series in C

I wrote a program in C for this series. but when I enter n = -8 and m = 2 the result is zero.
Why and how can I fix it?
Series here
#include <stdio.h>
#include <math.h>
int main()
{
int n,m;
double sum = 0;
printf("Enter n:\n");
scanf_s("%d",&n);
printf("Enter m:\n");
scanf_s("%d", &m);
for (int i = -10; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
sum += (pow((i + j), 3) / pow(j,2) );
}
}
printf_s("%f",sum);
}
for (int j = 1; j <= n; j++)
{
sum += (pow((i + j), 3) / pow(j,2) );
}
when you are trying to input n=-8 this loop won't work coz j=1 and condition is set to work until j<=n
In your code, the only expression that modifies the variable named sum is inside the inner loop. The loop will execute only if its controlling expression j <= n is true.
You initialize j with the value of 1. If you give n any value less than 1, the loop will not execute because j <= n would be false.
Since the initial value of the variable sum is 0 and the expression that modifies sum is not executed, the output is 0.

Is it the efficeint program to rotate array in left direction?

#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.

Negative numbers are printed

This is a program on sorting integers.
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:
-1217260830 25 34 588
What seems to be the problem?
You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).
But, inside that loop you are accessing an element beyond the last. For instance, in
if (nmbr[j] > nmbr[j + 1])
you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).
If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).
There are multiple problems in your code:
You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.
You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.
Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
Your Sorting Logic is wrong. It should be:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.
As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.
Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.
0 25 34 588

How to get adjacent elements of an element in 2D array programatically?

Suppose you have a 2D array arr[N][N]. If I give an input arr[i][j] to you, I should get left, right, top and down elements i.e. arr[i][j-1], arr[i][j+1], arr[i-1][j] and arr[i+1][j].
Eg: Arr[3][3]= {1, 2, 3, 4, 5, 6, 7, 8, 9}
Input: 5
Output: 4, 6, 2, 8
Input: 1
Output: null, 2, null, 4
How can I write a program that should consider boundary conditions?
So your program consists of two parts:
Finding if the input exists at some index. Find it by looping through your array, like so:
for( int i = 0; i < N; i++ ){
for( int j = 0; j < N; j++ ){
if(arr[i][j] == input) //produce output
}
}
Producing output. For simplicity i will just print it out, though if your goal is a function that returns the values around the input number then you should malloc an array and copy over the values to the array. To print, check first if we are in bounds, and do not attempt to print if we are out of bounds, otherwise there will be issues.
for( int k = i - 1 ; k < i + 2; k++ ){
for(int l = j - 1; l < j + 2; j++ ){
if ( k > -1 && l > -1 && k < N && j < N ){ // check if in bounds
printf("%i ", arr[k][l]);
}
}
}
When you are accessing an index in array, just make sure that you are not accessing an invalid index, like index < 0 or index > size. So in your case
if(j > 0) System.out.println(a[i][j-1]);
if(i > 0) System.out.println(a[i-1][j]);
if(j < N-1) System.out.println(a[i][j+1]);
if(i < N-1) System.out.println(a[i+1][j]);
If you want to return null if the index is not valid, just add in in else part for each if.

Resources