C - need to detect presence of digit in a number (hw) - c

I'm trying to write a function that'll detect if a digit is found in a number:
// returns 1 if source contains num, 0 otherwise
int contains_num(source, num);
for example, contains_num(12345, 3) returns 1 and contains_num(12345, 6) returns 0.
I'm not sure how to go about solving this. Probably can't use pointers, arrays and such.
Any ideas? thanks.

Since this is homework, I don't want to give you the entire answer right away. Instead, I'll ask a series of questions, and let you answer in the comments, so I'll simply be guiding you to the correct answer rather than giving it to you outright.
So, you have a number, and you want to break it down into individual digits. Can you think of a way of extracting one digit from the number, say, the last one? Think about what each digit represents, and how you might be able to isolate one digit from the rest of them.

An alternative way of looking at the problem is:
Does the string representation of the number contain a specific digit?
It is relatively easy to convert the number to a string; there are string searching functions to find whether a specific character appears in the string.
And this has the merit of working on negative numbers whereas some of the suggestions I've seen fail on negative numbers (and most of the rest do not address the issue explicitly). (Question for you: why?)

This should work:
int Contains_Num(int source, int num)
{
if (source == 0 && num == 0) return 1;
int tmpSource = source;
while (tmpSource != 0)
{
if (tmpSource % 10 == num) return 1;
tmpSource /= 10;
}
return 0;
}

Your answer is dependent on the base a number is represented in. For example, the number 255 contains 5 when written in base 10, but in base 16, it does not. Your base seems to be 10.
So what you want to do is to look at the last digit of a number, and see if it is the digit you want. The last digit can be easily found using the modulo operator (%). If it is the digit you want, you're done. If not, and if there are more digits, you can discard the last digit and repeat the process again for the number obtained by dividing the original number by 10 and discarding the fractional part. In C, the division operator, /, does this for you automatically if both the operands of it are of integer type.
When you run out of digits because division gives you 0, you are sure that the number doesn't contain the digit you wanted.

Related

How to write a code that will count the number of prime digits that consists only of prime numbers

