Find smallest number Q whose product of digits is N - c

In the following code
#include <stdio.h>
#define MAX 1000000000
int main()
{
int n,temp,prod,i;
scanf("%d",&n);
for(i=1;i<MAX;i++)
{
temp=i;
prod=1;
while(temp!=0)
{
prod=prod*(temp%10);
temp=temp/10;
}
if(prod==n)
{
printf("%d",i);
break;
}
}
return 0;
}
The code is working. I need to input a number N and find the smallest integer Q such that the product of its digits is N. For example, if N=10, Q=25. I need to output -1 if there is no such number Q. Putting the following strip of code after the if code strip gives -1 for all inputs
else
{
printf("-1");
break;
}
What am I doing wrong?

If you put the else block inside the loop then it will fire as soon as any single guess fails. You want it to fire after all guesses have failed. That means the -1 printout needs to be outside of the loop, after you've tried all the numbers and found all of them to be wrong.
But that means you can't use an else block. You'll need to use something else. How do you detect if the loop failed? One common way is to use a variable to track whether the loop succeeded or failed. For example, set found = 0 before the loop starts, and inside the if statement when you've found a match set found = 1. Then after the loop ends, check the value of found. If it's still 0 then you didn't find a match and can output -1.
int found = 0;
for (i = 1; i < MAX; i++)
{
// ...
if (prod == n)
{
printf("%d\n", i);
found = 1;
break;
}
}
if (found == 0) // could also be written: if (!found)
{
printf("-1\n");
}

What happens when i == 1? You calculate prod = 1. And unless n = 1, the if-condition is false, and you print -1 and exit the loop.
Nice problem though. How would you go about finding the solution if n = 1,000,000,000?

Better would be to find one-digit factors of N and see which combination of products is minimum.

Related

C program to write a GUESS game with certain constraints. Problems occuring - error in code, logic of code, suggesstions

Question :
Write a guessing game where the user has to guess a secret number. After every guess the program tells the user whether their number was too large or too small. At the end the number of tries needed should be printed. It counts only as one try if they input the same number multiple times consecutively.
My code :
#include<stdio.h>
#include<stdlib.h>
int compare(int m) {
int b;
b=73-m; ///I chose my number as 73 here.
if (b=0) printf("Congrats, you won.");
else {
if (-5 < b < 5) printf("Very Close\n"); ///always gives me this output two times.
else {
if (-15 < b < 15) printf("Close");
else {
printf("You are far");
}
}
}
return b;
}
int main() {
int arr[100],guess,count=0,i,m; ///I have 99 tries.
arr[0]=0;
for(i=1 ; i<=100 ; i++) {
printf("Enter your guess\n");
scanf("%d",&guess);
if(guess==arr[i-1]) {
arr[i]=guess;
printf("Guess is same as the previous input.\n");
} else {
arr[i]=guess;
compare(guess);
if (m = compare(guess)) {
count=count+1; /// can i create a separate function to keep the count?
printf("%d is the number of tries.\n",count);
break;
} else {
printf("\n");
}
}
}
return 0;
}
This is always giving me the same output two times i.e "Very close Very close". This is either faulty code (syntax) or wrong logic, I think. Also I want to know a better algorithm/logic with the code to solve this question (possibly shorter). Lastly I am new to programming with C as my first language.
The condition -5 < b< 5 is equal to (-5 < b) < 5, which means you compare the boolean (0 or 1) result of -5 < b with 5.
If you need to compare b to a range you need to do -5 < b && b < 5. I.e. compare b explicitly against both ends of the range.
Also, b = 0 is assignment not comparison, you need to use == for comparison.

Factorization in C-Recursion

