Find the largest prime divisor of any predetermined number without using / (division) and % (remainder) in C [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
Improve this question
I have some task:
You can use basic control structures–sequence, branch, loop, as well as addition, subtraction, and multiplication. You cannot use division: this module is designed to run on microcontrollers. Create an src/1948.c file which takes a number into stdin after compilation and launch, and calculates its largest prime divisor.
I can't figure out how this can be done without using devisor and reminder. Please help me to understand the issue.

By the Sieve of Eratosthenes
Suppose the predetermined integer is N.
Negate N if negative.
Store N as the 'highest prime divisor'.
Allocate an array with (N >> 1) + 1 elements and fill with 0.
Start with the first prime 2.
Check off every multiple of the prime in the array (with an addition loop).
Continue finding multiples right up to N.
If it hits N exactly, store this prime as the 'highest prime divisor'.
Find the next prime.
This will be the next unchecked element in the sieve - the array.
But if you've passed the end of the array then you are done.
Otherwise repeat as you did for the previous prime.

Of course you could just write a division function and then call that to do division.
Alternatively, you can write a square root function and use (a+b)(a-b) = a2 - b2. After removing the factors of 2, start with the smallest a >= sqrt(N), and then check every a2 - N to see if it's square.
A division function can be as easy as this:
// only works for num >= 0 and den>0
divide(num, den):
if (num < den):
return 0
q = divide(num, den*2) * 2
r = num - q*den
return r >= den ? q + 1 : q
Square root is just a little more complicated:
// only works for n >= 0
sqrt(n):
return sqrtScaled(n,1)
// return floor(sqrt(n)/scale). Must have n >= 0, scale > 0
sqrtScaled(n, scale):
if (n < scale*scale):
return 0
q = sqrtScaled(n, scale*2) * 2
test = (q+1)*scale
return test*test <= n ? q+1 : q

Related

What is going on in this solution to the Fizzbuzz question?

for (let number = 0; number <= 100; number++ ) {
let output = ""
if (number % 3 == 0) output += "Fizz"
if (number % 5 == 0) output += "buzz"
console.log(output || number)
}
I understand why it finds the modulo for 3 and 5. But why does this also find the modulo for 15? (The question asks to also find the numbers that are divisible by 3 and 5 and print "Fizzbuzz").
I was able to solve the question in a different manner and was offered this as one of the ideal solutions.
Is the += after the output somehow multiplying the other two remainders?
If your question is about the use of +=, then it is a short form of writing output=output+"Fizz". Hence instead of writing the above one we can simply write output+="Fizz"
The answer to my question is that the program runs both checks independently. When it reaches 15 (or any other number divisible by both 3 and 5), it will simply add "Fizz" and "buzz" together to create "Fizzbuzz".

Find all pairs such that x^2 + y^2 =< n^2 [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am trying to write an algorithm in C which for a given natural number n would find the number of pairs (x,y) where x,y are integers such that
x2 + y2 <= n2
I am able to do this with two for loops, however, this seems to be suboptimal. What would be the most effective approach to this problem?
One only needs to find the points at the border, i.e. for each given x the maximal y_max s.t. x^2+y_max^2 <= n. Then the number of interesting pairs for that given x is 2*y_max+1. For x=0 we have y_max=n. For x>0 we also have to consider the pairs with -x. This results in the following code:
int pairCnt = 2*n+1; /* pairs (0,-n), (0,-n+1), ..., (0,n) */
int n2 = n*n;
for (int x=1; x<=n; ++x)
{
int y_max = (int)sqrt(n2-x*x);
pairCnt += 2*(2*y_max+1); /* (+/-x,-y_max), ..., (+/-x,y_max) */
}
The use of sqrt can be avoided with the following algorithm:
int pairCnt = 2*n+1; /* pairs (0,-n), (0,-n+1), ..., (0,n) */
int n2 = n*n;
for (int x=1, y_max=n; 1; ++x)
{
if (y_max*y_max > n2-x*x)
--y_max;
if (x > y_max) break;
pairCnt += 2*(2*y_max+1); /* (+/-x,-y_max), ..., (+/-x,y_max) */
}
int s = 2*x-1; /* side length of maximal inscribed square */
pairCnt = 2*pairCnt - s*s;
The first idea for the second algorithm is that when x increases y_max will decrease maximally by 1 as long as y_max>x (i.e. we go along the inner of the circle with radius n from (0,n) until we cross the first median y=x). When we add a copy of the counted points turned by 90° (i.e. double the points found so far), we will have counted the points inside the maximal inscribed square twice.
Here is a kind of visualization for n=3. * marks pairs outside the interesting set (x*x+y*y > n*n=9). Numbers mark how often pairs inside the interesting set (x*x+y*y <= n*n=9) have been counted so far.
before loop after loop after doubling result
---- ---- ---- ----
432101234 432101234 432101234 432101234
4 ********* ********* ********* *********
3 ****1**** ****1**** ****1**** ****1****
2 **00100** **11111** **22222** **11111**
1 **00100** **11111** **22222** **11111**
0 *0001000* *0111110* *1222221* *1111111*
-1 **00100** **11111** **22222** **11111**
-2 **00100** **11111** **22222** **11111**
-3 ****1**** ****1**** ****1**** ****1****
-4 ********* ********* ********* *********
You don't need two loops. Just loop over x, and then you can calculate y because both x and n are known.
If you implement a function int int_sqrt (int n), which returns the integer part of sqrt(double n) ,then you could handle it with only one loop by using this function. But the integer square root exists only in C++, so you'd have to implement one in C by casting results to int
Edit :
Here's the idea :
int x=0,result=0;
while ( (n-(x*x)) >=0){
result += int_sqrt ( n-(x*x) ) +1;
x++;
}
that's in the case you accept all integers, including 0 to make your couples.

Interesting Powers Of 2 - algorithm/ Math (from Hackerrank ACM APC)

I came across a problem from a recent competition.
I was unable to figure out a solution, and no editorial for the question is yet available.
Question Link
I am quoting the problem statement here also in case the link doesn't work.
Find the number of integers n which are greater than or equal to A and less than or equal to B (A<= n <=B) and the decimal representation of 2^n ends in n.
Ex: 2^36 = 68719476736 which ends in “36”.
INPUT
The first line contains an integer T i.e. number of test cases. T lines follow, each containing two integers A and B.
Constraints
1 <= T <= 10^5
A<=B
A,B <= 10^150
OUTPUT
Print T lines each containing the answer to the corresponding testcase.
Sample Input
2
36 36
100 500
Sample Output
1
0
As often happens on programming competitions I have come up with an heuristics I have not proven, but seems plausible. I have written a short program to find the numbers up to 1000000 and they are:
36
736
8736
48736
948736
Thus my theory is the following - each consecutive number is suffixed with the previous one and only adds one digit. Hope this will set you on the right track for the problem. Note that if my assumption is right than you only need to find 150 numbers and finding each consecutive number requires checking 9 digits that may be added.
A general advice for similar problems - always try to find the first few numbers and think of some relation.
Also often it happens on a competition that you come up with a theory like the one I propose above, but have no time to prove it. You can't afford the time to prove it. Simply hope you are right and code.
EDIT: I believe I was able to prove my conjecture above(in fact I have missed some numbers -see end of the post). First let me point out that as v3ga states in a comment the algorithm above works up until 75353432948736 as no digit can be prepended to make the new number "interesting" as per the definition you give. However I completely missed another option - you may prepend some number of 0 and then add a non-zero digit.
I will now proof a lemma:
Lemma: if a1a2...an is an interesting number and n is more than 3, then a2...an also is interesting.
Proof:
2a1a2...an = 2a1*10n - 1*2a2a2...an
Now I will prove that 2a1*10n - 1*2a2a2...an is comparable to 2a2a2...an modulo 10n-1.
To do that lets prove that 2a1*10n - 1*2a2a2...an - 2a2a2...an is divisible by 10n-1.
2a1*10n - 1*2a2a2...an - 2a2a2...an =
2a2a2...an * (2a1*10n - 1 - 1)
a2a2...an is more than n-1 for the values we consider.
Thus all that's left to prove to have 10n-1 dividing the difference is that 5n-1 divides 2a1*10n - 1 - 1.
For this I will use Euler's theorem:
2phi(5n-1) = 1 (modulo 5n-1).
Now phi(5n-1) = 4*(5n-2) and for n >= 3 4*(5n-2) will divide a1*10n - 1(actually even solely 10n - 1).
Thus 2a1*10n - 1 gives remainder 1 modulo 5n-1 and so 5n-1 divides 2a1*10n - 1 - 1.
Consequently 10n-1 divides 2a2a2...an * (2a1*10n - 1 - 1) and so the last n - 1 digits of 2a1a2a2...an and 2a2a3a4...an are the same.
Now as a1a2a2...an is interesting the last n digits of 2a1a2a2...an are a1a2a2...an and so the last n-1 digits of 2a2a3a4...an are a2a3a4...an and consequently a2a3a4...an is also interesting. QED.
Use this lemma and you will be able to solve the problem. Please note that you may also prepend some zeros and then add a non-zero number.
In general, you can try solving these problems by finding some pattern in the output. Our team got this problem accepted at the contest. Our approach was to find a general pattern in the values that satisfy the criteria. If you print the first few such digits, then you will find the following pattern
36
736
8736
48736
948736
Thus the next number after 948736 should be of 7 digits and can be any one of 1948736, 2948736, 3948736, 4948736, 5948736, 6948736, 7948736, 8948736, 9948736. Thus check which value is valid and you have the next number. Continuing in this fashion you can back yourself to get all the 150 numbers.
But there is a problem here. There will be some numbers that do not immediately follow from the previous number by appending '1' to '9'. To counter this you can now start appending values from 10 to 99 and now check if there is a valid number or not. If there is still no valid number, then again try appending numbers from 100 to 999.
Now employing this hack, you will get all the 137 values that satisfy the criterion given in the question and easily answer all the queries. For example, working java code that implements this is shown here. It prints all the 137 values.
import java.io.*;
import java.math.*;
import java.util.*;
class Solution
{
public static void main(String[] args)throws java.lang.Exception{
new Solution().run();
}
void run()throws java.lang.Exception{
BigInteger[] powers = new BigInteger[152];
powers[0] = one;
for(int i=1; i<=150; i++){
powers[i] = powers[i-1].multiply(ten);
}
BigInteger[] answers = new BigInteger[152];
answers[2] = BigInteger.valueOf(36);
answers[3] = BigInteger.valueOf(736);
int last = 3;
for(int i=4; i<=150; i++){
int dif = i-last;
BigInteger start = ten.pow(dif-1);
BigInteger end = start.multiply(ten);
while(start.compareTo(end) < 0){
BigInteger newVal = powers[last].multiply(start);
newVal = newVal.add(answers[last]);
BigInteger modPow = pow(two, newVal, powers[i]);
if(modPow.equals(newVal)){
answers[i] = newVal;
System.out.println(answers[i]);
last = i;
break;
}
start = start.add(one);
}
}
}
BigInteger pow(BigInteger b, BigInteger e, BigInteger mod){
if(e.equals(zero)){
return one;
}
if(e.mod(two).equals(zero)){
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
return x;
}else{
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
x = x.multiply(two).mod(mod);
return x;
}
}
BigInteger ten = BigInteger.valueOf(10);
BigInteger zero = BigInteger.ZERO;
BigInteger one = BigInteger.ONE;
BigInteger two = BigInteger.valueOf(2);
}
This is very interesting property. During the contest, I found that 36 was the only number under 500 checking with python...
The property is : 2^36 last two digits are 36, last three digits are 736, so next number is 736. 2^736 has last three digits as 736, and next number is 8376...
And the series is : 36 , 736 , 8736 , 48736 , 948736 ...
And then started with BigInt class in C++.
But alas there was no time, and 4th problem wasn't solved. But after the contest, we did it in python.
here's link : Ideone it!
def powm(i):
j = 10
a = 1
while i:
if i % 2:
a = a * j
i /= 2
j *= j
return a
def power(n, i):
m = powm(i)
y = 1
x = 2
while n:
if n % 2 == 1:
y = y * x % m
x = x * x % m
n /= 2
return y
mylist = []
mylist.append(power(36, 2))
n = mylist[0]
print(n)
for i in range(3, 170):
p = power(n, i)
print p
if p != n:
mylist.append(p)
n = p
t = input()
while t:
x = raw_input().split(" ")
a = int(x[0])
b = int(x[1])
i = 0
#while i <= 150:
#print mylist[i]
#i += 1
#print power(8719476736,14)
while mylist[i] < a:
i += 1
ans = 0
while mylist[i] <= b:
i += 1
ans += 1
print ans
t -= 1
The final digits start to repeat after 20 increments. So for any n with the final digit 1, the final digit of the answer will be 2. So most values of n can be eliminated immediately.
2^1 = 2
2^21 = 2097152
2^101 = 2535301200456458802993406410752
2^2 = 4
2^22 = 4194304
2^42 = 4398046511104
In fact only two possibilities share a final digit:
2^14 = 16384
2^16 = 65536
2^34 = 17179869184
2^36 = 68719476736
If n is 14+20x or 16+20x, then it might work, so you'll need to check it. Otherwise, it cannot work.
I am not very good with such problems. But modular exponentiation appears to be key in your case.
Repeat for all n in the range A to B:
1. Find k, the no of digits in n. This can be done in O(logn)
2. Find 2^n (mod 10^k) using modular exponentiation and check if it is equal to n. This'll take O(n) time. (actually, O(n) multiplications)
EDIT
Actually, don't repeat the whole process for each n. Given 2^n (mod 10^k), we can find 2^(n+1) (mod 10^k) in constant time. Use this fact to speed it up further
EDIT - 2
This doesn't work for such large range.

Calculating and Printing a tree [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to build a tree that looks like this:
So I take in 2 numbers from the user, a and b. a defines the number of rows, and b defines the starting root node value. So if i had a=5 and b=3, then we get:
I basically just print that out to the console. I am just really lost how on how to start. Could anyone give me a little push in the right direction?
This is Pascal's triangle, and the value at row n, column k is b * (n choose k) where n and k are both zero-indexed, and (n choose k) = n! / (k! * (n-k)!)
Once you've figured this out, then the solution to your problem amounts to writing a function int choose(int n, int k) and to laying out the square on the console.
The layout is the hardest part, but here's an approach:
First, you need to pick a width that you're going to print the number out in. Let's say it's W. Probably W = 3 will be good.
Second, you need to figure out how many spaces to print at the start of each line. Each row adds W + 1 width to the printed part, so you need to have (W + 1) / 2 less space before on each subsequent row, ending at 0 space at row (a - 1). That means (a - n - 1) * (W + 1) / 2 spaces beforehand on row n.
Third, you need to write a function int choose(int n, int k)
Finally, you just need to iterate through the rows, first printing the number of spaces determined by step 2, then printing the numbers computed using the function in step 3, making sure that they're printed using something like printf("%-*d ", W, b * choose(n, k)); to keep them aligned.
One way might be to "grow" the tree downwards... Given the number of rows you can figure out how many elements are in the tree and allocate an array of the appropriate size.
Then starting at the top, assuming rows numbered from 1, down_left(x) = x + row(x) where x is the array index and row(x) is the row number x belongs to. down_right(x) = down_left(x) + 1.
Start at the top and go down_left and down_right. Then for each element in the next row you just created do the same, except add to the row below to get the cumulative effect of the "parent" numbers.
e.g. if user asks for 3 rows and root value of 3.
You know you will need 6 array elements. Allocate 6 elements and zero them.
Row 1: Put 3 at array[0].
Row n: Create by looking at each element in the previous row, call it i. Then do array[down_left(i)] += i and array[down_right(i)] += i. This creates row n. Repeat.
That's the rough idea anyway, have a play and see where it gets you... :)

Optimizing my algorithm for multiplication modulo [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I have a problem from the internet where i have an array of N integers and have to perform segment multiplication some T times given the left(L) and right segment(R) of the array and return the answer modulo some given modulus(M).
Constraints
N,T<=100000
1<=L<=R<=N
M<=10^9
and integers <=100
Ex-
input
5(N)
2 5 8 9 4
4(T)
1 2 3
2 3 4
1 1 1
1 5 100000
output
1
0
0
2880
So i have made a solution to this problem but it is a little slow i need tips to optimize my program.
#include "stdio.h"
int main(void)
{
int t;
scanf("%d",&t);
int Array[t+1];
for (int i = 1; i <=t; i++)
{
scanf("%d",&Array[i]);
}
int N;
scanf("%d",&N);
for (int i = 0; i <N ; i++)
{
long long a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
long long Product = 1;
if (c==1)
{
Product = 0;
}
else
{
for (int j = a; j <=b ; j++)
{
Product *= Array[j];
if (Product>=10000000000000000)
{
Product%=c;
}
}
}
Product%=c;
printf("%lld\n",Product );
}
return 0;
}
HINTS
You could compute an array A_p[i] for each prime p less than 100 that notes how many times p divides the i^th entry of your array.
Then you can compute a secondary array B_p[j] which is the cumulative sum of A_p[i] for i up to and including j. (This can be done in O(n) by the recursion B_p[i]=B_p[i-1]+A_p[i].)
This secondary array will allow you to compute the total power of each prime in any range. For example, if you wanted to know how many times the prime 5 appeared in array entries 10 to 100 you can compute B_5[100]-B_5[10-1].
So for each query you can then compute the final answer by raising each prime to the corresponding power and multiplying the results together modulo M. Note that there is a technique called exponentiation by squaring that makes this calculation efficient.
If 0 is a possible integer, then add 0 to your list of primes that are considered in the calculation.
FOR INTEREST
Note that this approach of using a cumulative sum is quite useful in many situations. For example, the Viola-Jones method for face recognition uses a version of this technique in 2 dimensions in order to be able to compute 2d filters efficiently.

Resources