Related
How can we develop a dynamic programming algorithm that calculates the minimum number of different primes that sum to x?
Assume the dynamic programming calculates the minimum number of different primes amongst which the largest is p for each couple of x and p. Can someone help?
If we assume the Goldbach conjecture is true, then every even integer > 2 is the sum of two primes.
So we know the answer if x is even (1 if x==2, or 2 otherwise).
If x is odd, then there are 3 cases:
x is prime (answer is 1)
x-2 is prime (answer is 2)
otherwise x-3 is an even number bigger than 2 (answer is 3)
First of all, you need a list of primes up to x. Let's call this array of integers primes.
Now we want to populate the array answer[x][p], where x is the sum of primes and p is maximum for each prime in the set (possibly including, but not necessarily including p).
There are 3 possibilities for answer[x][p] after all calculations:
1) if p=x and p is prime => answer[x][p] contains 1
2) if it's not possible to solve problem for given x, p => answer[x][p] contains -1
3) if it's possible to solve problem for given x, p => answer[x][p] contains number of primes
There is one more possible value for answer[x][p] during calculations:
4) we did not yet solve the problem for given x, p => answer[x][p] contains 0
It's quite obvious that 0 is not the answer for anything but x=0, so we are safe initializing array with 0 (and making special treatment for x=0).
To calculate answer[x][p] we can iterate (let q is prime value we are iterating on) through all primes up to (including) p and find minimum over 1+answer[x-q][q-1] (do not consider all answer[x-q][q-1]=-1 cases though). Here 1 comes for q and answer[x-q][q-1] should be calculated in recursive call or before this calculation.
Now there's small optimization: iterate primes from higher to lower and if x/q is bigger than current answer, we can stop, because to make sum x we will need at least x/q primes anyway. For example, we will not even consider q=2 for x=10, as we'd already have answer=3 (actually, it includes 2 as one of 3 primes - 2+3+5, but we've already got it through recursive call answer(10-5, 4)), since 10/2=5, that is we'd get 5 as answer at best (in fact it does not exist for q=2).
package ru.tieto.test;
import java.util.ArrayList;
public class Primers {
static final int MAX_P = 10;
static final int MAX_X = 10;
public ArrayList<Integer> primes= new ArrayList<>();
public int answer[][] = new int[MAX_X+1][MAX_P+1];
public int answer(int x, int p) {
if (x < 0)
return -1;
if (x == 0)
return 0;
if (answer[x][p] != 0)
return answer[x][p];
int max_prime_idx = -1;
for (int i = 0;
i < primes.size() && primes.get(i) <= p && primes.get(i) <= x;
i++)
max_prime_idx = i;
if (max_prime_idx < 0) {
answer[x][p] = -1;
return -1;
}
int cur_answer = x+1;
for (int i = max_prime_idx; i >= 0; i--) {
int q = primes.get(i);
if (x / q >= cur_answer)
break;
if (x == q) {
cur_answer = 1;
break;
}
int candidate = answer(x-q, q-1);
if (candidate == -1)
continue;
if (candidate+1 < cur_answer)
cur_answer = candidate+1;
}
if (cur_answer > x)
answer[x][p] = -1;
else
answer[x][p] = cur_answer;
return answer[x][p];
}
private void make_primes() {
primes.add(2);
for (int p = 3; p <= MAX_P; p=p+2) {
boolean isPrime = true;
for (Integer q : primes) {
if (q*q > p)
break;
if (p % q == 0) {
isPrime = false;
break;
}
}
if (isPrime)
primes.add(p);
}
// for (Integer q : primes)
// System.out.print(q+",");
// System.out.println("<<");
}
private void init() {
make_primes();
for (int p = 0; p <= MAX_P; p++) {
answer[0][p] = 0;
answer[1][p] = -1;
}
for (int x = 2; x <= MAX_X; x++) {
for (int p = 0; p <= MAX_P; p++)
answer[x][p] = 0;
}
for (Integer p: primes)
answer[p][p] = 1;
}
void run() {
init();
for (int x = 0; x <= MAX_X; x++)
for (int p = 0; p <= MAX_P; p++)
answer(x, p);
}
public static void main(String[] args) {
Primers me = new Primers();
me.run();
// for (int x = 0; x <= MAX_X; x++) {
// System.out.print("x="+x+": {");
// for (int p = 0; p <= MAX_P; p++) {
// System.out.print(String.format("%2d=%-3d,",p, me.answer[x][p]));
// }
// System.out.println("}");
// }
}
}
Start with a list of all primes lower than x.
Take the largest. Now we need to solve the problem for (x - pmax). At this stage, that will be easy, x - pmax will be low. Mark all the primes as "used" and store solution 1. Now take the largest prime still in the list and repeat until all the primes are either used or rejected. If (x - pmax) is high, the problem gets more complex.
That's your first pass, brute force algorithm. Get that working first before considering how to speed things up.
Assuming you're not using goldbach conjecture, otherwise see Peter de Rivaz excellent answer, :
dynamic programming generally takes advantage of overlapping subproblems. Usually you go top down, but in this case bottom up may be simpler
I suggest you sum various combinations of primes.
lookup = {}
for r in range(1, 3):
for primes in combinations_with_replacement(all_primes, r):
s = sum(primes)
lookup[s] = lookup.get(s, r) //r is increasing, so only set it if it's not already there
this will start getting slow very quickly if you have a large number of primes, in that case, change max r to something like 1 or 2, whatever the max that is fast enough for you, and then you will be left with some numbers that aren't found, to solve for a number that doesnt have a solution in lookup, try break that number into sums of numbers that are found in lookup (you may need to store the prime combos in lookup and dedupe those combinations).
what i want to store is a particular row of pascal table elements mod 10^9+7 in an array i tried to code it but it is failing somewhere when value is huge of like 10^5
here is the code. i have tried to apply modular inverse here and modular arithmetic here mod is 10^9+7
void pascal_row(ll n){
memset(soo,0,MAX);
soo[0] = 1; //First element is always 1
for(ll i=1; i<n/2+1; i++){ //Progress up, until reaching the middle value
soo[i] = ( ( soo[i-1] %mod ) * ((( (n-i+1)%mod * calcInverse(i,mod)%mod) % mod ))%mod)%mod;
}
for(ll i=n/2+1; i<=n; i++){ //Copy the inverse of the first part
soo[i] = soo[n-i]%mod;
}
}
here is what my modular inverse function look
long long calcInverse(long long a, long long n)
{
long long t = 0, newt = 1;
long long r = n, newr = a;
while (newr != 0) {
auto quotient = r /newr;
tie(t, newt) = make_tuple(newt, t- quotient * newt);
tie(r, newr) = make_tuple(newr, r - quotient * newr);
}
if (r > 1)
throw runtime_error("a is not invertible");
if (t < 0)
t += n;
return t;
}
Please tell what is the correct way of doing this Thanks
There's a relationship between the elements of Pascal's triangle and the choose function (where n choose r = n!/(r!*(n-r)!).) Specifically, starting from zero, the n'th row and r'th column of Pascal's triangle is n choose r. To find a particular row, you know what n you want, and then you should iterate over the possible values of r, find n choose r, and then take your modulus.
I'd recommend Java's BigInteger class for this, because it will handle any overflow errors you might be getting.
This is an interview question: "Given 2 integers x and y, check if x is an integer power of y" (e.g. for x = 8 and y = 2 the answer is "true", and for x = 10 and y = 2 "false").
The obvious solution is:int n = y; while(n < x) n *= y; return n == x
Now I am thinking about how to improve it.
Of course, I can check some special cases: e.g. both x and y should be either odd or even numbers, i.e. we can check the least significant bit of x and y. However I wonder if I can improve the core algorithm itself.
You'd do better to repeatedly divide y into x. The first time you get a non-zero remainder you know x is not an integer power of y.
while (x%y == 0) x = x / y
return x == 1
This deals with your odd/even point on the first iteration.
It means logy(x) should be an integer. Don't need any loop. in O(1) time
public class PowerTest {
public static boolean isPower(int x, int y) {
double d = Math.log(Math.abs(x)) / Math.log(Math.abs(y));
if ((x > 0 && y > 0) || (x < 0 && y < 0)) {
if (d == (int) d) {
return true;
} else {
return false;
}
} else if (x > 0 && y < 0) {
if ((int) d % 2 == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(isPower(-32, -2));
System.out.println(isPower(2, 8));
System.out.println(isPower(8, 12));
System.out.println(isPower(9, 9));
System.out.println(isPower(-16, 2));
System.out.println(isPower(-8, -2));
System.out.println(isPower(16, -2));
System.out.println(isPower(8, -2));
}
}
This looks for the exponent in O(log N) steps:
#define MAX_POWERS 100
int is_power(unsigned long x, unsigned long y) {
int i;
unsigned long powers[MAX_POWERS];
unsigned long last;
last = powers[0] = y;
for (i = 1; last < x; i++) {
last *= last; // note that last * last can overflow here!
powers[i] = last;
}
while (x >= y) {
unsigned long top = powers[--i];
if (x >= top) {
unsigned long x1 = x / top;
if (x1 * top != x) return 0;
x = x1;
}
}
return (x == 1);
}
Negative numbers are not handled by this code, but it can be done easyly with some conditional code when i = 1
This looks to be pretty fast for positive numbers as it finds the lower and upper limits for desired power and then applies binary search.
#include <iostream>
#include <cmath>
using namespace std;
//x is the dividend, y the divisor.
bool isIntegerPower(int x, int y)
{
int low = 0, high;
int exp = 1;
int val = y;
//Loop by changing exponent in the powers of 2 and
//Find out low and high exponents between which the required exponent lies.
while(1)
{
val = pow((double)y, exp);
if(val == x)
return true;
else if(val > x)
break;
low = exp;
exp = exp * 2;
high = exp;
}
//Use binary search to find out the actual integer exponent if exists
//Otherwise, return false as no integer power.
int mid = (low + high)/2;
while(low < high)
{
val = pow((double)y, mid);
if(val > x)
{
high = mid-1;
}
else if(val == x)
{
return true;
}
else if(val < x)
{
low = mid+1;
}
mid = (low + high)/2;
}
return false;
}
int main()
{
cout<<isIntegerPower(1024,2);
}
double a=8;
double b=64;
double n = Math.log(b)/Math.log(a);
double e = Math.ceil(n);
if((n/e) == 1){
System.out.println("true");
} else{
System.out.println("false");
}
I would implement the function like so:
bool IsWholeNumberPower(int x, int y)
{
double power = log(x)/log(y);
return floor(power) == power;
}
This shouldn't need check within a delta as is common with floating point comparisons, since we're checking whole numbers.
On second thoughts, don't do this. It does not work for negative x and/or y. Note that all other log-based answers presented right now are also broken in exactly the same manner.
The following is a fast general solution (in Java):
static boolean isPow(int x, int y) {
int logyx = (int)(Math.log(x) / Math.log(y));
return pow(y, logyx) == x || pow(y, logyx + 1) == x;
}
Where pow() is an integer exponentiation function such as the following in Java:
static int pow(int a, int b) {
return (int)Math.pow(a, b);
}
(This works due to the following guarantee provided by Math.pow: "If both arguments are integers, then the result is exactly equal to the mathematical result of raising the first argument to the power of the second argument...")
The reason to go with logarithms instead of repeated division is performance: while log is slower than division, it is slower by a small fixed multiple. At the same time it does remove the need for a loop and therefore gives you a constant-time algorithm.
In cases where y is 2, there is a quick approach that avoids the need for a loop. This approach can be extended to cases where y is some larger power of 2.
If x is a power of 2, the binary representation of x has a single set bit. There is a fairly simple bit-fiddling algorithm for counting the bits in an integer in O(log n) time where n is the bit-width of an integer. Many processors also have specialised instructions that can handle this as a single operation, about as fast as (for example) an integer negation.
To extend the approach, though, first take a slightly different approach to checking for a single bit. First determine the position of the least significant bit. Again, there is a simple bit-fiddling algorithm, and many processors have fast specialised instructions.
If this bit is the only bit, then (1 << pos) == x. The advantage here is that if you're testing for a power of 4, you can test for pos % 2 == 0 (the single bit is at an even position). Testing for a power of any power of two, you can test for pos % (y >> 1) == 0.
In principle, you could do something similar for testing for powers of 3 and powers of powers of 3. The problem is that you'd need a machine that works in base 3, which is a tad unlikely. You can certainly test any value x to see if its representation in base y has a single non-zero digit, but you'd be doing more work that you're already doing. The above exploits the fact that computers work in binary.
Probably not worth doing in the real world, though.
Here is a Python version which puts together the ideas of #salva and #Axn and is modified to not generate any numbers greater than those given and uses only simple storage (read, "no lists") by repeatedly paring away at the number of interest:
def perfect_base(b, n):
"""Returns True if integer n can be expressed as b**e where
n is a positive integer, else False."""
assert b > 1 and n >= b and int(n) == n and int(b) == b
# parity check
if not b % 2:
if n % 2:
return False # b,n is even,odd
if b == 2:
return n & (n - 1) == 0
if not b & (b - 1) and n & (n - 1):
return False # b == 2**m but n != 2**M
elif not n % 2:
return False # b,n is odd,even
while n >= b:
d = b
while d <= n:
n, r = divmod(n, d)
if r:
return False
d *= d
return n == 1
Previous answers are correct, I liked Paul's answer the best. It's Simple and clean.
Here is the Java implementation of what he suggested:
public static boolean isPowerOfaNumber(int baseOrg, int powerOrg) {
double base = baseOrg;
double power = powerOrg;
while (base % power == 0)
base = base / power;
// return true if base is equal 1
return base == 1;
}
in the case the number is too large ... use log function to reduce time complexity:
import math
base = int(input("Enter the base number: "))
for i in range(base,int(input("Enter the end of range: "))+1):
if(math.log(i) / math.log(base) % 1 == 0 ):
print(i)
If you have access to the largest power of y, that can be fitted inside the required datatype, this is a really slick way of solving this problem.
Lets say, for our case, y == 3. So, we would need to check if x is a power of 3.
Given that we need to check if an integer x is a power of 3, let us start thinking about this problem in terms of what information is already at hand.
1162261467 is the largest power of 3 that can fit into an Java int.
1162261467 = 3^19 + 0
The given x can be expressed as [(a power of 3) + (some n)]. I think it is fairly elementary to be able to prove that if n is 0(which happens iff x is a power of 3), 1162261467 % x = 0.
So, to check if a given integer x is a power of three, check if x > 0 && 1162261467 % x == 0.
Generalizing. To check if a given integer x is a power of a given integer y, check if x > 0 && Y % x == 0: Y is the largest power of y that can fit into an integer datatype.
The general idea is that if A is some power of Y, A can be expressed as B/Ya, where a is some integer and A < B. It follows the exact same principle for A > B. The A = B case is elementary.
I found this Solution
//Check for If A can be expressed as power of two integers
int isPower(int A)
{
int i,a;
double p;
if(A==1)
return 1;
for(int a=1; a<=sqrt(A);++a )
{
p=log(A)/log(a);
if(p-int(p)<0.000000001)
return 1;
}
return 0;
}
binarycoder.org
I hope this isn't a dupe, but it's hard to boil down the problem into keywords!
This is always something that I've wondered about. Let's say you have a black box that takes n integers as an input (where n > 1). Given that there is a bounds on the integer values, how would you go about writing an algorithm that will push the entire sample space through the black box? (bonus points if n can be specified at runtime)
My attempt when n = 2 is as follows:
int min = 0;
int max = 9;
int a = min;
int b = min;
while(a <= max && b <= max)
{
blackBox(a, b);
a++;
if(a > max)
{
a = min;
b++;
}
}
The above code is fine for two variables, but as you might guess, my algorithm gets really ugly when n approaches double-digits.
Is there a better way to do this other than nesting if statements like I have done?
I know a bad way to do it, which would be to randomly generate the values for each iteration and save the inputs of previous iterations so you don't poke the black box with the same variables twice. However, I was hoping for a more speedy method as collisions really hurt the execution time as the number of unique black box calls approaches (max - min + 1) ^ n
Why not used nested loops? Then you just add more nested loops as necessary.
Might not be overly efficent but you did indicate you need to cover the entire sample space, so you're going to have to run every possible combination of values of the input variables anway - so I doubt there's much you can do about efficency unless it's possible to only evaluate against a portion of the state space.
int min = 0;
int max = 9;
for( int a = min ; a <= max ; ++a )
for( int b = min ; b <= max ; ++b )
blackBox( a , b );
Also, I think you'll find the number of unique calls is (max - min + 1) ^ n, not the other way around.
Edit:
A different run-time version to that already suggested
Imre L seems to have hit the nail on the head for a real-time version using the same language type as your question (something C-like), but since you've tagged this as language agnostic I've decided to try something different (also, I'm learning Python at the moment so was looking for an excuse to practice).
Here's a Python real-time version, in each case x will be a n-tuple, such as [1,0,3,2]. Only thing I will say is this does not include max in the state-space (in the example below it will use 0 to 2 inclusive, not 3) so you'd have to increment max before use.
import itertools
min = 0
max = 3
n = 4
for x in itertools.product(range(min,max), repeat=n):
blackBox( x )
The numbers will be held in array a that will be set dynamically eg: int a[] = new int[n]
If the blackBox cannot be modified to take a sample as array then you can either write an ugly wrapper function for calling it with different count of parameters or you are pretty much out of luck for doing it dynamically.
(Procedural) Pseudo code:
int min = 0;
int max = 9;
int a[] = array();
int count = length(a);
setToMinValue(a);
while(a[count-1] <= max)
{
blackBox(a); // or bb(a[0],a[1],...)
a[0]++;
//while next number needs to be increased
for (int i = 0; a[i] > max && i < count-1; i++) {
a[i] = min;
a[i+1]++;
}
}
Here is a generic solution, in Java:
public class Counter implements Iterator<int[]> {
private int[] max;
private int[] vector;
public Counter(int[] maxValues) {
this.max = maxValues;
this.vector = new int[maxValues.length];
}
public int[] next() {
if (!hasNext())
throw new NoSuchElementException();
int[] res = vector.clone();
int i = 0;
while (i < vector.length && vector[i] == max[i]) {
vector[i] = 0;
i++;
}
if (i == vector.length)
vector = null;
else
vector[i]++;
return res;
}
#Override
public boolean hasNext() {
return (vector != null);
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
public static void main(String[] args) {
Counter c = new Counter(new int[]{3});
while (c.hasNext()) {
System.out.println(Arrays.toString(c.next()));
}
}
}
The constructor receives the maximum values for each position. The minimum is always 0 (therefore you can use it to simulate a counter in any radix, and in any "mixed radix"). I added a usage example at the bottom.
You may think of each input to the black box as an n-digit number in a max - min + 1 radix system. For example, if min = 3 and max = 12, then max - min + 1 == 10 and each input to the black box corresponds to an n-digit number in the decimal system. Simply iterate over all the numbers from 0 to (max - min + 1)^n, decode each number and feed the resulting vector to the black box.
Here's a Java implementation:
public static interface BlackBox {
void consume(int... vector);
}
public static void iterateSample(int min, int max, int n, BlackBox bb) {
int radix = max - min + 1;
long limit = (long) Math.pow(radix, n); /* Imprecise for larger numbers! */
for (int i = 0; i < limit; i++) {
int encoded = i;
int[] decoded = new int[n];
for (int j = 0; j < n; j++) {
decoded[j] = min + (encoded % radix);
encoded /= radix;
}
bb.consume(decoded);
}
}
Can someone suggest an algorithm that finds all Pythagorean triplets among numbers in a given array? If it's possible, please, suggest an algorithm faster than O(n2).
Pythagorean triplet is a set {a,b,c} such that a2 = b2 + c2. Example: for array [9, 2, 3, 4, 8, 5, 6, 10] the output of the algorithm should be {3, 4, 5} and {6, 8, 10}.
I understand this question as
Given an array, find all such triplets i,j and k, such that a[i]2 = a[j]2+a[k]2
The key idea of the solution is:
Square each element. (This takes O(n) time). This will reduce the original task to "find three numbers in array, one of which is the sum of other two".
Now it you know how to solve such task in less than O(n2) time, use such algorithm. Out of my mind comes only the following O(n2) solution:
Sort the array in ascending order. This takes O(n log n).
Now consider each element a[i]. If a[i]=a[j]+a[k], then, since numbers are positive and array is now sorted, k<i and j<i.
To find such indexes, run a loop that increases j from 1 to i, and decreases k from i to 0 at the same time, until they meet. Increase j if a[j]+a[k] < a[i], and decrease k if the sum is greater than a[i]. If the sum is equal, that's one of the answers, print it, and shift both indexes.
This takes O(i) operations.
Repeat step 2 for each index i. This way you'll need totally O(n2) operations, which will be the final estimate.
No one knows how to do significantly better than quadratic for the closely related 3SUM problem ( http://en.wikipedia.org/wiki/3SUM ). I'd rate the possibility of a fast solution to your problem as unlikely.
The 3SUM problem is finding a + b + c = 0. Let PYTHTRIP be the problem of finding a^2 + b^2 = c^2 when the inputs are real algebraic numbers. Here is the O(n log n)-time reduction from 3SUM to PYTHTRIP. As ShreevatsaR points out, this doesn't exclude the possibility of a number-theoretic trick (or a solution to 3SUM!).
First we reduce 3SUM to a problem I'll call 3SUM-ALT. In 3SUM-ALT, we want to find a + b = c where all array entries are nonnegative. The finishing reduction from 3SUM-ALT to PYTHTRIP is just taking square roots.
To solve 3SUM using 3SUM-ALT, first eliminate the possibility of triples where one of a, b, c is zero (O(n log n)). Now, any satisfying triple has two positive numbers and one negative, or two negative and one positive. Let w be a number greater than three times the absolute value of any input number. Solve two instances of 3SUM-ALT: one where all negative x are mapped to w - x and all positive x are mapped to 2w + x; one where all negative x are mapped to 2w - x and all positive x are mapped to w + x. The rest of the proof is straightforward.
I have one more solution,
//sort the array in ascending order
//find the square of each element in the array
//let 'a' be the array containing square of each element in ascending order
for(i->0 to (a.length-1))
for (j->i+1 to (a.length-1))
//search the a[i]+a[j] ahead in the array from j+1 to the end of array
//if found get the triplet according to sqrt(a[i]),sqrt(a[j]) & sqrt(a[i]+a[j])
endfor
endfor
Not sure if this is any better but you can compute them in time proportional to the maximum value in the list by just computing all possible triples less than or equal to it. The following Perl code does. The time complexity of the algorithm is proportional to the maximum value since the sum of inverse squares 1 + 1/2^2 + 1/3^3 .... is equal to Pi^2/6, a constant.
I just used the formula from the Wikipedia page for generating none unique triples.
my $list = [9, 2, 3, 4, 8, 5, 6, 10];
pythagoreanTriplets ($list);
sub pythagoreanTriplets
{
my $list = $_[0];
my %hash;
my $max = 0;
foreach my $value (#$list)
{
$hash{$value} = 1;
$max = $value if ($value > $max);
}
my $sqrtMax = 1 + int sqrt $max;
for (my $n = 1; $n <= $sqrtMax; $n++)
{
my $n2 = $n * $n;
for (my $m = $n + 1; $m <= $sqrtMax; $m++)
{
my $m2 = $m * $m;
my $maxK = 1 + int ($max / ($m2 + $n2));
for (my $k = 1; $k <= $maxK; $k++)
{
my $a = $k * ($m2 - $n2);
my $b = $k * (2 * $m * $n);
my $c = $k * ($m2 + $n2);
print "$a $b $c\n" if (exists ($hash{$a}) && exists ($hash{$b}) && exists ($hash{$c}));
}
}
}
}
Here's a solution which might scale better for large lists of small numbers. At least it's different ;v) .
According to http://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple,
a = m^2 - n^2, b = 2mn, c = m^2 + n^2
b looks nice, eh?
Sort the array in O(N log N) time.
For each element b, find the prime factorization. Naively using a table of primes up to the square root of the largest input value M would take O(sqrt M/log M) time and space* per element.
For each pair (m,n), m > n, b = 2mn (skip odd b), search for m^2-n^2 and m^2+n^2 in the sorted array. O(log N) per pair, O(2^(Ω(M))) = O(log M)** pairs per element, O(N (log N) (log M)) total.
Final analysis: O( N ( (sqrt M/log M) + (log N * log M) ) ), N = array size, M = magnitude of values.
(* To accept 64-bit input, there are about 203M 32-bit primes, but we can use a table of differences at one byte per prime, since the differences are all even, and perhaps also generate large primes in sequence on demand. To accept 32-bit input, a table of 16-bit primes is needed, which is small enough to fit in L1 cache. Time here is an overestimate assuming all prime factors are just less than the square root.)
(** Actual bound lower because of duplicate prime factors.)
Solution in O(N).
find out minimum element in array. min O(n).
find out maximum element in array. max O(n).
make a hastable of elements so that element can be searched in O(1).
m^2-1 = min .... put min from step 1. find out m in this equation.O(1)
2m = min .... put min from step 1. find out m in this equation.O(1)
m^2+1= max .... put max from step 2. find out m in this equation.O(1)
choose floor of min of (steps 4,5,6) let say minValue.O(1)
choose ceil of max of (steps 4,5,6) let say maxValue.O(1)
loop from j=minValue to maxValue. maxvalue-minvalue will be less than root of N.
9.a calculate three numbers j^2-1,2j,j^2+1.
9.b search these numbers in hashtable. if found return success.
return failure.
A few of my co-workers were asked this very same problem in a java cert course they were taking the solution we came up with was O(N^2). We shaved off as much of the problem space as we could but we could not find a way to drop the complexity to N Log N or better.
public static List<int[]> pythagoreanTripplets(int[] input) {
List<int[]> answers = new ArrayList<int[]>();
Map<Long, Integer> map = new HashMap<Long, Integer>();
for (int i = 0; i < input.length; i++) {
map.put((long)input[i] * (long)input[i], input[i]);
}
Long[] unique = (Long[]) map.keySet().toArray(new Long[0]);
Arrays.sort(unique);
long comps =0;
for(int i = 1 ; i < unique.length;i++)
{
Long halfC = unique[i]/2;
for(int j = i-1 ; j>= 0 ; j--)
{
if(unique[j] < halfC) break;
if(map.containsKey(unique[i] - unique[j]))
{
answers.add(new int[]{map.get(unique[i] - unique[j]),map.get(unique[j]),map.get(unique[i])});
}
}
}
return answers;
}
If (a, b, c) is a Pythagorean triple, then so is (ka, kb, kc) for any positive integer.
so simply find one value for a, b, and c and then you can calculate as many new ones as you want.
Pseudo code:
a = 3
b = 4
c = 5
for k in 1..N:
P[k] = (ka, kb, kc)
Let me know if this is not exactly what you're looking for.
It can be done in O(n) time. first hash the elements in map for existence check. after that apply the below algorithm
Scan the array and if element is even number, (n,n^2/2 +1, n^2/2 -1) is triplet to be found. just check for that's existence using hash map lookup. if all elements in triplet exists, print the triplet.
This is the one i had implemented ...
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* #author Pranali Choudhari (pranali_choudhari#persistent.co.in)
*/
public class PythagoreanTriple {
/
//I hope this is optimized
public static void main(String[] args) {
Map<Long,Set<Long>> triples = new HashMap<Long,Set<Long>>();
List<Long> l1 = new ArrayList<Long>();
addValuesToArrayList(l1);
long n =0;
for(long i : l1){
//if its side a.
n = (i-1L)/2L;
if (n!=0 && n > 0){
putInMap(triples,n,i);
n=0;
}
//if its side b
n = ((-1 + Math.round(Math.sqrt(2*i+1)))/2);
if (n != 0 && n > 0){
putInMap(triples,n,i);
n=0;
}
n= ((-1 - Math.round(Math.sqrt(2*i+1)))/2);
if (n != 0 && n > 0){
putInMap(triples,n,i);
n=0;
}
//if its side c
n = ((-1 + Math.round(Math.sqrt(2*i-1)))/2);
if (n != 0 && n > 0){
putInMap(triples,n,i);
n=0;
}
n= ((-1 - Math.round(Math.sqrt(2*i-1)))/2);
if (n != 0 && n > 0){
putInMap(triples,n,i);
n=0;
}
}
for(Map.Entry<Long, Set<Long>> e : triples.entrySet()){
if(e.getValue().size() == 3){
System.out.println("Tripples" + e.getValue());
}
//need to handle scenario when size() > 3
//even those are tripples but we need to filter the wrong ones
}
}
private static void putInMap( Map<Long,Set<Long>> triples, long n, Long i) {
Set<Long> set = triples.get(n);
if(set == null){
set = new HashSet<Long>();
triples.put(n, set);
}
set.add(i);
}
//add values here
private static void addValuesToArrayList(List<Long> l1) {
l1.add(1L);
l1.add(2L);
l1.add(3L);
l1.add(4L);
l1.add(5L);
l1.add(12L);
l1.add(13L);
}
}
Here's the implementation in Java:
/**
* Step1: Square each of the elements in the array [O(n)]
* Step2: Sort the array [O(n logn)]
* Step3: For each element in the array, find all the pairs in the array whose sum is equal to that element [O(n2)]
*
* Time Complexity: O(n2)
*/
public static Set<Set<Integer>> findAllPythogoreanTriplets(int [] unsortedData) {
// O(n) - Square all the elements in the array
for (int i = 0; i < unsortedData.length; i++)
unsortedData[i] *= unsortedData[i];
// O(n logn) - Sort
int [] sortedSquareData = QuickSort.sort(unsortedData);
// O(n2)
Set<Set<Integer>> triplets = new HashSet<Set<Integer>>();
for (int i = 0; i < sortedSquareData.length; i++) {
Set<Set<Integer>> pairs = findAllPairsThatSumToAConstant(sortedSquareData, sortedSquareData[i]);
for (Set<Integer> pair : pairs) {
Set<Integer> triplet = new HashSet<Integer>();
for (Integer n : pair) {
triplet.add((int)Math.sqrt(n));
}
triplet.add((int)Math.sqrt(sortedSquareData[i])); // adding the third element to the pair to make it a triplet
triplets.add(triplet);
}
}
return triplets;
}
public static Set<Set<Integer>> findAllPairsThatSumToAConstant(int [] sortedData, int constant) {
// O(n)
Set<Set<Integer>> pairs = new HashSet<Set<Integer>>();
int p1 = 0; // pointing to the first element
int p2 = sortedData.length - 1; // pointing to the last element
while (p1 < p2) {
int pointersSum = sortedData[p1] + sortedData[p2];
if (pointersSum > constant)
p2--;
else if (pointersSum < constant)
p1++;
else {
Set<Integer> set = new HashSet<Integer>();
set.add(sortedData[p1]);
set.add(sortedData[p2]);
pairs.add(set);
p1++;
p2--;
}
}
return pairs;
}
if the problem is the one "For an Array of integers find all triples such that a^2+b^2 = c^2
Sort the array into ascending order
Set three pointers p1,p2,p3 at entries 0,1,2
set pEnd to past the last entry in the array
while (p2 < pend-2)
{
sum = (*p1 * *p1 + *p2 * *p2)
while ((*p3 * *p3) < sum && p3 < pEnd -1)
p3++;
if ( *p3 == sum)
output_triple(*p1, *p2, *p3);
p1++;
p2++;
}
it's moving 3 pointers up the array so it O(sort(n) + n)
it's not n2 because the next pass starts at the next largest number and doesn't reset.
if the last number was too small for the triple, it's still to small when you go to the next bigger a and b
public class FindPythagorusCombination {
public static void main(String[] args) {
int[] no={1, 5, 3, 4, 8, 10, 6 };
int[] sortedno= sorno(no);
findPythaComb(sortedno);
}
private static void findPythaComb(int[] sortedno) {
for(int i=0; i<sortedno.length;i++){
int lSum=0, rSum=0;
lSum= sortedno[i]*sortedno[i];
for(int j=i+1; j<sortedno.length; j++){
for(int k=j+1; k<sortedno.length;k++){
rSum= (sortedno[j]*sortedno[j])+(sortedno[k]*sortedno[k]);
if(lSum==rSum){
System.out.println("Pythagorus combination found: " +sortedno[i] +" " +sortedno[j]+" "+sortedno[k]);
}else
rSum=0;
}
}
}
}
private static int[] sorno(int[] no) {
for(int i=0; i<no.length;i++){
for(int j=i+1; j<no.length;j++){
if(no[i]<no[j]){
int temp= no[i];
no[i]= no[j];
no[j]=temp;
}
}
}
return no;
}
}
import java.io.*;
import java.lang.*;
import java.util.*;
class PythagoreanTriplets
{
public static void main(String args[])throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int arr[] = new int[n];
int i,j,k,sum;
System.out.println("Enter the numbers ");
for(i=0;i<n;i++)
{
arr[i]=Integer.parseInt(br.readLine());
arr[i]=arr[i]*arr[i];
}
Arrays.sort(arr);
for(i=n-1;i>=0;i--)
{
for(j=0,k=i-1;j<k;)
{
sum=arr[j]+arr[k];
if(sum==arr[i]){System.out.println((int)Math.sqrt(arr[i]) +","+(int)Math.sqrt(arr[j])+","+(int)Math.sqrt(arr[k]));break;}
else if(sum>arr[i])k--;
else j++;
}
}
}
}
Finding Pythagorean triplets in O(n)
Algorithm:
For each element in array, check it is prime or not
if it is prime, calculate other two number as ((n^2)+1)/2 and ((n^2)-1)/2 and check whether these two calculated number is in array
if it is not prime, calculate other two number as mentioned in else case in code given below
Repeat until end of array is reached
int arr[]={1,2,3,4,5,6,7,8,9,10,12,13,11,60,61};
int prim[]={3,5,7,11};//store all the prime numbers
int r,l;
List<Integer> prime=new ArrayList<Integer>();//storing in list,so that it is easy to search
for(int i=0;i<4;i++){
prime.add(prim[i]);
}
List<Integer> n=new ArrayList<Integer>();
for(int i=0;i<arr.length;i++)
{
n.add(arr[i]);
}
double v1,v2,v3;
int dummy[]=new int[arr.length];
for(int i=0;i<arr.length;i++)
dummy[i]=arr[i];
Integer x=0,y=0,z=0;
List<Integer> temp=new ArrayList<Integer>();
for(int i=0;i<arr.length;i++)
{
temp.add(arr[i]);
}
for(int j:n){
if(prime.contains(j)){//if it is prime
double a,b;
v1=(double)j;
v2=Math.ceil(((j*j)+1)/2);
v3=Math.ceil(((j*j)-1)/2);
if(n.contains((int)v2) && n.contains((int)v3)){
System.out.println((int)v1+" "+(int)v2+" "+(int)v3);
}
}
else//if it is not prime
{
if(j%3==0){
x=j;
y=4*(j/3);
z=5*(j/3);
if(temp.contains(y) && temp.contains(z)){
System.out.println(x+" "+y+" "+z);
//replacing those three elements with 0
dummy[temp.indexOf(x)-1]=0;
dummy[temp.indexOf(y)-1]=0;
dummy[temp.indexOf(z)-1]=0;
}
}
}//else end
}//for end
Complexity: O(n)
Take a look at the following code that I wrote.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
bool existTriplet(vector<ll> &vec)
{
for(auto i = 0; i < vec.size(); i++)
{
vec[i] = vec[i] * vec[i]; //Square all the array elements
}
sort(vec.begin(), vec.end()); //Sort it
for(auto i = vec.size() - 1; i >= 2; i--)
{
ll l = 0;
ll r = i - 1;
while(l < r)
{
if(vec[l] + vec[r] == vec[i])
return true;
vec[l] + vec[r] < vec[i] ? l++ : r--;
}
}
return false;
}
int main() {
int T;
cin >> T;
while(T--)
{
ll n;
cin >> n;
vector<ll> vec(n);
for(auto i = 0; i < n; i++)
{
cin >> vec[i];
}
if(existTriplet(vec))
cout << "Yes";
else
cout << "No";
cout << endl;
}
return 0;
}
Plato's formula for Pythagorean Triples:
Plato, a Greek Philosopher, came up with a great formula for finding Pythagorean triples.
(2m)^2 + (m^2 - 1)^2 = (m^2 + 1)^2
bool checkperfectSquare(int num){
int sq=(int)round(sqrt(num));
if(sq==num/sq){
return true;
}
else{
return false;
}
}
void solve(){
int i,j,k,n;
// lenth of array
cin>>n;
int ar[n];
// reading all the number in array
for(i=0;i<n;i++){
cin>>ar[i];
}
// sort the array
sort(ar,ar+n);
for(i=0;i<n;i++){
if(ar[i]<=2){
continue;
}
else{
int tmp1=ar[i]+1;
int m;
if(checkperfectSquare(tmp1)){
m=(ll)round(sqrt(tmp1));
int b=2*m,c=(m*m)+1;
if(binary_search(ar,ar+n,b)&&binary_search(ar,ar+n,c)){
cout<<ar[i]<<" "<<b<<" "<<c<<endl;
break;
}
}
if(ar[i]%2==0){
m=ar[i]/2;
int b=(m*m-1),c=(m*m+1);
if(binary_search(ar,ar+n,b)&&binary_search(ar,ar+n,c)){
cout<<ar[i]<<" "<<b<<" "<<c<<endl;
break;
}
}
}
}
}