I've been asked to write a void function in c(no loops), that gets an even number(lets say 80), and prints it like this
2*2*5*2*2
As you can see the result is 80 lol.
Between 2 numbers you need to print "*", and the odd number(for my example,5) you need to print it in the middle, or if there is an odd numbers of "2" in the number, lets say 96 you need to print it like that:2*2*2*3*2*2
If the given number is odd, return the number.
I whould like to get not only te answer, but the way you "think" before starting to code.
Here is what i got so far
if(n%4==0)
{
printf("2*");
PrintTwos(n/4);
return;
}
if(n%2==0)
{
printf("*2");
PrintTwos(n/2);
return;
}
printf("%d",n);
here is some pseudo code:
func(nbr)
isOdd(nbr) // recursive stop condition
print nbr
return
evenNbr = findFirstEven(nbr) //return the shortest even number from nbr
print evenNbr
func(nbr / evenNbr)
I didn't add logic for the * printing because i'm sure u can figure that about by yourself. And one case will break that pseudo code, but that's a good start to help you thinking about what your recursive function should do.
EDIT following comments: (NOT COMPLETE : odd number in the middle is missing in this)
int findFirstEven(nbr, i) {
if (nbr%i != 0)
return findFirstEven(nbr, i++);
return i;
}
int primefact(int n)
{
int i=2;
i = findFirstEven(n, i);
printf("%d*", i);
if(n==i)
printf("1");
return 0;
else
primefact(n/i);
}
(not tested)
You need to distribute 2's in halves, so you need to remove two twos from the number before the recursive step – otherwise the recursive step would have to know how deep it is to keep from printing too many twos on the left side.
Of course you must verify if there actualy are two twos!
So:
void PrintTwosInNumber(unsigned n)
{
if(n % 4 == 0)
{
printf("2*");
PrintTwosInNumber(n/4);
printf("*2");
}
else if(n % 2 == 0)
{
printf("2*");
PrintTwosInNumber(n/2);
}
else
printf("%u", n);
}
You can save the last recursive step with
void PrintTwosInNumber(unsigned n)
{
if(n % 4 == 0)
{
printf("2*");
PrintTwosInNumber(n/4);
printf("*2");
}
else if(n % 2 == 0)
printf("2*%u", n/2);
else
printf("%u", n);
}
Edit:
Please note the function will fall into an infinite recursion for n==0 – zero is infinitely divisible by 2. However, zero can not be represented as a product of any number of 2's and some odd numer, so it is out of scope of this problem.
Anyway if it was a real programming task, one should take that special case into account and add a protecting if(n==0) return; branch, just to be on the safe side if a caller passes a wrong parameter value.

C product of three consecutive numbers

I was trying to solve this tricky question, but for some reason my code is doing something wrong... I don't exactly know why, but I'll try to explain as much as I can.
Consecutive products:
Write a program that reads a positive integer
from standard input and verifies if it's equal to the product of three
natural and consecutive numbers. For example, the number 120 is equal
to 4x5x6, as for number 90 there aren't any three consecutive natural
numbers whose product is 90. Your program should generate as output
'S' if there are 3 consecutive natural numbers whose product is the
value read, or 'N' if none.
Input
120
Expected Output
"S"
Input
60
Expected Output
"S"
Input
80
Expected Output
"N"
Input
120
Expected Output
"S"
And this is my code:
#include <stdio.h>
int main(){
int int1,i,count=10,j,k,w=0;
scanf("%i",&int1);
for (i = 1; i <= count; ++i)
{
for (j = 1; j <= count+1; ++j)
{
for ( k = 1; k <= count+2; ++k)
{
if ((i==j+1 && i==k+2) && (i*j*k==int1)){
w=1;
}
}
}
}
if (w==0)
{
printf("N");
}
else{
printf("S");
}
}
So basically what this does is I have 3 loops that will generate random numbers in a k*i*j form... and it checks if we are getting what we want(the product of three natural and consecutive numbers) . This is for an assignment.
I modified your code. Please let me know if the problem still exists. The change made is exactly as WDS said.
#include <stdio.h>
int main(){
int int1,i,count=10,j,k,w=0,comp;
scanf("%i",&int1);
for (i = 1; i <= count; ++i)
{
comp = i*(i+1)*(i+2);
if(comp==int1)
{
w = 1;
}
}
if (w==0)
{
printf("N");
}
else
{
printf("S");
}
return 0;
}
You don't need 3 loops. One trival approach would be:
int test(int num)
{
for (int i = 1; i < num; i++)
{
int product = i * (i + 1) * (i + 2);
if ( product == num )
return true;
else if (product > num)
break;
}
return false;
}
You might want to add the algorithm tag on this question. That said, my approach would be to consider what the product of 3 consecutive numbers is. You could write it as x * (x+1) * (x+2). But there is a better way.
Write it as (x-1) * x * (x+1). Then multiply and simplify. The result is x^3-x.
Now for any given number, start a single loop on x from x = 2 (because if x=1 then x-1=0 and this will never be a solution) and incrementing by 1 each loop. Check on each loop for a match with the input number. If it is a match, return true. If it is not a match and exceeds the input number return false. If it is not a match and is less than the input number, loop again.

