I have to write a program that takes in two positive integers, start and end, where (1 < start < end). Then the program would look within this range [start, end] and count the number of powers of 3.
So, for example, if start is 2 and end is 10, the output would be 2. (as 3 and 9 are powers of 3).
Below is my code:
#include <stdio.h>
#include <math.h>
int main(void) {
int start, end, i, count = 0;
printf("Enter start and end: ");
scanf("%d %d", &start, &end);
for (i = start; i <= end; i++) {
if ((log(i) / log(3)) == floor((log(i) / log(3)))) {
printf("%d\n", i);
count++;
}
}
printf("Answer = %d\n", count);
return 0;
}
But, when I tried to run one of the test cases [3, 1000], the output is 5, when it should be 6.
3
9
27
81
729
Answer = 5
The number 243 is missing. Is there something wrong with my code?
The problem is you are using exact comparison of floating point numbers. Specifically, here:
if ((log(i)/log(3)) == floor((log(i)/log(3))))
Since log() and floor() return double, you're comparing without any tolerance two values which cannot be compared that way.
How should I do floating point comparison?
Your immediate problem has to do with the imprecision of floating point numbers, something that is generally well documented on the net, including various methods useful in fixing that problem.
However, I'm not actually going to bother referring you to them because the use of floating point is totally unnecessary here. There's a much more efficient way of doing this that involves only integers.
Rather than going through numbers in your range looking for powers of three using floating point operations, you would be better off going through powers of three (using just integer multiplication) looking for numbers in your range.
In pseudo-code, that would go something like:
powerOfThree = 1
while powerOfThree <= endRange:
if powerOfThree >= startRange:
print powerOfThree
powerOfThree = powerOfThree * 3
You could even make it more efficient by selecting a more suitable starting value for powerOfThree but, since there are only 40-odd powers of three in a 64 bit number, that's probably a waste of time.
When converting from pseudo-code to the more concrete C, you unfortunately come across the limitations of the datatypes in that language, specifically the fact that multiplication may result in overflow.
There are various ways you can avoid this this such as detecting that it's about to happen and exiting the loop early.
Given below is the function that you need, one which handles this issue, along with some test code which can be used for validating it.
#include <stdio.h>
#include <limits.h>
// I hate typing :-)
typedef unsigned long ULONG;
typedef unsigned int UINT;
static UINT countPowersOfThreeBetween (ULONG low, ULONG high) {
// Catch invalid params, just exit with zero.
if (low > high) return 0;
// Go through all powers of three.
ULONG powerOfThree = 1;
UINT count = 0;
do {
// If within your range, count it.
if ((powerOfThree >= low) && (powerOfThree <= high)) {
count++;
// printf ("DEBUG: got %lu\n", powerOfThree);
}
// Early exit if about to overflow.
if (ULONG_MAX / powerOfThree < 3) break;
// Advance to next power and continue if within range.
powerOfThree *= 3;
} while (powerOfThree <= high);
// Notify caller of count.
return count;
}
// Test function to make test suite easier.
static void testRange (ULONG low, ULONG high) {
UINT count = countPowersOfThreeBetween (low, high);
printf ("In range %lu..%lu, found %u occurrences\n", low, high, count);
}
// Test suite, add whatever you need.
int main (void) {
testRange (1000, 10);
testRange (0, 0);
testRange (9, 9);
testRange (3, 1000);
testRange (0, ULONG_MAX);
testRange (ULONG_MAX, ULONG_MAX);
return 0;
}
As you will see from the output, this gives the correct counts for various ranges:
In range 1000..10, found 0 occurrences
In range 0..0, found 0 occurrences
In range 9..9, found 1 occurrences
In range 3..1000, found 6 occurrences
In range 0..18446744073709551615, found 41 occurrences
In range 18446744073709551615..18446744073709551615, found 0 occurrences
And, if you uncomment the printf line in countPowersOfThreeBetween(), you'll also see the actual values detected.
Before choosing floating point types in the future, I strongly recommend you read this article entitled "What every computer scientist should know about floating-point arithmetic", by David Goldberg. It explains your problem(s) nicely, much better than I could have.
You don't actually need floating point (or negative integer) types here, so they should be avoided. Form your powers by multiplication, rather than addition:
#include <assert.h>
#include <limits.h>
#include <stdio.h>
int main(void){
unsigned int start, end, i, count = 0;
printf("Enter start and end: ");
int x = scanf("%u %u", &start, &end);
assert(x == 2); // XXX: INSERT PROPER ERROR HANDLING!
// find the first power greater than or equal to start
for (i = 1; i < start && UINT_MAX / 3 >= i; i *= 3);
// ... then count each one less than or equal to end
while (i <= end && UINT_MAX / 3 >= i) {
printf("%u\n", i);
i *= 3;
count++;
}
printf("Answer = %u\n", count);
}
Your problem is round-off error while float calculating in computer, the result of log(243)/log(3) is not exactly log3(243), where computer store approximate value of it. eg, in my 32bit computer, it is 4.99999999999999911182.
However, you have two ways to solve it,
use integer calculation instead of float.
simple mathematical transformation.
number of powers of 3 in [start, end] is equivalent to floor(log3(end)-log3(start))+1, wrote in c is
printf("answer:%d\n", (int)((log(1000)-log(3))/log(3))+1);
complete code:
#include <stdio.h>
#include <math.h>
int pow3(int n) {
int ret = 1;
while(n--) {
ret *= 3;
}
return ret;
}
int main() {
int a, start, end, answer;
scanf("%d%d", &start, &end);
a = (int)(log(start+0.5)/log(3));
//printf("%d,%d,%d\n", a, pow3(a), start);
if(start == end) answer = (start == pow3(a));
else answer = (int)((log(end+0.5)-log(start))/log(3))+1;
printf("answer = %d\n", answer);
}
Result:
Input[0]: 2 10
Output[0]: 2
Input[1]: 1 3
Output[1]: 2
Input[2]: 3 1000
Output[2]:6
Your program fails because of floating point precision issues.
Use integer arithmetics instead:
#include <limits.h>
#include <stdio.h>
int main(void) {
unsigned int start, end, i, count;
printf("Enter start and end: ");
if (scanf("%u %u", &start, &end) == 2) {
for (i = 1, count = 0; i <= end && i <= UINT_MAX / 3; i *= 3) {
if (i >= start) {
printf("%u\n", i);
count++;
}
}
printf("Answer = %u\n", count);
}
return 0;
}
A direct solution with floating point arithmetics is possible too:
#include <math.h>
#include <stdio.h>
int main(void) {
unsigned int start, end, count = 0;
printf("Enter start and end: ");
if (scanf("%u %u", &start, &end) == 2) {
if (end > 0 && end >= start) {
int start3 = (start <= 1) ? 0 : (int)(log(start - 0.5) / log(3));
int end3 = (int)(log(end + 0.5) / log(3));
count = end3 - start3;
}
printf("Answer = %u\n", count);
}
return 0;
}
Related
I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.
Hello guys i am trying to implement a program which is finding the happy numbers were between two numbers A and B.
Summing the squares of all the digits of the number, we replace the number with the outcome, and repeat the process. If after some steps the result is equal to 1 (and stay there), then we say that the number N is **<happy>**. Conversely, if the process is repeated indefinitely without ever showing the number 1, then we say that the number N is **<sad>**.
For example, the number 7 is happy because the procedure described above leads to the following steps: 7, 49, 97, 130, 10, 1, 1, 1 ... Conversely, the number 42 is sad because the process leads to a infinite sequence 42, 20, 4, 16, 37, 58, 89, 145, 42, 20, 4, 16, 37 ...
I try this right down but i am getting either segm faults or no results.
Thanks in advance.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
printf("%ld %d\n",A,npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == 1 || A[0] == 7)
printf("%c\n",A[0]);
printf("%s\n",A);
return;
}
long sum = 0 ;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = atoi(&A[i]);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Thanks for your time.
by the definition of your program sad numbers will cause your program to run forever
Conversely, if the process is repeated indefinitely
You need to add a stopping condition, like if I have looped for 1000 times, or if you hit a well known non terminating number (like 4) (is there a definite list of these? I dont know)
I find this solution tested and working..
Thanks for your time and I am sorry for my vagueness.
Every advice about this solution would be welcome
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
if (happynum ==1)
printf("%s\n",Ap);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == '3' || A[0] == '6' || A[0] == '9')
{
happynum = 0;
}
else
{
happynum = 1;
}
return;
}
long sum = 0;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = (int)(A[i]-48);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Your code uses some questionable practices. Yoe may be misguided because you are concerned about performance and memory usage.
When you allocate memory for the string, you forget to allocate one character for the null terminator. But you shouldn't be allocating, re-allocating and freeing constantly anyway. Dynamic memory allocation is expensive compared to your other operations.
Your limits are long, which may be a 32-bit or 64-bit signed integer, depending on your platform. The maximum number that can be represented with e 64-bit signed integer is 9,223,372,036,854,775,807. This is a number with 19 digits. Add one for the null terminator and one for a possible minus sign, so that overflow won't hurt, you and use a buffer of 21 chars on the stack.
You probably shouldn't be using strings inthe first place. Use the basic code to extract the digits: Split off the digit by taking the remainder of a division by 10. Then divide by 10 until you get zero. (And if you use strings with a fixed buffer size, as described above, you don't have to calculate the difits separately: sprintf returns the number of characters written to the string.
Your functions shouldn't be recursive. A loop is enough. As pm100 has noted, you need a termination criterion: You must keep track of the numbers that you have already visited. Each recursive call creates a new state; it is easier to keep an array, that can be repeatedly looked at in a loop. When you see a number that you have already seen (other than 1, of course), your number is sad.
Happy and sad numbers have this property that when your sum of squares is a number with a known happiness, the original number has this happiness, too. If you visit a known das number, the original number is sad. If you visit a known happy number, the original number is happy.
The limits of your ranges may ba large, but the sum of square digits is not large; it can be at most the number of digits times 81. In particular:
type max. number number of max. square sum dss
int 2,147,483,647 1,999,999,999 730
uint 4,294,967,295 3,999,999,999 738
long 9,223,372,036,854,775,807 8,999,999,999,999,999,999 1522
ulong 18,446,744,073,709,55,1616 9,999,999,999,999,999,999 1539
That means that when you take the sum of digit squares of an unsigned long, you will get a number that is smaller than 1540. Create an array of 1540 entries and mark all known happy numbers with 1. Then you can reduce your problem to taking the sum of digit squares once and then looking up the happiness of the number in this array.
(You can do the precalculation of the array once when you start the program.)
#include <stdio.h>
#include <math.h>
/* converts to binary using logs */
int main()
{
long int decimalNUM = 0, binaryNUM = 0, exponentNUM = 0;
printf("Enter a number to be converted to binary.\t");
scanf("%ld", &decimalNUM);
fflush(stdin);
int origDEC = decimalNUM;
while (decimalNUM > 0)
{
exponentNUM = (log(decimalNUM))/(log(2));
binaryNUM += pow(10, exponentNUM);
decimalNUM -= pow(2, exponentNUM);
}
printf("\nBINARY FORM OF %ld is %ld", origDEC, binaryNUM);
getchar();
return binaryNUM;
}
If STDIN is 4 it returns 99 and it should not. On IDEONE it returns 100. Why?
EDIT seems that any even number above two returns something with nines in it
Floating point operations like log are not exact. On my machine this code runs as expected (4 on STDIN gives 100).
One way you could do this, is by using the mod (%) operator with successive powers of two.
Works fine : http://ideone.com/PPZG5
As mentioned in the comments, your approach is really strange.
A general base-n conversion routine looks like:
void print_base_n(int val, int n) {
if(val==0) { printf("0"); return; }
else if(val < n) { printf("%d", val); return; }
print_base_n(val/n, n);
printf("%d", val % n);
}
As a homework problem, I'm working on reading a decimal int from stdin, converting it to a different base (also provided from stdin) and printing it to the screen.
Here's what I've got so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// keep dividing to find remainders
while (quotient > 0) {
remainder = num % base;
quotient = num / base;
num = quotient;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
}
printf("\n");
return 0;
}
This works great, only that the algorithm this uses calculates the converted numbers from least significant to most significant digit, thus printing it in reverse. So, for example, converting 1020 to hexadecimal ( 0x3FC ) will print CF3.
Is there a trick I could use to reverse these numbers to print in the correct order. I can only use if-else, while, simple math operators and printf()/getchar()/scanf() - no functions, arrays or pointers. thanks.
(removed original part of the post here, since it is not the solution)
Then the only solution I can see is to perform the loop that you have now the number of times that you have digits.
So, first you calculate all digits till you get to the last, and then print it.
Then you take the original value + base and start dividing again till you come to the second "highest value" digit, then print it.
It is a double loop and you calculate everything twice, but you don't use extra storage.
It's a good try, and well phrased question. If only we had more people asking questions in such a clear manner!
The restrictions seem artificial. I guess you haven't learned about functions, arrays, pointers etc., in your class yet, but I think this problem is not meant to be solved elegantly without functions and/or arrays.
Anyway, you can do something like this:
curr := base
pow := 1
while num / curr >= 1 do:
curr := curr * base
pow := pow + 1
while pow >= 1:
pow := pow - 1
print floor(num / base ** pow)
num := mod(num, base ** pow)
Basically, you are calculating how many digits you will need in the first loop, and then printing the digits in the correct order later.
Some specific issues with your code. I understand it's the beginning of a C class, but still, it's better to know of such issues now than to never realize them:
printf("please enter a positive number to convert: ");
You should add an fflush(stdout) after this to make sure the output appears before scanf() is called. By default, stdout is line buffered on many systems, so the prompt may not appear before your program waits for input.
printf("please enter the base to convert to: ");
Same as above.
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
You're assuming ASCII character set. This need not be true. But without arrays or pointers, there's no easy way to print the alphabets corresponding to 10.... Also, your code may print weird characters for base > 36.
You should also be aware that it's very hard to use scanf() safely. Hopefully you will learn better ways of getting input later.
In one loop you can calculate the number of digits and the big_base.
In a second loop you can output the digits starting from the most significant, like this:
n = 1020, 3 hex digits, big_base = 16*16
1st step
1020 / (16*16) = 3
2nd step
n = 1020- 3*(16*16) = 252
252 / (16) = 15, F
3rd step
n = 252 - 15*16 = 12, C
Hey ! I recognize a famous homework I had in first year of my school too (#Epitech students : don't copy/paste the following code, try to come up with your own solution, it's for your own good ^^)
The solution to your problem is to perform the problem in a recursive way :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
Does your homework specifies that it should only work with positives numbers ? If not, it's easy to include the negative numbers handling :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
}
#arno : that's true, because the exemple code is using ASCII table. If we want something trully flexible we need the base in parameter. For example :
>> my_putnbr_base(4242, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
39U
>> my_putnbr_base(42, "0123456789ABCDEF")
2A
this implements the example :
void my_putnbr_base(int num, char *base)
{
int start;
int remainder;
int len;
len = strlen(base);
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % len;
start = (num - remainder) / len;
if (start != 0)
my_putnbr_base(start, base);
printf("%c", base[remainder]);
}
}
I hope it solves your problem !
edit: I didn't read correctly ^^ You are not allowed to use functions, so recursion is out of the question... Here is an interative way, you can put this in a main(). You can improve this code by adding the negative numbers handling and flexible bases, as I showed you :)
int my_putnbr_base_it(int num, int base)
{
unsigned int quotient = 1;
unsigned int remainder;
while ((num / quotient) >= base)
quotient *= base;
while (quotient)
{
if ((remainder = (num / quotient) % base) < 10)
printf("%d", remainder);
else
printf("%c", 55 + remainder);
quotient /= base;
}
return (0);
}
Hope it solves everything now !
You could rewrite the piece of code calculating each number to behave as a state machine. It will start in the initial state and compute the number of digits, then change the state to "print the Nth digit" to print the most significant digit, then change the state to proceed to the less significant digits, etc until it eneters the final state. Running this inside a loop you will output all digits in proper order.
You could use two loops. The first keeps generating powers of the base until it finds a power greater than the input number. The second starts from here (or rather, one power before) and works back to base^0 (i.e. 1) to compute the output digits most significant first.
Untested pseudo-code:
// Determine highest power, don't actually need "power" it's just there for illustration
power = 0;
baseraisedtopower = 1;
while (baseraisedtopower <= input)
{
baseraisedtopower *= base;
power++;
}
// Go back one step, could have saved previous result
baseraisedtopower /= base;
power--;
// Output
while (input > 0)
{
// Integer division, truncate
quotient = input / baseraisedtopower;
printf("%c", quotient + 55);
input -= quotient * baseraisedtopower;
baseraisedtopower /= base;
power--;
}
You can give a try at this approach.
It's more a proof of concept, you'll still need to handle some special case, but, hey, that's your homework :)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
int divider;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// First get the highest divider
divider = base;
while ( num / divider > base ) {
divider *= base;
}
do {
// Get the highest digit
remainder = num / divider;
// And update num accordingly
num -= remainder * divider;
divider /= base;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
} while ( divider );
printf("\n");
return 0;
}
Interesting task, you've got as a homework.
I am a beginner programmer to, and I've tried to resolve this task.
The following code is working (I haven't tested a lot, apparently is working). I am sure it's not the optimal&best solution, but was the only thing I've could come up with. It should work with any base. Unfortunately it won't convert 10->A, 11->B, etc.:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int nr,base,res,tp,tpb,tpbt,r,rnr,lp,lpt,i;
float baset,rt;
/** Read number */
printf("nr=");
scanf("%d",&nr);
/** Read base */
printf("base=");
scanf("%d",&base);
/** Returning result */
res=0;
/** Test if number is positive
and base is bigger than 2 */
if(nr<0||base<2){
/** Error */
res=1;
}
else{
/** Determine how many
digits are necessary */
lp=0;
baset=base;
while(baset>1){
lp++;
baset/=10;
}
/** Determine full power
of 10 when r has length of lp */
tpb=1;
while((lp--)>0){
tpb*=10;
}
/** Power of ten that will be
incremented */
tp=0;
/** Converted number (will be printed
as the result) */
rnr=0;
/** Algorithm */
while(nr>0){
r=nr%base;
nr/=base;
rt=r;
/** Temporary lp for
r */
lpt=0;
while(rt>1){
lpt++;
rt/=10;
}
/** Temporary tpb for
lpt */
tpbt=tpb;
for(i=0;i<lpt;i++){
tpbt/=10;
}
/** Build number */
rnr+=r*pow((double)(tpbt),(double)(tp++));
}
}
/** Show number */
printf("number is: %d \n",rnr);
return (res);
}
Based on what was suggested, the way to tackle this was to keep print the last number and repeat the loop for every digit. I kept track of the print condition by saving the previous quotient and printing when I got to it every time (then reseting the number and starting over), then reset it to the one before. Sounds complicated, but the change to the code was simple. My stop condition for the loop was when I had 2 consecutive prints, since most of the time it would just calculate quotient/remainder and print nothing, and when 2 digits print in a row, it's the last two. Anyway, here's the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, saved, base, remainder;
int quotient, prev_q, stop_q, just_printed;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
saved = num;
remainder = quotient = prev_q = just_printed = 1;
stop_q = 0;
// validate input
if (num <= 0 || base <= 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// divide
while (1) {
remainder = num % base;
quotient = num / base;
num = quotient;
// print if it's the last number and reset num to the next
if (quotient == stop_q) {
if (remainder >= 10) { printf("%c", remainder + 55); }
else { printf("%d", remainder); }
// if 2 consecutive printing occur, this means it's time to end this
if (just_printed) { break; }
// next time print when hitting the previous quotient
stop_q = prev_q;
// reset the number to the original value
num = saved;
just_printed = 1;
} else {
just_printed = 0;
}
prev_q = quotient;
}
printf("\n");
return 0;
}
Thanks to everyone who pitched in!
We could use a recursive function to reverse the order of the digits of a number :
We'll need some mathematical functions from these libraries - stdlib.h and math.h
int reverse(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverse(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
'If statement' is the base case for the recursive function.
'Else statement' may look intimidating at first but it's actually just simple arithmetic. floor(log10(abs(x))) gives us the number of digits of x, so ((x%10)*(pow(10, (floor(log10(abs(x))))))) is just putting the 'ones' place digit of the number to its correct place in accordance with the desired reversed number.
For better comprehension let's take an example, Let 123 be the number we need to reverse. The first thing that the function reverse will do is ask itself the reverse of 12 (reverse(x/10)) and when the function is called for the second time with argument 12 it'll ask itself the reverse of 1, Now this will be the base case for our function. It'll return 1 as abs(1)<=9, Now 2 will be prepended using ((x%10)*(pow(10, (floor(log10(abs(x)))))) it then will return 21 and 3 will be prepended by the same.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int reverse(int x);
int main()
{
int x, revInt;
scanf("%d", &x); // input : 123
revInt = reverse(x);
printf("%d", revInt); // output : 321
return 0;
}
By starting with 1 and 2, the first 10 terms of Fibonacci Series will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not exceed 4 million.
Now, I got the idea for how to do this. But I'm confused about the data types to hold such big data. I'm getting weird results with int. :(
MORE: Its Project Euler 2nd question. But I can't get it. I get crazy values as answer. Can someone please post the ideal program?
EDIT: Here's what I wrote for just printing Fibonacci to screen. Bare Basic. My variable goes crazy even when I give 100 for the limit. Is my code wrong?
// Simple Program to print Fibonacci series in Console
#include <stdio.h>
int main() {
int x=1,y=2,sum=0,limit=0,i=0,temp=0;
printf("Enter Limit:");
scanf("%d",&limit);
if(limit==1)
printf("%d",x);
else if(limit>1) {
printf("%d %d",x,y);
if (limit>2) {
while (i<limit-2) {
temp=y;
sum=x+y;
x=temp;
y=sum;
printf(" %d",sum);
i++;
}
}
}
printf("\n");
return 0;
}
SOLVED: Actually, I managed to get the solution myself. Here's my program. It works.
#include <stdio.h>
int main() {
int x=1,y=2,sum,limit; //Here value of first 2 terms have been initialized as 1 and 2
int evensum=2; //Since in calculation, we omit 2 which is an even number
printf("Enter Limit: "); //Enter limit as 4000000 (4million) to get desired result
scanf("%d",&limit);
while( (x+y)<limit ) {
sum=x+y;
x=y;
y=sum;
if (sum%2==0)
evensum+=sum;
}
printf("%d \n",evensum);
return 0;
}
Since you only want up to four million, it's likely that int is not your problem.
It's quite possible that your program is buggy and that the data storage is just fine, so you should test your program on smaller values. For example, it's clear that the sum of the first three even terms is 44 (hint: every third term is even) so if you run your program with a cap of 50, then you should instantly get 44 back. Keep running small test cases to get confidence in the larger ones.
For security, use the 'long' data type; the C standard requires that to hold at least 4 billion, but on most machines, 'int' will also hold 4 billion.
enum { MAX_VALUE = 4000000 };
int sum = 0;
int f_n0 = 0;
int f_n1 = 1;
int f_n2;
while ((f_n2 = f_n0 + f_n1) < MAX_VALUE)
{
if (f_n2 % 2 == 0)
sum += f_n2;
f_n0 = f_n1;
f_n1 = f_n2;
}
printf("%d\n", sum);
I am not a programmer, but here's an adaptation to Leffler's code without the IF-criterion. It should work for MAX_VALUES above 2 (given there are no mistakes in programming syntax), based on a pattern I found in the even-only fibonacci series: 0,2,8,34,144,610,2584... so interestingly: f_n2 = 4*f_n1 + f_n0. This also means this program only needs 1/3rd of the calculations, since it doesn't even consider/calculate the odd fibonacci numbers.
enum { MAX_VALUE = 4000000 };
int sum = 2;
int f_n0 = 0;
int f_n1 = 2;
int f_n2 = 8;
while (f_n2 < MAX_VALUE)
{
sum += f_n2;
f_n0 = f_n1;
f_n1 = f_n2;
f_n2 = 4*f_n1 + f_n0;
}
printf("%d\n", sum);
Try changing this:
while (i<limit-2)
to this:
while (y<limit)
As written, your program is cycling until it gets to the 4 millionth Fibonacci number (i.e. when i gets to 4 million, though overflow obviously happens first). The loop should check to see when y (the larger Fibonacci number) becomes greater than 4 million.
Guys, I got the answer. I confirmed the result and int can handle it. Here's my program:
#include <stdio.h>
int main() {
int x=1,y=2,sum,limit; //Here value of first 2 terms have been initialized as 1 and 2
int evensum=2; //Since in calculation, we omit 2 which is an even number
printf("Enter Limit: "); //Enter limit as 4000000 (4million) to get desired result
scanf("%d",&limit);
while( (x+y)<limit ) {
sum=x+y;
x=y;
y=sum;
if (sum%2==0)
evensum+=sum;
}
printf("%d \n",evensum);
return 0;
}
Thx for all the replies and help. "Thinking on my feet" to the rescue :)
An amusing solution is to use the closed form for Fibonacci sequences and the closed form for geometric progressions. The end solution looks like this:
sum = ( (1-pow(phi_cb, N+1)) / (1-phi_cb) - (1-pow(onephi_cb,N+1)) / (1-onephi_cb)) / sqrt(5);
where
double phi = 0.5 + 0.5 * sqrt(5);
double phi_cb = pow(phi, 3.0);
double onephi_cb = pow(1.0 - phi, 3.0);
unsigned N = floor( log(4000000.0 * sqrt(5) + 0.5) / log(phi) );
N = N / 3;
with all the caveats regarding double to int-type conversions of course.
int is big enough for values in the millions on almost every modern system, but you can use long if you are worried about it. If that still gives you weird results, then the problem is with your algorithm.
Use BigInt.
Then again, unsigned int stores values up to over 4 billion, so you shouldn't be having any problems even with "sum of all fibonacci numbers up to 4 million" (which, obviously, has to be less than 8 mil)?
Your program prints F_1 + ..+ F_limit and not F_1 + ... F_n with F_n < limit as you described.
Check the Wikipedia article on Fibonacci Numbers and Sloane A000045: Fibonacci numbers grows exponentially. Checking this table F_48 = 4807526976 which exceeds int. F_100 is 354224848179261915075 which surely overflows even int64_t (your stack doesn't, though).
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
int main()
{
long first = 1, second = 2, next, c;
int sum=0;
for ( c = 1 ; c <100000000; c++ )
{
next = first + second;
if(next>=4000000)
{
next= next-second;
break;
}
first = second;
second = next;
if(next%2==0){
sum=sum+next;
}
}
printf("the sum of even valued term is %d\n",sum+2);
}
Here's my program:
#include <iostream>
long int even_sum_fibonacci(int n){
int i = 8;
int previous_i = 2;
int next_i = 0;
long int sum = previous_i + i;;
while(n>next_i){
next_i = i*4 + previous_i;
previous_i = i;
i = next_i;
sum = sum + i;
}
return sum - next_i; //now next_i and i are both the bigger number which
//exceeds 4 million, but we counted next_i into sum
//so we'll need to substract it from sum
}
int main()
{
std::cout << even_sum_fibonacci(4000000) << std::endl;
return 0;
}
Because if you look at the fibonacci series (at the first few even numbers)
2 8 34 144 610 2584 ... you'll see that it matches the pattern that
next_number = current_number * 4 + previous_number.
This is one of solutions. So the result is 4613732
You can try the below code.
public static void SumOfEvenFibonacciNumbers()
{
int range = 4000000;
long sum = 0;
long current = 1;
long prev = 0;
long evenValueSum= 0;
while (evenValueSum< range)
{
sum = prev + current;
prev = current;
current = sum;
if (sum % 2 == 0 )
{
evenValueSum = evenValueSum+ sum;
}
}
Console.WriteLine(evenValueSum);
}
You can use the above code.
import numpy as np
M = [[0,1],[1,1]]
F = [[0],[1]]
s = 0
while(F[1][0] < 4000000):
F = np.matmul(M, F)
if not F[0][0]%2:
s+=F[0][0]
print(s)
We can do better than this in O(log n) time. Moreover, a 2 × 2 matrix and a two dimensional vector can be multiplied again in O(1) time. Therefore it suffices to compute Mn.
The following recursive algorithm computes Mn
If n = 0, return I2
If n = 1, return M.
If n = 2m.
Recursively compute N = Mm, and set P = N2.
If n = 2m+1, set P = PM.
Return P.
We have T(n) = T(n/2) + O(1), and by master's theorem T(n) = O(log n)
You can also use recurrence for Even Fibonacci sequence is:
EFn = 4EFn-1 + EFn-2
with seed values
EF0 = 0 and EF1 = 2.
SIMPLE SOLUTION WOULD BE:-
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int n1=1;
int n2=2;
int num=0,sum;
for (int i=1;i,n1<4000000;i++)
{
cout<<" "<<n1;
num=n1+n2;
if(!(n1%2))
{
sum+=n1;
}
n1=n2;
n2=num;
}
cout<<"\n Sum of even term is = "<<sum;
return 0;
}
Here's my offer, written in Java. I had been using a for loop whose exit value was 4000000 but realized early on there was a serious overflow for the sum of the numbers. Realizing the Fibonacci Number has to be less than 4 million (and not the sum), I changed to a while loop and got it:
class Main {
public static void main(String[] args) {
int counter = 0;
int fibonacciSum = 0, fibonacciNum = 0;
int previous = 1, secondPrevious = 0;
fibonacciNum = previous + secondPrevious;
while (fibonacciNum <= 4000000){
if (fibonacciNum % 2 == 0 ){
counter++;
fibonacciSum += fibonacciNum;
secondPrevious = previous;
previous = fibonacciNum;
}//ends if statement
else {
secondPrevious = previous;
previous = fibonacciNum;
}//ends else statement
fibonacciNum = previous + secondPrevious;//updates number
}//ends loop
System.out.println("\n\n\n" + fibonacciSum);
}//ends main method
}//ends Main