First, I need to input N.
For example, from 1 to 5, there is 3 prime number: 2,3,5.
Now, I need to find prime numbers that consists only from odd numbers.
53 is it's example.
It's always easier to think about code like this if you partition different functionality off into different functions. You can, theoretically, interweave all the code together, to have code that's checking for prime numbers and odd digits at the same time, but it's much harder to write, read, understand, and debug, so unless there's some compelling reason to compress everything (like, maybe, efficiency), for everyday purposes it's much easier to keep things separate.
So although you haven't quite written your code that way yet, what I'm imagining is that we have a number n we're interested in checking. In your case it's the loop variable in your for(i = 2; i <= N; i++) loop. If you were just counting primes, you'd have
if(isprime(n))
count++;
Here I'm imagining that you have a separate function called isprime() that you can call to see if a number is prime. (It would contain the same kind of code you currently have for setting your isPrime variable to true or false.) And then, if you want to count how many of the prime numbers have only odd digits, you might go to something like this:
if(isprime(n)) {
count++;
if(has_only_odd_digits(n))
count2++;
}
Arranged this way, count will be the count of how many numbers were prime, and count2 will be the count of how many numbers were prime and had only odd digits. (Different arrangements are obviously possible to answer different variants of the question, like how many numbers had only odd digits, whether or not they were prime.)
And then the obvious question is: Where does the hypothetical has_only_odd_digits function come from? We'll have to write it ourselves, of course, but the nice thing is that while we're writing it, we'll only have to think about the problem of determining whether digits are even or odd; we won't have to worry about prime numbers at all.
So let's take a first cut at writing has_only_odd_digits. You had a version, sort of, in the code you originally posted:
int has_only_odd_digits(int n)
{
if(n % 2 == 0) /* if even */
return 0;
else return 1;
}
But this is wrong: it just tests whether the number n itself is even or odd. It will return "false" for 2 and 20 and 222, and it will return "true" for 3 and 13 and 13579, but it will also return "true" for 2461, since 2461 is odd, even though it happens to have mostly even digits. So for a working version of has_only_odd_digits we need something more like this:
int has_only_odd_digits(int n)
{
for(each digit d of n) {
if(d % 2 == 0)
return 0;
}
return 1;
}
This is pseudocode, not real C code yet. Notice that this time there's no else in the if statement. If we find an even digit, we're done. But if we find an odd digit, we can't necessarily return "true" yet — we have to check all the digits, and only return true" if none of the digits were even.
But the real question is, how do we get at those digits? An int variable is not represented internally by anything remotely like an array of its decimal digits. No, an int variable is an integer, a number, and the only way to get at its decimal-digit representation is to, literally, divide it repeatedly by 10.
So, fleshing out our code just a little bit more, we're going to have something like
int has_only_odd_digits(int n)
{
while(n != 0) {
int d = one digit of n;
if(d % 2 == 0)
return 0;
n = the rest of n, except for the digit d we just checked;
}
return 1;
}
And that's as far as I'm going to take it: I think you've got the idea by now, and in case this is a homework assignment, I'm not going to do all the work for you. :-) I'll note that there's also still a discrepancy to nail down between your question title and your problem description in the question: are you looking for prime numbers with odd digits, or prime digits? (And if the latter, I'm honestly not sure what to do with 1's, but that'll be a question for you and your instructor, I guess.)
But, in closing, I want to point out a couple of things: besides learning how to count primes with odd digits, I hope you've also also begun to appreciated two, much more general, related points:
If you break a complicated program up into separate functions, it's much easier to think about each function (each part of the problem) in isolation.
If you're not sure how to do something, often you can attack it in little steps, sort of a "successive refinement" approach, like I did with the several different versions of the has_only_odd_digits function here.
Now, it's true, you can't necessarily just break a complicated problem up into functions any old way, and when you're solving a problem by stepwise refinement, you have to choose the right steps. But, still, these are definitely valuable approaches, and with time and experience, you'll find it easier and easier to see how to break a big problem down into pieces you can handle.

Using chars into an int datatype

Using C, One array with 5 memory spaces
int call[5]
I'm trying to figure out how to use the first 3 spaces of the array to make a base-36 conversion (meaning 1K0 base-36 equals to 2040 in base-10), the other 2 spaces would be filled with data (probably more ints).
However... does 1K0 look actually like an int? (to me K looks like a char and in theory, char should be enough -127 to 127 for the conversion using base-36)
however what would happen if i try to do this using int instead of char?
is there any alternative to use a base-36 conversion in the first array only mixed with ints for the rest of the spaces in memory
does it matter? (since the array was declared int)
EDIT: to be clear i just want to know if i can declare an int array and fill it with chars, and if i cant, how can i achieve this?
I'm not exactly sure if you can tell the compiler that, you can signal Hex (0x), octal (o) Binary (b) but base 36 is odd enough to not be standard.
You can always make a function (and maybe embed it in a class) that does the string-to-base10 conversion of base 36
I'll do my best in C terms
int base10Number = 0
int base36StringLenght = strlen(base35String);
for( int i = base36StringLenght - 1; i <= 0; i--){ //count from the end of the string back
char c = base36String[i];
if(c <= '9'){
c -= '0' //gives a 0 to 9 range
}
else{ //assuming that the string is perfect and has no extra characters is safe to just do this
c = tolower(c); //first make sure it's lowercase
c -= 'a' + 10 // this will make the letters start at 10 dec
}
base10Number += c * pow(36, base36StringLenght - 1 - i) // the power function specifies which 'wheel' you're turning (imagine an old analog odometer) and then turns the wheel c times, then adds it to the overall sum.
}
This whole code works by the theory that every digit starting from the last is worth its base 10 number multipled by 36 to the power of its position from last.
So last digit is c * 36^0 which is one, the c*36^1 and so on. similar on how 2*10^1 equals 20 if the 2 is in second-to-last position.
Hope that some of this makes sense to you, and dont forget to make your base36 number a string
EDIT:
I saw your edit to the answer and the short asnwer is yes, you can totally do that, it would be a waste of space since you'll have a whole 3 bytes unused at all times, you can simply make a char array. Besides, all string functions will demand you to feed them a char array (you can cast it) but if you're storing one digit per array space char will do the trick. If your array is dynamic and/or you need to make some math on it the base 36 to base 10 conversion will allow you to do math and to blow the whole array for a single int or float type. But if you're just going to store it to display it later or to feed it to another function in the same format the conversion is not necessary at all. (If you're working with a big ammount of this numbers and you need to put them in a database converting to base10 and storing in a single in will save tons of space)
PS: also edited the code to use ' ' enclosed chars instead of ascii numbers, thanks for the request!

How to increase the speed of computed Fibonacci caluculations - C