How can I reduce the runtime?

Here is a link to the problem I'm trying to solve: http://acm.timus.ru/problem.aspx?space=1&num=1086
Here is my approach:
#include <stdio.h>
#include <math.h>
int main()
{
int n, i, m, p;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &m);
p = find_prime(m);
printf("%d\n", p);
}
return 0;
}
int find_prime(int a)
{
int i, p = 1, t, prime[15000], j;
prime[0] = 2;
for(i = 0; i < a; )
{
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
t = 0;
for(j = 0; prime[j] <= sqrt(p); j++)
{
if(p%prime[j] == 0 && p != 2)
{
t = 1;
break;
}
}
if(t != 1)
{
i++;
prime[i] = p;
}
}
return p;
}
I know the algorithm is fine and it produces the correct answer. But I always get "Time Limit Exceeded". I can't get the runtime download to 2 seconds. It's always equal to 2.031 seconds. I have tried few other approaches, for example, I iterated through all the numbers until I found the mth prime number, I tried skipping the even integers greater than 2 but I still get 2.031 seconds.
What should I do?
Your buffer for prime numbers doesn't need to be a local variable that's recalculated every time.
You can try to memoize by storing the buffer in the global scope and using a global counter to keep track of how many primes you have already calculated until now and which number was the maximum number requested.
If the next number that's requested from you is smaller than the previous maximum, you should fall back to the corresponding pre-calculated number. If the next number is larger than the previous maximum, make it the new maximum - and also try to start calculating from where you last left off.
Remove
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
and replace it with
p++
as I understand it,
the problem is to find the next prime greater that the sum of all the prior input numbers.
That means there are certain expectations.
1) the sum of the prior input numbers is available in find_prime().
2) for simplification, the last found prime number is available in find_prime().
Neither of these expectations are implemented.
Then there is that 60 thousand byte array on the stack in find_prime().
Suggest moving that to a file global position and including a 'static' modifier.
move the prior sum of inputs to a file global location, so it is always available.
for overall speed,
calculate all the primes in the array as a first thing, thereby filling the array with prime values. then
1) add new input to sum,
2) index into array using sum.
3) return value found in array.

How do I fill up the array with the first 10 prime numbers?

This is probably a really simple problem to solve but for for some reason I just can't think of the correct solution!
We have a function int isPrime(int n) which returns a 2 if n is prime, a -1 if n is not positive and a 0 if n isn't prime. (We don't have to write any code for this function, we just assume that the code is already written so all we have to do is call this function). Using this function, we have to write a code fragment that fills up an integer array of size 10 with the first ten prime numbers. NOTE: Treat 1 as a non-prime number.
I've attempted a solution below but I don't think it's right:
NOTE: We just have to write a code fragment!
int a[10];
int n, i, result;
result = isPrime(n);
for (i = 0; i < 10; i++) {
if (result == 1) {
a[i] = n;
}
}
I have a feeling that I will have to use two for loops, one to cycle through the numbers being checked with isPrime and another one to loop through the positions in the array as I have above. But I'm not sure how it would look if I had two for loops. Any help is appreciated! Thanks ahead of time.
Try something like this. It will repeatedly find the next prime until you have found 10 of them.
Note: Since you did not provide an implementation of isPrime, this code is not tested. It is only meant to give you an idea of what it should look like.
int a[10];
int n, i, result;
n = 2;
for (i = 0; i < 10; i++) {
// Keep bumping n until we find a prime.
while (!(isPrime(n) == 2)) {
n++;
}
// Record the prime we just found.
a[i] = n;
// Ensure that we do not just record the same prime n times.
n++;
}
Start by having zero primes. While you don't have 10 of them, see if the next number is prime; if it is, add it to the next spot in the array if it is (and now you have one more prime).
(This straightforwardly translates into code. You need one loop, but two different counters: number of found primes, and number you're testing next)
An implementation of Amaden's algorithm:
int a[10];
for (int n = 1, nprimes = 0;;)
if (isPrime(++n) == 2) {
a[nprimes++] = n;
if (nprimes == 10)
break;
}

Resources