I am learning c. So, I was practicing in a online judge. I have got a logic behind the problem and submitted ans got wrong answer. What is the problem?
Problem:
Area
100 Points · Limits 1s, 512 MB
In this problem, you will be given a square which has a length of n. Co-ordinates of the square are (0,0), (n,0),(n,n),(0,n) . You need to draw 4 straight lines:
Line from (0,1) to (n,n-1)
Line from (1,0) to (n-1,n)
Line from (0,n-1) to (n,1)
Line from (1,n) to (n-1,0)
These four lines will intersect in a point (x,y) like the figure shown below.
Calculate the total area of A+B+C+D (except the four corner unit square).
Input
Input will start with an integer T. Then there will be T cases. Each case will contain one integer N. 1 <= T <= 100000
3 <= n <= 1018
Output
For each test case, print “Case x: y” without quotation marks where x is the case number and y is the required answer.
It is guaranteed that y is always an integer.
Sample
Input Output
1
6
Case 1: 8
My code:
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()
{
int test, i;
scanf("%d", &test);
for(i=0; i<test; i++)
{
double n, area, a,x, b1, b, s, tri, area1, area_t;
scanf("%lf", &n);
area= n*n;
a=n-2;
x=n/2;
b1= (x-1)*(x-1) + x*x;
b= sqrt(b1);
s= (a+b+b)/2;
area1= s*(s-a)*(s-b)*(s-b);
area_t = (4* sqrt(area1));
printf("Case %d: %.0lf\n",i+1, (area-(area_t + 4)));
}
return 0;
}
Please help me to improve the code. Thank you.
I believe you have a compatability problem and your online judge is on a C89 implementation where "%lf" does not exist, making your program output
Case 1: %.0lf
Case 2: %.0lf
...
Try using the C89 specifier
printf("Case %d: %.0f\n", i + 1, area - (area_t + 4));
/* ^^^^ C89, not %.0lf */
Note: double x; scanf("&lf", &x) has been valid since C89.
Let Area be the requested area, which can be calculated as:
Area = OuterSquareArea - 4 * IsoscelesTringleArea - 4 * SmallSqareArea
where:
OuterSqareArea = n * n
IsoscelesTriangleArea = base * height / 2
= (n - 2) * (n / 2) / 2
= (n - 2) * n / 4
SmallSquareArea = 1 * 1
= 1
The computation of Area can be summed up to:
Area = (n * n) - 4 * ((n - 2) * n / 4) - 4 * (1)
= n * n - (n - 2) * n - 4
= (n - (n - 2)) * n - 4
= 2 * n - 4
The trace guarantees that t, n and Area are integers. The code we need is then:
#include <stdio.h>
int main() {
int i, t, n;
scanf("%d", &t); /* read t */
for (i = 1; i <= t; i++) { /* for any i in [1,t] */
scanf("%d", &n); /* read n */
printf("Case %d: %d\n", i, 2 * n - 4); /* solve */
}
}
The code could simply be extented to check t and n to be in the given ranges.
Related
I'm a computer engineering student and next semester I am going to start C course. So in order to prepare myself a bit, I have started learning C by myself and stumbled across an interesting task, designed for, how it seemed to me at first sight, not a very advanced level.
The task is to write a program to compute the value of a given position in Pascal's Triangle. And the formula given to compute it is written as element = row! / ( position! * (row - position)! )
I've written a simple console program that seems to work okay, until I get to testing it with large numbers.
When trying this program with row 16 and position 3, it calculates the value as 0, although it's obvious that there can't be such a value (in fact it should compute the value as 560), all cells of this triangle are supposed to be integers and be greater than one.
I suppose I'm experiencing a problem with storing and processing large numbers. The factorial function seems to work okay, and the formula I used works until I get to trying large numbers
So far the best solution was found here - How do you printf an unsigned long long int(the format specifier for unsigned long long int)? using inttypes.h library with type uint64_t but it still doesn't give me the result I need.
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
void clear_input(void);
uint64_t factorial(int x);
int main()
{
// Printing
printf("This program computes the value of a given position in Pascal's Triangle.\n");
printf("You will be asked for row and position of the value.\n");
printf("Note that the rows and positions starts from 0.\n");
printf("\n");
printf(" 1 * 0 \n");
printf(" 1 1 * 1 \n");
printf(" 1 2 1 * 2 \n");
printf(" 1 3 3 1 * 3 \n");
printf(" 1 4 6 4 1 * 4 \n");
printf(" **************** \n");
printf(" 0 1 2 3 4 \n");
printf("\n");
// Initializing
int row, pos;
// Input Row
printf("Enter the row: ");
scanf("%d", &row);
clear_input();
// Input Position
printf("Enter the position in the row: ");
scanf("%d", &pos);
clear_input();
// Initializing
uint64_t element, element_1, element_2, element_3, element_4;
// Previously written as -> element = ( factorial(row) ) / ( factorial(pos) * factorial(row - pos) );
// Doesn't fix the problem
element_1 = factorial(row);
element_2 = factorial(pos);
element_3 = factorial(row - pos);
element_4 = element_2 * element_3;
element = element_1 / element_4;
// Print result
printf("\n");
printf("%"PRIu64"\n", element_1); // Temporary output
printf("%"PRIu64"\n", element_2); // Temporary output
printf("%"PRIu64"\n", element_3); // Temporary output
printf("%"PRIu64"\n", element_4); // Temporary output
printf("\n");
printf("The element is %"PRIu64"", element);
printf("\n");
return 0;
}
void clear_input(void) // Temporary function to clean input from the keyboard
{
while(getchar() != '\n');
}
uint64_t factorial(int x) // Function to calculate factorial
{
int f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Factorials get really big really fast (scroll down a little to see the list). Even a 64-bit number is only good up to 20!. So you have to do a little preprocessing before you start multiplying.
The general idea is to factor the numerator and the denominator, and remove all of the common factors. Since the results of Pascal's Triangle are always integers, you are guaranteed that the denominator will be 1 after all common factors have been removed.
For example let's say you have row=35 and position=10. Then the calculation is
element = 35! / (10! * 25!)
which is
35 * 34 * 33 * ... * 26 * 25 * 24 * ... * 3 * 2 * 1
---------------------------------------------------
10! * 25 * 24 * ... * 3 * 2 * 1
So the first simplification is that the larger factorial in the denominator cancels all of the smaller terms of the numerator. Which leaves
35 * 34 * 33 * ... * 26
-----------------------
10 * 9 * 8 * ... * 1
Now we need to remove the remaining common factors in the numerator and denominator. It helps to put all the number of the numerator in an array. Then, for each number in the denominator, compute the greatest common divisor (gcd) and divide the numerator and denominator by the gcd.
The following code demonstrates the technique.
array[10] = { 35, 34, 33, 32, 31, 30, 29, 28, 27, 26 };
for ( d = 10; d >= 2; d-- )
{
temp = d;
for ( i = 0; i < 10 && temp > 1; i++ )
{
common = gcd( array[i], temp );
array[i] /= common;
temp /= common;
}
}
Here's what the code does step by step
d=10 i=0 temp=10 array[0]=35 ==> gcd(35,10)=5, so array[0]=35/5=7 and temp=10/5=2
d=10 i=1 temp=2 array[1]=34 ==> gcd(34, 2)=2, so array[1]=34/2=17 and temp=2/2=1
inner loop breaks because temp==1
d=9 i=0 temp=9 array[0]=7 ==> gcd(7,9)=1, so nothing changes
d=9 i=1 temp=9 array[1]=17 ==> gcd(17,9)=1, so nothing changes
d=9 i=2 temp=9 array[2]=33 ==> gcd(33,9)=3, so array[2]=11 and temp=3
d=9 i=3 ==> gcd(32,3)=1
d=9 i=4 ==> gcd(31,3)=1
d=9 i=5 temp=3 array[5]=30 ==> gcd(30,3)=3, so array[5]=10 and temp=1
inner loop breaks
When all is said and done the array ends up as
array[10] = { 1, 17, 11, 1, 31, 1, 29, 14, 3, 26 }
Multiply those numbers together and the answer is 183579396, and the entire calculation could be performed using 32-bit ints. In general, as long as the answer fits into 32-bits, the calculations can be done with 32-bits.
(my C is rusty, so this may not be super accurate)
Your factorial function is returning a uint64_t, but it's doing the computation with regular ints. If you changed f and i to uint64_t I think you'll avoid your current integer overflow issue.
However, you're still going to run into overflow pretty quickly (uint64_t will overflow around 21!). To avoid this you can be a bit smarter with the algorithm. With row=16 and position=3, you need 16! / (3! * 13!). You can cancel out most of the terms (16!/13! is just 14*15*16) and end up with 14*15*16 / (1*2*3). This'll let your program go a lot further than row 21.
When you are calculating the factorial, even though you are returning a 64-bit integer it won't make a difference if you are using regular int variables for your intermediate calculations. Change to this:
uint64_t factorial(uint64_t x)
{
uint64_t f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Also, think about how you can rearrange the equation so that you don't have to calculate really large intermediate values. For example you could rearrange to this:
element = ( factorial(row) / factorial(pos) ) / factorial(row - pos);
Then you won't be multiplying two factorials together and getting a really large number.
Also, when you compute factorial(row) / factorial(pos) you can eliminate terms that will be in both factorial(row) and factorial(pos), so you don't need to calculate the entire factorials.
This will work:
#include <stdio.h>
int main()
{
printf ("\n");
int n = 10;
int i;
int j;
int x[n];
for (i = 0; i < n; i++)
x[i] = 0;
for (i = 1; i <= n; i++)
{
for (j = n - 1; j >= 1; j--)
x[j] = x[j-1] + x[j];
x[0] = 1;
int s = n - i;
for (j = 0; j < s; j++)
printf (" ");
for (j = 0; j < n; j++)
{
if (x[j] != 0)
printf (" %3d", x[j]);
}
printf ("\n");
}
printf ("\n");
return 0;
}
I'm a computer engineering student and next semester I am going to start C course. So in order to prepare myself a bit, I have started learning C by myself and stumbled across an interesting task, designed for, how it seemed to me at first sight, not a very advanced level.
The task is to write a program to compute the value of a given position in Pascal's Triangle. And the formula given to compute it is written as element = row! / ( position! * (row - position)! )
I've written a simple console program that seems to work okay, until I get to testing it with large numbers.
When trying this program with row 16 and position 3, it calculates the value as 0, although it's obvious that there can't be such a value (in fact it should compute the value as 560), all cells of this triangle are supposed to be integers and be greater than one.
I suppose I'm experiencing a problem with storing and processing large numbers. The factorial function seems to work okay, and the formula I used works until I get to trying large numbers
So far the best solution was found here - How do you printf an unsigned long long int(the format specifier for unsigned long long int)? using inttypes.h library with type uint64_t but it still doesn't give me the result I need.
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
void clear_input(void);
uint64_t factorial(int x);
int main()
{
// Printing
printf("This program computes the value of a given position in Pascal's Triangle.\n");
printf("You will be asked for row and position of the value.\n");
printf("Note that the rows and positions starts from 0.\n");
printf("\n");
printf(" 1 * 0 \n");
printf(" 1 1 * 1 \n");
printf(" 1 2 1 * 2 \n");
printf(" 1 3 3 1 * 3 \n");
printf(" 1 4 6 4 1 * 4 \n");
printf(" **************** \n");
printf(" 0 1 2 3 4 \n");
printf("\n");
// Initializing
int row, pos;
// Input Row
printf("Enter the row: ");
scanf("%d", &row);
clear_input();
// Input Position
printf("Enter the position in the row: ");
scanf("%d", &pos);
clear_input();
// Initializing
uint64_t element, element_1, element_2, element_3, element_4;
// Previously written as -> element = ( factorial(row) ) / ( factorial(pos) * factorial(row - pos) );
// Doesn't fix the problem
element_1 = factorial(row);
element_2 = factorial(pos);
element_3 = factorial(row - pos);
element_4 = element_2 * element_3;
element = element_1 / element_4;
// Print result
printf("\n");
printf("%"PRIu64"\n", element_1); // Temporary output
printf("%"PRIu64"\n", element_2); // Temporary output
printf("%"PRIu64"\n", element_3); // Temporary output
printf("%"PRIu64"\n", element_4); // Temporary output
printf("\n");
printf("The element is %"PRIu64"", element);
printf("\n");
return 0;
}
void clear_input(void) // Temporary function to clean input from the keyboard
{
while(getchar() != '\n');
}
uint64_t factorial(int x) // Function to calculate factorial
{
int f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Factorials get really big really fast (scroll down a little to see the list). Even a 64-bit number is only good up to 20!. So you have to do a little preprocessing before you start multiplying.
The general idea is to factor the numerator and the denominator, and remove all of the common factors. Since the results of Pascal's Triangle are always integers, you are guaranteed that the denominator will be 1 after all common factors have been removed.
For example let's say you have row=35 and position=10. Then the calculation is
element = 35! / (10! * 25!)
which is
35 * 34 * 33 * ... * 26 * 25 * 24 * ... * 3 * 2 * 1
---------------------------------------------------
10! * 25 * 24 * ... * 3 * 2 * 1
So the first simplification is that the larger factorial in the denominator cancels all of the smaller terms of the numerator. Which leaves
35 * 34 * 33 * ... * 26
-----------------------
10 * 9 * 8 * ... * 1
Now we need to remove the remaining common factors in the numerator and denominator. It helps to put all the number of the numerator in an array. Then, for each number in the denominator, compute the greatest common divisor (gcd) and divide the numerator and denominator by the gcd.
The following code demonstrates the technique.
array[10] = { 35, 34, 33, 32, 31, 30, 29, 28, 27, 26 };
for ( d = 10; d >= 2; d-- )
{
temp = d;
for ( i = 0; i < 10 && temp > 1; i++ )
{
common = gcd( array[i], temp );
array[i] /= common;
temp /= common;
}
}
Here's what the code does step by step
d=10 i=0 temp=10 array[0]=35 ==> gcd(35,10)=5, so array[0]=35/5=7 and temp=10/5=2
d=10 i=1 temp=2 array[1]=34 ==> gcd(34, 2)=2, so array[1]=34/2=17 and temp=2/2=1
inner loop breaks because temp==1
d=9 i=0 temp=9 array[0]=7 ==> gcd(7,9)=1, so nothing changes
d=9 i=1 temp=9 array[1]=17 ==> gcd(17,9)=1, so nothing changes
d=9 i=2 temp=9 array[2]=33 ==> gcd(33,9)=3, so array[2]=11 and temp=3
d=9 i=3 ==> gcd(32,3)=1
d=9 i=4 ==> gcd(31,3)=1
d=9 i=5 temp=3 array[5]=30 ==> gcd(30,3)=3, so array[5]=10 and temp=1
inner loop breaks
When all is said and done the array ends up as
array[10] = { 1, 17, 11, 1, 31, 1, 29, 14, 3, 26 }
Multiply those numbers together and the answer is 183579396, and the entire calculation could be performed using 32-bit ints. In general, as long as the answer fits into 32-bits, the calculations can be done with 32-bits.
(my C is rusty, so this may not be super accurate)
Your factorial function is returning a uint64_t, but it's doing the computation with regular ints. If you changed f and i to uint64_t I think you'll avoid your current integer overflow issue.
However, you're still going to run into overflow pretty quickly (uint64_t will overflow around 21!). To avoid this you can be a bit smarter with the algorithm. With row=16 and position=3, you need 16! / (3! * 13!). You can cancel out most of the terms (16!/13! is just 14*15*16) and end up with 14*15*16 / (1*2*3). This'll let your program go a lot further than row 21.
When you are calculating the factorial, even though you are returning a 64-bit integer it won't make a difference if you are using regular int variables for your intermediate calculations. Change to this:
uint64_t factorial(uint64_t x)
{
uint64_t f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Also, think about how you can rearrange the equation so that you don't have to calculate really large intermediate values. For example you could rearrange to this:
element = ( factorial(row) / factorial(pos) ) / factorial(row - pos);
Then you won't be multiplying two factorials together and getting a really large number.
Also, when you compute factorial(row) / factorial(pos) you can eliminate terms that will be in both factorial(row) and factorial(pos), so you don't need to calculate the entire factorials.
This will work:
#include <stdio.h>
int main()
{
printf ("\n");
int n = 10;
int i;
int j;
int x[n];
for (i = 0; i < n; i++)
x[i] = 0;
for (i = 1; i <= n; i++)
{
for (j = n - 1; j >= 1; j--)
x[j] = x[j-1] + x[j];
x[0] = 1;
int s = n - i;
for (j = 0; j < s; j++)
printf (" ");
for (j = 0; j < n; j++)
{
if (x[j] != 0)
printf (" %3d", x[j]);
}
printf ("\n");
}
printf ("\n");
return 0;
}
I'd like for the program to solve my equation yet sadly it doesn't. Additionally, I'd want for it to print an answer depending on the value of x that I input in the equation. Please let me know how I would be able to print the answer or how I can program it so that the equation gives me an answer that I can then print.
/* Preprocessor directives */
#include <stdio.h>
#include <math.h>
/* Main program */
void main ()
{
/*
variable declaration section comments
l: length value
q: value of q
ei: value of ei
s: l devided by 2 since 0 < x < l/2
b: the length l (thus, 20)
z: 0
first_equation: The first equation pertaining to 0 < x < l/2
second_equation:The second equation pertaining to l/2 < x < l
*/
double x, first_equation, second_equation, l, q, ei, s, b, z;
l = 20.0;
q = 4000.0;
ei = 1.2 * (pow(10.0, 8.0));
s = l / 2.0;
b = l;
z = 0.0;
printf ("please enter the x-value\n");
scanf ("%lf", &x);
/* Deflection equations */
first_equation = ((q * x) / (384.0 * ei)) * ((9 * (pow(l, 3.0))) - (24.0 * l * (pow(x, 2.0))) + (16 * (pow(x, 3.0))));
second_equation = ((q * l) / (384.0 * ei)) * ((8 * (pow(x, 3.0))) - (24.0 * l * (pow(x, 2.0))) + (17 * (pow(l, 2.0)) * x) - (pow(l, 3.0)));
/* Determining what equation to use */
if (x >= z && x <= s)
printf ("\n first_equation\n\n");
else if (x > s && x <= b)
printf ("\n second_equation\n\n", second_equation);
else if (x < 0 || x > b)
printf ("\n invalid location\n\n");
return;
}
This...
printf ("\n second_equation\n\n", second_equation);
... does not print the second_equation variable: it provides it as an argument to printf, but printf only uses extra arguments as directed by %f or other conversion instructions embedded in the text provided as the first argument. You could write:
printf ("\n second_equation %f\n\n", second_equation);
You may want to do something similar for first_equation.
Alternatively [when I answered the question was tagged C++] you could use C++ I/O routines (scanf and printf are from the C library, and have a number of disadvantages, the most obvious here being that you have to remember funny letter codes like "lf" matching your data types)...
#include <iostream>
...at the very top of your file, then in your function write...
std::cout << "\n second_equation " << second_equation << "\n\n";
You could also use C++ I/O for input, replacing scanf with...
if (!(std::cin >> x))
{
std::cerr << "you didn't enter a valid number\n";
exit(1);
}
Your code is really unclear; but going by your question, you seem to want to be able to print your answer. In that case, here is the proper syntax
printf ("Answer: %d \n", yourAnswer); //if 'yourAnswer' is decimal or number
To use one of your code snippets, you'll have this:
printf ("\n second_equation: %d\n", second_equation);
I'm a computer engineering student and next semester I am going to start C course. So in order to prepare myself a bit, I have started learning C by myself and stumbled across an interesting task, designed for, how it seemed to me at first sight, not a very advanced level.
The task is to write a program to compute the value of a given position in Pascal's Triangle. And the formula given to compute it is written as element = row! / ( position! * (row - position)! )
I've written a simple console program that seems to work okay, until I get to testing it with large numbers.
When trying this program with row 16 and position 3, it calculates the value as 0, although it's obvious that there can't be such a value (in fact it should compute the value as 560), all cells of this triangle are supposed to be integers and be greater than one.
I suppose I'm experiencing a problem with storing and processing large numbers. The factorial function seems to work okay, and the formula I used works until I get to trying large numbers
So far the best solution was found here - How do you printf an unsigned long long int(the format specifier for unsigned long long int)? using inttypes.h library with type uint64_t but it still doesn't give me the result I need.
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
void clear_input(void);
uint64_t factorial(int x);
int main()
{
// Printing
printf("This program computes the value of a given position in Pascal's Triangle.\n");
printf("You will be asked for row and position of the value.\n");
printf("Note that the rows and positions starts from 0.\n");
printf("\n");
printf(" 1 * 0 \n");
printf(" 1 1 * 1 \n");
printf(" 1 2 1 * 2 \n");
printf(" 1 3 3 1 * 3 \n");
printf(" 1 4 6 4 1 * 4 \n");
printf(" **************** \n");
printf(" 0 1 2 3 4 \n");
printf("\n");
// Initializing
int row, pos;
// Input Row
printf("Enter the row: ");
scanf("%d", &row);
clear_input();
// Input Position
printf("Enter the position in the row: ");
scanf("%d", &pos);
clear_input();
// Initializing
uint64_t element, element_1, element_2, element_3, element_4;
// Previously written as -> element = ( factorial(row) ) / ( factorial(pos) * factorial(row - pos) );
// Doesn't fix the problem
element_1 = factorial(row);
element_2 = factorial(pos);
element_3 = factorial(row - pos);
element_4 = element_2 * element_3;
element = element_1 / element_4;
// Print result
printf("\n");
printf("%"PRIu64"\n", element_1); // Temporary output
printf("%"PRIu64"\n", element_2); // Temporary output
printf("%"PRIu64"\n", element_3); // Temporary output
printf("%"PRIu64"\n", element_4); // Temporary output
printf("\n");
printf("The element is %"PRIu64"", element);
printf("\n");
return 0;
}
void clear_input(void) // Temporary function to clean input from the keyboard
{
while(getchar() != '\n');
}
uint64_t factorial(int x) // Function to calculate factorial
{
int f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Factorials get really big really fast (scroll down a little to see the list). Even a 64-bit number is only good up to 20!. So you have to do a little preprocessing before you start multiplying.
The general idea is to factor the numerator and the denominator, and remove all of the common factors. Since the results of Pascal's Triangle are always integers, you are guaranteed that the denominator will be 1 after all common factors have been removed.
For example let's say you have row=35 and position=10. Then the calculation is
element = 35! / (10! * 25!)
which is
35 * 34 * 33 * ... * 26 * 25 * 24 * ... * 3 * 2 * 1
---------------------------------------------------
10! * 25 * 24 * ... * 3 * 2 * 1
So the first simplification is that the larger factorial in the denominator cancels all of the smaller terms of the numerator. Which leaves
35 * 34 * 33 * ... * 26
-----------------------
10 * 9 * 8 * ... * 1
Now we need to remove the remaining common factors in the numerator and denominator. It helps to put all the number of the numerator in an array. Then, for each number in the denominator, compute the greatest common divisor (gcd) and divide the numerator and denominator by the gcd.
The following code demonstrates the technique.
array[10] = { 35, 34, 33, 32, 31, 30, 29, 28, 27, 26 };
for ( d = 10; d >= 2; d-- )
{
temp = d;
for ( i = 0; i < 10 && temp > 1; i++ )
{
common = gcd( array[i], temp );
array[i] /= common;
temp /= common;
}
}
Here's what the code does step by step
d=10 i=0 temp=10 array[0]=35 ==> gcd(35,10)=5, so array[0]=35/5=7 and temp=10/5=2
d=10 i=1 temp=2 array[1]=34 ==> gcd(34, 2)=2, so array[1]=34/2=17 and temp=2/2=1
inner loop breaks because temp==1
d=9 i=0 temp=9 array[0]=7 ==> gcd(7,9)=1, so nothing changes
d=9 i=1 temp=9 array[1]=17 ==> gcd(17,9)=1, so nothing changes
d=9 i=2 temp=9 array[2]=33 ==> gcd(33,9)=3, so array[2]=11 and temp=3
d=9 i=3 ==> gcd(32,3)=1
d=9 i=4 ==> gcd(31,3)=1
d=9 i=5 temp=3 array[5]=30 ==> gcd(30,3)=3, so array[5]=10 and temp=1
inner loop breaks
When all is said and done the array ends up as
array[10] = { 1, 17, 11, 1, 31, 1, 29, 14, 3, 26 }
Multiply those numbers together and the answer is 183579396, and the entire calculation could be performed using 32-bit ints. In general, as long as the answer fits into 32-bits, the calculations can be done with 32-bits.
(my C is rusty, so this may not be super accurate)
Your factorial function is returning a uint64_t, but it's doing the computation with regular ints. If you changed f and i to uint64_t I think you'll avoid your current integer overflow issue.
However, you're still going to run into overflow pretty quickly (uint64_t will overflow around 21!). To avoid this you can be a bit smarter with the algorithm. With row=16 and position=3, you need 16! / (3! * 13!). You can cancel out most of the terms (16!/13! is just 14*15*16) and end up with 14*15*16 / (1*2*3). This'll let your program go a lot further than row 21.
When you are calculating the factorial, even though you are returning a 64-bit integer it won't make a difference if you are using regular int variables for your intermediate calculations. Change to this:
uint64_t factorial(uint64_t x)
{
uint64_t f = 1, i = x;
if (x == 0) {
return 1;
}
while (i != 1) {
f = f * i;
i = i - 1;
}
return f;
}
Also, think about how you can rearrange the equation so that you don't have to calculate really large intermediate values. For example you could rearrange to this:
element = ( factorial(row) / factorial(pos) ) / factorial(row - pos);
Then you won't be multiplying two factorials together and getting a really large number.
Also, when you compute factorial(row) / factorial(pos) you can eliminate terms that will be in both factorial(row) and factorial(pos), so you don't need to calculate the entire factorials.
This will work:
#include <stdio.h>
int main()
{
printf ("\n");
int n = 10;
int i;
int j;
int x[n];
for (i = 0; i < n; i++)
x[i] = 0;
for (i = 1; i <= n; i++)
{
for (j = n - 1; j >= 1; j--)
x[j] = x[j-1] + x[j];
x[0] = 1;
int s = n - i;
for (j = 0; j < s; j++)
printf (" ");
for (j = 0; j < n; j++)
{
if (x[j] != 0)
printf (" %3d", x[j]);
}
printf ("\n");
}
printf ("\n");
return 0;
}
Yes, this is a basic C coding homework problem. No, I am not just looking for someone to do it for me. Considering that this is my first programming class, I'm not surprised that I can't get it to work, and I'm certain there is plenty wrong with it. I just want some help pointing out the problems in my code and the things that are missing so that I can fix them on my own.
Homework Question:
Write a program to read ONLY one integer number (your input must be
one 3 digit number from 100 to 999), and to think of a number as
being ABC (where A, B, and C are the 3 digits of a number). Now,
form the number to become ABC, BCA, and CAB, then find out the
remainder of these three numbers when they are divided by 11.
Assume remainders would respectively be X, Y, and Z and add them
up as X+Y, Y+Z, and Z+X. Now if any of these summations is odd
number, increase it by 11 if the summation plus 11 is less than 20,
otherwise decrease the summation by 11 (this summation operation
must be positive number but less than 20). Finally, divide each
of the sums in half. Now, print out all the resulting digits.
My Code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Declare all variables
int OrigNumber;
int x, y, z;
int number;
number = x, y, z;
int sum;
//
printf("Input a three digit number");
//
int c;
c = OrigNumber %10;
//
int b;
b=((OrigNumber - c) % 100)/10;
//
int a;
a = (OrigNumber - (b + c))/100;
//
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
//
if((number % 2) == 1)
{
if(number + 11 < 20)
number += 11;
else if((100 - 11 > 0) && (100 - 11 < 20))
number -= 11;
}
//
x = abc/11;
y = bca/11;
z = cab/11;
//
sum = (x + y),
(y + z),
(z + x);
}
To start with, you need to read the input. Start with a prompt that includes a carriage return:
printf("Input a three digit number: \n");
Since it's a three digit number, you could add the following line to read the input:
scanf("%3d", &OrigNumber);
The next bit of code works quite well until you get to your if (number % 2) which is meaningless since you didn't really define number - well, you did, but the line
number = x, y, z;
does NOT do what you think it does. If you add
printf("So far I have abc=%d, bca=%d, cab=%d\n", abc, bca, cab);
after you first read in the number and computed those three, you will see you are well on your way.
Note that
number = x, y, z;
Uses a thing called the "comma operator". All the things (a,b,c) are "evaluated" but their values are not returned. At any rate, where you have that line, you didn't yet assign a value to x,y and z.
Is that enough to get your started?
update now that you have had a few hours to mull this over, here are a few more pointers.
Your computation of abc, cab, bca makes no sense. I will show you just one of them:
cab = c*100 + a*10 + b;
Next you need to compute each of x, y and z. Again, here is one of the three:
y = bca%11;
Now you have to make the sums - I call them xy, yz, and zx. Just one of them:
zx = z + x;
Next, to deal with the instruction: "Now if any of these summations is odd number, increase it by 11 if the summation plus 11 is less than 20, otherwise decrease the summation by 11:
if(xy % 2 == 1) {
if(xy + 11 < 20) xy += 11; else xy -= 11;
}
use similar code for all three sums. Then "divide by 2":
xy /= 2;
repeat as needed.
Finally, print out the result:
printf("xy: %d, yz: %d, zx: %d\n", xy, yz, zx);
The amazing thing is that if you did this right, you get the original numbers back...
You could make the code more compact by using an array of values and looping through it - rather than repeating the code snippets I wrote above with different variables. But I suspect that is well outside the scope of what you are expected to know at this point.
Can you take it from here?
#include <stdio.h>
int main()
{
//Declare all variables
int OrigNumber;
int a, b, c;
int abc, bca, cab;
int x, y, z;
int xplusy , yplusz, xplusz;
printf(" A program to read ONLY one integer number.\n Input must be one 3 digit number from 100 to 999 : ");
scanf("%d", &OrigNumber); // Get input from console
if(OrigNumber > 999 || OrigNumber < 100) {
printf("Invalid number. Quiting program. This is error handling. Important while learning programming.");
return 0;
}
c = OrigNumber %10; // digit at unit's place
b=((OrigNumber) % 100)/10; //digit at the ten's place
a = (OrigNumber)/100; //digit at the 100's place. Note: 734/100 = 7. NOT 7.34.
printf("\n Three numbers say A,B, C : %d, %d , %d ", a, b, c);
abc = a*100 + 10*b + c;
bca = 100*b + 10*c + a;
cab = c*100 + a*10 + b;
printf("\n Three numbers say ABC, BCA, CAB : %d, %d , %d ", abc, bca, cab);
x = abc % 11; // Reminder when divided by 11.
y = bca % 11;
z = cab % 11;
printf("\n Three numbers say X, Y, Z : %d, %d , %d ", x, y, z);
xplusy = x + y; // Adding reminders two at a time.
yplusz = y + z;
xplusz = x + z;
printf("\n Three numbers X+Y, Y+Z, X+Z : %d, %d , %d ", xplusy, yplusz, xplusz);
if((xplusy % 2) == 1) {
if(xplusy + 11 < 20)
xplusy += 11;
else
xplusy -= 11;
}
if((yplusz % 2) == 1) {
if(yplusz + 11 < 20)
yplusz += 11;
else
yplusz -= 11;
}
if((xplusz % 2) == 1) {
if(xplusz + 11 < 20)
xplusz += 11;
else
xplusz -= 11;
}
xplusy /= 2; // Finally, divide each of the sum in half.
yplusz /= 2;
xplusz /= 2;
printf("\n Now print out all the resulting digits : %d, %d , %d \n", xplusy, yplusz, xplusz);
return 0;
}
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
I suggest printing out the numbers at this point in the code.
printf( "%d %d %d", abc, bca, cab );
I think you'll see one of the problems you need to solve.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int n, a, b, c, abc, bca, cab, x, y, z, p, q, r;
scanf("%d", &n);
c=n%10;
b=(n/10)%10;
a=n/100;
abc=a*100+b*10+c;
bca=b*100+c*10+a;
cab=c*100+a*10+b;
x=abc%11;
y=bca%11;
z=cab%11;
p=x+y;
q=y+z;
r=z+x;
return 0;
}
Now if any of these summations is odd number, increase it by 11 if the
summation plus 11 is less than 20, otherwise decrease the summation by
11 (this summation operation must be positive number but less than
20). Finally, divide each of the sums in half. Now, print out all the
resulting digits.
i didnt get the final part, can you explain it more clearly?