I wrote a small program to compute Fibonacci numbers:
#include <stdio.h>
int main()
{
int first, second, final;
first = 0;
second = 1;
printf("0\n1\n"); /* I know this is a quick fix, but the program still works */
while (final <= 999999999999999999) {
final = first + second;
first = second;
second = final;
printf("%d\n", final);
}
}
Is there any way to increase the speed in which this program computes these calculations? Could you possible explain the solution to me (if it exists)?
Thanks.
Of course it's possible! :)
First of all, please note you're using signed int for your variables, and max int on a 32 bit machine is 2,147,483,647 which is approx. 10^8 times smaller than the max number you're using, which is 999,999,999,999,999,999.
I'll recommend to change the max num to INT_MAX (You'll need to include "limits.h")
Edit:
In addition, as said in the comments to my answer, consider changing to unsigned int. you need only positive values, and the max number will be twice higher.
2nd Edit:
That being said, when final will reach the closest it can to the limit in the condition, the next time its promoted, it'll exceed INT_MAX and will result in an overflow. That means here, that the condition will never be met.
Better to just change the condition to the times you want the loop to run. Please note though, that any fibonacci number larger than the max numder that can be stored in your variable type, will result in an overflow.
Secondly, final isn't initialized. Write final = 0 to avoid errors.
I recommend turning on all the warnings in your compiler. It could catch many errors before they compile :)
Also, I see no reason not to initialize the variables when you declare them. The value is already known.
Now for the speed of the program:
I'm not sure to which extent you're willing to change the code, but the simplest change without changing the original flow, is to make less calls to printf().
Since printf() is a function that will wait for a system resource to become available, this is probably the most time consuming part in your code.
Maybe consider storing the output in a string, and lets say every 100 numbers print the string to the screen.
Try maybe to create a string, with a size of
(10 (num of chars in an int) + 1 (new line char) )* 100 (arbitrary, based on when you'll want to flush the data to the screen)
Consider using sprintf() to write to a string in the inner loop, and strcat() to append a string to another string.
Then, every 100 times, use printf() to write to the screen.
As already stated in other answers, you have obvious two problems. 1) The missing initialization of final and 2) that your loop condition will result in an endless loop due to 999999999999999999 being larger than any integer value.
The real problem here is that you use a fixed number in the condition for the while.
How do you know which number to use so that you actually calculates all the Fibonacci numbers possible for the used integer type? Without knowing the numbers in advance you can't do that! So you need a better condition for stopping the loop.
One way of solving this to check for overflow instead - like:
while (second <= (INT_MAX - first)) { // Stop when next number will overflow
The above approach prevents signed overflow by checking whether the next first + second will overflow before actually doing the first+second. In this way signed overflow (and thereby UB) is prevented.
Another approach is to use unsigned integers and deliberately make an overflow (which is valid for unsigned int). Using unsigned long long that could look like:
unsigned long long first, second, next;
first = 1;
second = 1;
printf("1\n1\n");
next = first + second;
while (next > second) { // Stop when there was an overflow
printf("%llu\n", next);
first = second;
second = next;
next = first + second;
}
Speed isn't your problem. You have an infinite loop:
while (final <= 999999999999999999) {
final has type int. Most likely int is 32-bit on your system, which means the maximum value it can hold is 2147483647. This will always be smaller than 999999999999999999 (which is a constant of type long long), so the loop never ends.
Change the datatype of your variables to long long and the loop will terminate after about 87 iterations. Also, you'll need to change your printf format specifier from %d to %lld to match the datatype printed.
Why are you asking this question?
If it's the intention to increase the performance, you might go for the formula of the n-th Fibonacci number, which is something like:
((1+v5)/2)^n + ((1-v5)/2)^n, something like that (v5 being the square root of 5).
If it's about learning to increase performance, you might do a code review or use performance diagnostics tools.

Converting a result of Integer to String or Word in C

so i have a problem here. I am working on my class assignment which is create a calculator but every result must be in a word, example :
int a,b,c;
printf("Input first number:");
scanf("%d", &a);
printf("Input second number:"):
scanf("%d", &b);
c=a+b;
printf("The result are: %d", c);
printf("If in words, it is = ");
switch(c){
case 0:printf("abcdef");break;
case 1:printf("bc");break;
case 2:printf("abged");break;
case 3:printf("abgcd");break;
case 4:printf("fbgc");break;
case 5:printf("afgod");break;
case 6:printf("fgcde");break;
case 7:printf("abc");break;
case 8:printf("abcdefg");break;
case 9:printf("abcdfg");break;
default :printf("error");break;
So the result from this when im running it is :
Input first number : 12
input second number : 12
The result are: 24
If in words, it is = error
so what I'm confused here is how I did print the c result as a word? so what i want from my output is
Input first number : 12
input second number : 12
The result are : 24
If in words, it is = abged fbcg
so far I'm searching for answers but I cannot find it. If anyone here can help me, please do.
Thanks in advance
*edited
what i want from my output is
Input first number : 12
input second number : 12
The result are : 24
If in words, it is = abged fbcg
The question would be much clearer if you had written "two four" instead of "abged fbcg"...
You apparently want to print the "tens" and the "ones" separately. (Probably the "hundreds" as well.)
As this is a homework assignment, I will only give you some hints instead of a complete solution:
If you divide c by 10, you get the "tens". If you divide that result by 10 again, you get the "hundreds".
If something like "two four" would be acceptable, you can use the same lookup for "tens" and "ones". If you actually need "twenty four", you need a lookup for "tens" and a different one for "ones".
You need to print the words for the highest-order (leftmost) digit first, but you get it last from the by-10 divisions I mentioned above. So you need to "store" the lookup result for "ones" somewhere while you do the lookup for "tens" (and, perhaps, "hundreds"). Storage could be...
...an array. Be careful to check the numbers entered against the space in the array (so you don't overflow if someone enters too-large numbers). If you do it right, you do not need to store the strings you looked up, as you could store pointers to those strings.
...a recursive function. (One that calls itself with the value divided by 10, then does the lookup for the "ones" of the value it was called with -- you get that via the modulo operator, c % 10.)
The first problem here, you missed to use the break statement after each case statement.
Hence, yours is a fall-through switch case, which is not what you want. It will jump to the case matching in switch statement and then fall-thorough all other available case statements.
Once you have solved that problem, one of the possible the approach to target the next problem is to explain it properly, with the current description, it's not very clear.
Use a lookup for all the options of this word and then print the relevant according to the index without all the switch case mess
char* lookup = {
{"abcdef\n"},
{"bc\n"},
{"abged\n"},
{"abgcd\n"},
{"fbgc\n"},
{"afgod\n"},
{"fgcde\n"},
{"abc\n"},
{"abcdefg\n"},
{"abcdfg\n"},
};
then==>
c=a+b;
if (c>9)
{
printf("error\n");
}
else
{
printf(lookup[c]);
}
ok, so you mean you want to print a string for each digit of a number, which is the result of whatever math function?
Try [untested]
int d = c;
do {
switch (d % 10) { /* your replacement-text-switch goes here */ }
d /= 10;
} while (d != 0)
This will print out the number in reverse.
If you want to print it out the other way, then you have to know about the maximum number you are going to calculate. (Or, being advanced you can use logarithm to determine the length of a number.)

Goldbach theory in C

I want to write some code which takes any positive, even number (greater than 2) and gives me the smallest pair of primes that sum up to this number.
I need this program to handle any integer up to 9 digits long.
My aim is to make something that looks like this:
Please enter a positive even integer ( greater than 2 ) :
10
The first primes adding : 3+7=10.
Please enter a positive even integer ( greater than 2 ) :
160
The first primes adding : 3+157=160.
Please enter a positive even integer ( greater than 2 ) :
18456
The first primes adding : 5+18451=18456.
I don't want to use any library besides stdio.h. I don't want to use arrays, strings, or anything besides for the most basic toolbox: scanf, printf, for, while, do-while, if, else if, break, continue, and the basic operators (<,>, ==, =+, !=, %, *, /, etc...).
Please no other functions especially is_prime.
I know how to limit the input to my needs so that it loops until given a valid entry.
So now I'm trying to figure out the algorithm.
I thought of starting a while loop like something like this:
#include <stdio.h>
long first, second, sum, goldbach, min;
long a,b,i,k; //indices
int main (){
while (1){
printf("Please enter a positive integer :\n");
scanf("%ld",&goldbach);
if ((goldbach>2)&&((goldbach%2)==0)) break;
else printf("Wrong input, ");
}
while (sum!=goldbach){
for (a=3;a<goldbach;a=(a+2))
for (i=2;(goldbach-a)%i;i++)
first = a;
for (b=5;b<goldbach;b=(b+2))
for (k=2;(goldbach-b)%k;k++)
sum = first + second;
}
}
Have a function to test primality
int is_prime(unsigned long n)
And then you only need to test whether a and goldbach - a are both prime. You can of course assume a <= goldbach/2.
And be sure to handle goldbach = 4 correctly.
If the requirements don't allow defining and using your own functions, ignore them first. Solve the problem using any functions you deem helpful and convenient. When you have a working solution using disallowed functionality, then you start replacing that with allowed constructs. Self-defined functions can be inlined directly, replacing the return with an assignment, so instead of if (is_prime(a)), you have the code to determine whether a is prime and instead of returning the result you assign it is_prime = result; and test that variable if (is_prime). Where you have used library functions, reimplement them yourself - efficiency doesn't matter much - and then inline them too.

Resources