Question asked in oracle interview.For example,if my input is 6, then
5+1=6 Ans:2
4+2=6 Ans:2
3+2+1=6 Ans:3
So, the final answer should be 3.(i.e 3,2,1 are needed to get sum 6)
Note:Repetition of number isn't allowed (i.e 1+1+1+1+1+1=6)
I solved it using recursion but interviewer wasn't satisfied. Is Dynamic Programming possible?
The minimum sum of x numbers is
So just find x that satisfies the inequality:
Here's the code:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int x = 1;
while ((x+1)*x/2 <= n) x++;
x--; // now (x+1)*x/2 > n , so x is too large
printf("%d\n", x);
return 0;
}
You can use binary search if n is very large.
I was about to post the answer but #Cruise Liu beat me to it. Ill try explaining it a bit .
Its a type of integer partitioning but you dont need to generate the elements since you're only interested in the 'number of elements'. i.e. the final answer 3 and not {1, 2, 3}
Given a number N, you have another restriction that numbers cannot repeat.
Hence the best case would be if N is actually a number say 1, 3, 6, 10, 15
i.e. f(x) = x * (x + 1) / 2.
For example, take 6. f(x) = 6 exists. specifically f(3) = 6 . Thus you get the answer 3.
What this means is that if there is an integer X that exists for f(x) = N, then there is a set of numbers 1, 2, 3 ... x that when added up give N. And this is the maximum number possible (without repitition).
However, there are cases in f(x) = N where x is not an integer.
f(x) = x * (x + 1 ) / 2 = N
i.e. x**2 + x = 2*N
x**2 + x - 2*N = 0
Solving this quadratic we get
Since the number x is not negative we can't have
So we're left with
For N = 6
A perfect Integer. But for N = 12
which is 8.845 / 2 which is a fraction. The floor value is 4, which is the answer.
In short: Implement a function
f(N) = (int) ((-1.0 + sqrt(1 + 8*N))/2.0 )
i.e.
int max_partition_length(int n){
return (int)((-1.0 + sqrt(1 + n*8))/2);
}
Related
I'm doing some exam prep for my discrete mathematics course, and I have to implement the function
f(x) = ((9^x)-2)%5
Since the values of our x in the assignment is 100000 < x <= 1000000, I'm having some trouble handling the overflow
In our assignment there's a hint: "Find a way to apply the modulus throughout the calculations. Otherwise you will get much too big numbers very quickly when calculating 9^x"
I cannot figure out the logic to make this work tho, any help would be appreciated
/* This function should return 1 if 9^x-2 mod 5 = 2 and 0 otherwise */
int is2mod5(int x){
int a;
double b = pow(9, x);
a = b;
int c = (a-2)%5;
if (c == 2)
{
return 1;
}
else
{
return 0;
}
}
Since you are calculating modulo 5, multiplications can be done modulo 5 as well. 9 is congruent to -1 modulo 5. Thus 9^x is congruent to (-1)^x modulo 5, i.e. 1 if x is even and -1 if x is odd. Subtracting 2 gives -1 and -3 which are congruent to 4 and 2 respectively.
Thus, f(x) is 4 if x is even and 2 if x is odd.
Problem Statement:
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
Using the following knowledge about squares (given below) we can implement the following solution.
A natural number is...
... a square if and only if each prime factor occurs to an even power in the number's prime factorization.
... a sum of two squares if and only if each prime factor that's 3 modulo 4 occurs to an even power in the number's prime factorization.
... a sum of three squares if and only if it's not of the form 4a(8b+7) with integers a and b.
... a sum of four squares. Period. No condition. You never need more than four.
int numSquares(int n) {
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
return 3;
}
Question:
Can someone help me understand what exactly are we trying to achieve in following for loop?
I'm a little lost here.
for (int a=0; a*a<=n; ++a) {
int b = sqrt(n - a*a);
if (a*a + b*b == n)
return 1 + !!a;
}
The loop is trying to find two squares that sum to n.
Rather than trying every combination of numbers to see if we can square them and they add up to n, we just loop through the possibilities for one of the numbers -- this is a. We square that with a*a, and subtract that from n. We then get the integer part of the square root of this difference, and this is b. If a2+b2 adds up to n, this is the pair of squares that we're looking for.
We need to calculate the sum of the squares in case n - a*a wasn't a perfect square. In that case its square root will have a fraction in it, which will be lost when we convert it to an integer. In other words, testing a*a+b*b == n allows us to determine whether the square root was an integer.
How to create a c code that receive int parameter n and return the value of this mathematical equation
f(n) = 3 * f(n - 1) + 4, where f(0) = 1
each time the program receive n , the program should start from the 0 to n which means in code (for loop) .
the problem here that i can't translate this into code , I'm stuck at the f(n-1) part , how can i make this work in c ?
Note. this code should be build only in basic C (no more the loops , no functions , in the void main etc) .
It's called recursion, and you have a base case where f(0) == 1, so just check if (n == 0) and return 1 or recurse
int f(int n)
{
if (n == 0)
return 1;
return 3 * f(n - 1) + 4;
}
An iterative solution is quite simple too, for example if f(5)
#include <stdio.h>
int
main(void)
{
int f;
int n;
f = 1;
for (n = 1 ; n <= 5 ; ++n)
f = 3 * f + 4;
printf("%d\n", f);
return 0;
}
A LRE (linear recurrence equation) can be converted into a matrix multiply. In this case:
F(0) = | 1 | (the current LRE value)
| 1 | (this is just copied, used for the + 4)
M = | 3 4 | (calculates LRE to new 1st number)
| 0 1 | (copies previous 2nd number to new 2nd number (the 1))
F(n) = M F(n-1) = matrixpower(M, n) F(0)
You can raise a matrix to the power n by using repeated squaring, sometimes called binary exponentiation. Example code for integer:
r = 1; /* result */
s = m; /* s = squares of integer m */
while(n){ /* while exponent != 0 */
if(n&1) /* if bit of exponent set */
r *= s; /* multiply by s */
s *= s; /* s = s squared */
n >>= 1; /* test next exponent bit */
}
For an unsigned 64 bit integer, the max value for n is 40, so the maximum number of loops would be 6, since 2^6 > 40.
If this expression was calculating f(n) = 3 f(n-1) + 4 modulo some prime number (like 1,000,000,007) for very large n, then the matrix method would be useful, but in this case, with a max value of n = 40, recursion or iteration is good enough and simpler.
Best will be to use recursion . Learn it online .
Its is very powerful method for solving problems. Classical one is to calculate factorials. Its is used widely in many algorithms like tree/graph traversal etc.
Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem.
Here you break you problem of size n into 3 instance of sub problem of size n-1 + a problem of constant size at each such step.
Recursion will stop at base case i.e. the trivial case here for n=0 the function or the smallest sub problem has value 1.
Forgive me if I am being a bit silly, but I have only very recently started programming, and am maybe a little out of my depth doing Problem 160 on Project Euler. I have made some attempts at solving it but it seems that going through 1tn numbers will take too long on any personal computer, so I guess I should be looking into the mathematics to find some short-cuts.
Project Euler Problem 160:
For any N, let f(N) be the last five digits before the trailing zeroes
in N!. For example,
9! = 362880 so f(9)=36288 10! = 3628800 so f(10)=36288 20! =
2432902008176640000 so f(20)=17664
Find f(1,000,000,000,000)
New attempt:
#include <stdio.h>
main()
{
//I have used long long ints everywhere to avoid possible multiplication errors
long long f; //f is f(1,000,000,000,000)
f = 1;
for (long long i = 1; i <= 1000000000000; i = ++i){
long long p;
for (p = i; (p % 10) == 0; p = p / 10) //p is i without proceeding zeros
;
p = (p % 1000000); //p is last six nontrivial digits of i
for (f = f * p; (f % 10) == 0; f = f / 10)
;
f = (f % 1000000);
}
f = (f % 100000);
printf("f(1,000,000,000,000) = %d\n", f);
}
Old attempt:
#include <stdio.h>
main()
{
//This part of the programme removes the zeros in factorials by dividing by 10 for each factor of 5, and finds f(1,000,000,000,000) inductively
long long int f, m; //f is f(n), m is 10^k for each multiple of 5
short k; //Stores multiplicity of 5 for each multiple of 5
f = 1;
for (long long i = 1; i <= 100000000000; ++i){
if ((i % 5) == 0){
k = 1;
for ((m = i / 5); (m % 5) == 0; m = m / 5) //Computes multiplicity of 5 in factorisation of i
++k;
m = 1;
for (short j = 1; j <= k; ++j) //Computes 10^k
m = 10 * m;
f = (((f * i) / m) % 100000);
}
else f = ((f * i) % 100000);
}
printf("f(1,000,000,000,000) = %d\n", f);
}
The problem is:
For any N, let f(N) be the last five digits before the trailing zeroes in N!. Find f(1,000,000,000,000)
Let's rephrase the question:
For any N, let g(N) be the last five digits before the trailing zeroes in N. For any N, let f(N) be g(N!). Find f(1,000,000,000,000).
Now, before you write the code, prove this assertion mathematically:
For any N > 1, f(N) is equal to g(f(N-1) * g(N))
Note that I have not proved this myself; I might be making a mistake here. (UPDATE: It appears to be wrong! We'll have to give this more thought.) Prove it to your satisfaction. You might want to start by proving some intermediate results, like:
g(x * y) = g(g(x) * g(y))
And so on.
Once you have obtained a proof of this result, now you have a recurrence relation that you can use to find any f(N), and the numbers you have to deal with don't ever get much larger than N.
Prod(n->k)(k*a+c) mod a <=> c^k mod a
For example
prod[ 3, 1000003, 2000003,... , 999999000003 ] mod 1000000
equals
3^(1,000,000,000,000/1,000,000) mod 1000000
And number of trailing 0 in N! equals to number of 5 in factorisation of N!
I would compute the whole thing and then separate first nonzero digits from LSB ...
but for you I think is better this:
1.use bigger base
any number can be rewrite as sum of multiplies of powers of the same number (base)
like 1234560004587786542 can be rewrite to base b=1000 000 000 like this:
1*b^2 + 234560004*b^1 + 587786542*b^0
2.when you multiply then lower digit is dependent only on lowest digits of multiplied numbers
A*B = (a0*b^0+a1*b^1+...)*(b0*b^0+b1*b^1+...)
= (a0*b0*b^0)+ (...*b^1) + (...*b^2)+ ...
3.put it together
for (f=1,i=1;i<=N;i++)
{
j=i%base;
// here remove ending zeroes from j
f*=j;
// here remove ending zeroes from f
f%=base;
}
do not forget that variable f has to be big enough for base^2
and base has to be at least 2 digits bigger then 100000 to cover 5 digits and overflows to zero
base must be power of 10 to preserve decimal digits
[edit1] implementation
uint<2> f,i,j,n,base; // mine 64bit unsigned ints (i use 32bit compiler/app)
base="10000000000"; // base >= 100000^2 ... must be as string to avoid 32bit trunc
n="20"; // f(n) ... must be as string to avoid 32bit trunc
for (f=1,i=1;i<=n;i++)
{
j=i%base;
for (;(j)&&((j%10).iszero());j/=10);
f*=j;
for (;(f)&&((f%10).iszero());f/=10);
f%=base;
}
f%=100000;
int s=f.a[1]; // export low 32bit part of 64bit uint (s is the result)
It is too slow :(
f(1000000)=12544 [17769.414 ms]
f( 20)=17664 [ 0.122 ms]
f( 10)=36288 [ 0.045 ms]
for more speed or use any fast factorial implementation
[edit2] just few more 32bit n! factorials for testing
this statement is not valid :(
//You could attempt to exploit that
//f(n) = ( f(n%base) * (f(base)^floor(n/base)) )%base
//do not forget that this is true only if base fulfill the conditions above
luckily this one seems to be true :) but only if (a is much much bigger then b and a%base=0)
g((a+b)!)=g(g(a!)*g(b!))
// g mod base without last zeroes...
// this can speed up things a lot
f( 1)=00001
f( 10)=36288
f( 100)=16864
f( 1,000)=53472
f( 10,000)=79008
f( 100,000)=56096
f( 1,000,000)=12544
f( 10,000,000)=28125
f( 1,000,100)=42016
f( 1,000,100)=g(??????12544*??????16864)=g(??????42016)->42016
the more is a closer to b the less valid digits there are!!!
that is why f(1001000) will not work ...
I'm not an expert project Euler solver, but some general advice for all Euler problems.
1 - Start by solving the problem in the most obvious way first. This may lead to insights for later attempts
2 - Work the problem for a smaller range. Euler usually give an answer for the smaller range that you can use to check your algorithm
3 - Scale up the problem and work out how the problem will scale, time-wise, as the problem gets bigger
4 - If the solution is going to take longer than a few minutes, it's time to check the algorithm and come up with a better way
5 - Remember that Euler problems always have an answer and rely on a combination of clever programming and clever mathematics
6 - A problem that has been solved by many people cannot be wrong, it's you that's wrong!
I recently solved the phidigital number problem (Euler's site is down, can't look up the number, it's quite recent at time of posting) using exactly these steps. My initial brute-force algorithm was going to take 60 hours, I took a look at the patterns solving to 1,000,000 showed and got the insight to find a solution that took 1.25s.
It might be an idea to deal with numbers ending 2,4,5,6,8,0 separately. Numbers ending 1,3,7,9 can not contribute to a trailing zeros. Let
A(n) = 1 * 3 * 7 * 9 * 11 * 13 * 17 * 19 * ... * (n-1).
B(n) = 2 * 4 * 5 * 6 * 8 * 10 * 12 * 14 * 15 * 16 * 18 * 20 * ... * n.
The factorial of n is A(n)*B(n). We can find the last five digits of A(n) quite easily. First find A(100,000) MOD 100,000 we can make this easier by just doing multiplications mod 100,000. Note that A(200,000) MOD 100,000 is just A(100,000)*A(100,000) MOD 100,000 as 100,001 = 1 MOD 100,000 etc. So A(1,000,000,000,000) is just A(100,000)^10,000,000 MOD 100,000.
More care is needed with 2,4,5,6,8,0 you'll need to track when these add a trailing zero. Obviously whenever we multiply by numbers ending 2 or 5 we will end up with a zero. However there are cases when you can get two zeros 25*4 = 100.
Example:
When the division is applied as a whole, the result is,
The summation formula is given by,
The above can be easily calculated in O(1), using the rules of summation.
But when it is applied to each term individually(truncating after the decimal point in the quotient),
=0+1+1+2+3+3+4+5=19. [using normal int/int division in C]
The above method requires O(N) as rules of summation can NOT be applied.
I understand the above is due to loss of precision is more when the division is applied to each term rather than at the last. But this is exacly what I need.[In the above example, 19 is the required solution and not 21]
Is there a formula that would serve as a shortcut for applying division individually to each term, similar to summation?
So, you get:
0 + (1+1+2) + (3+3+4) + 5
Let's multiply this by 3:
0 + (3+3+6) + (9+9+12) + 15
And compare it with the numerator of (1+...+15)/3:
1 + (3+5+7) + (9+11+13) + 15
You can clearly see that the sum you're seeking is losing 3 every 3 terms to the numerator or 1 in every term on average. And it doesn't matter how we group terms into triples:
(0+3+3) + (6+9+9) + 12+15
(1+3+5) + (7+9+11) + 13+15
or even
0+3 + (3+6+9) + (9+12+15)
1+3 + (5+7+9) + (11+13+15)
So your sum*3 is less than the numerator of (1+...+15)/3 by about the number of terms.
And the numerator can be calculated using the formula for the sum of the arithmetic progression: n2, where n is the number of terms in the sum:
1+3+5+7+9+11+13+15 = 28 = 64
Now you subtract 8 from 64, get 56 and divide it by 3, getting 18.6(6). The number isn't equal to 19 because n (the number of terms) wasn't a multiple of 3.
So, the final formula isn't exactly (n2-n)/3, but differs in value at most by 1 from the correct one.
In fact, it's:
(n*n-n+1)/3 rounded down or calculated using integer division.
Plugging the number(s) into it we get:
(8*8-8+1)/3 = 57/3 = 19
Short answer: Yes there is such a formula.
Long answer (as I guess you want the formula):
How to get it: You already realized that the difference between the summation formula and the sum of the int devision came from the rounding of the int division at each summand.
Make a table with the rows:
First row, the result of each summand, when you divide with full precision.
Second row, the reuslt of each summand, when you perform integer division.
And third row, the difference of both.
Now you should realize the pattern, its always 1/3, 0, 2/3.
That came from the division by 3, you could proof that formal if you want (e.g. induction).
So in the end your formula is: (n^2)/3 - (n/3)
the n*n/3 is the regular summation formula, and as for all full 3 summands 1 is lost we subtract n/3.
The result is going to be
1+1 + 2 + 3+3 + 4 + 5+5 + 6 + 7+7 + 8 + 9+9 + 10 + ...
in other words all odd numbers appear twice and all even numbers once. The sum of first n natural numbers is n*(n+1)/2 so the sum of first n even natural numbers is twice that and the sum of first n odd numbers is instead n*n.
I think you now have all pieces to get the result you need...
The sums you need are, for increasing ns:
1, 2, 4, 7, 10, 14, 19, 24, 30, 36 ...
Plug these into the The On-Line Encyclopedia of Integer Sequences™ (OEIS™) and you get A007980 as the series that fits your requirements. It is calculated as a(n)=ceil((n+1)*(n+2)/3).
This makes a(0) = 1, a(1) = 2, a(6) = 19, meaning the index is offset by 2: sum(1,8) = a(8-2).
Σ((2i+1)/3) where i =0 to n-1 and Σ((2i+1)/3) = n*n/3
#include <stdio.h>
typedef struct fraction {
int n;//numerator
int d;//denominator
} Fraction;
int gcd(int x, int y){
x = (x < 0)? -x : x;
y = (y < 0)? -y : y;
while(y){
int wk;
wk = x % y;
x = y;
y = wk;
}
return x;
}
Fraction rcd(Fraction x){
int gcm;
gcm = gcd(x.n, x.d);
x.n /= gcm;
x.d /= gcm;
return x;
}
Fraction add(Fraction x, Fraction y){
x.n = y.d*x.n + x.d*y.n;
x.d = x.d*y.d;
return rcd(x);
}
int main(void){
Fraction sum = {0,1};
int n;
for(n=1;n<=8;++n){
Fraction x = { 2*n-1, 3 };
sum = add(sum, x);
}
printf("%d/%d=",sum.n,sum.d);
printf("%d",sum.n/sum.d);
return 0;
}