Possible Paths [HackerRank] - math

Please see the following Question recently posted on HackerRank
Adam is standing at point (a,b) in an infinite 2D grid. He wants to know if he can reach point (x,y) or not. The only operation he can do is to move to point (a+b,b), (a,a+b), (a-b,b), or (a,a-b) from some point (a,b). It is given that he can move to any point on this 2D grid,i.e., the points having positive or negative X(or Y) co-ordinates.Tell Adam whether he can reach (x,y) or not.
https://www.hackerrank.com/contests/infinitum-jun14/challenges/possible-path
I realized that both x and y must be a sum of some multiple of a and b...
So x%(a+b) OR x%(a-b) should be divisible by either a or b
and similarly for y...
But the following does not work ...
long long int xb,yb,xa,ya;
xb = x % b;
xa = x % a;
yb = y % b;
ya = y % a;
// for x
bool cxbaplusb = a+b==0 ? xb == 0: (xb%(a+b))==0;
bool cxbaminb = a-b==0 ? xb == 0: (xb%(a-b))==0;
// for y
bool cybaplusb = a+b==0 ? yb == 0: (yb%(a+b))==0;
bool cybaminb = a-b==0 ? yb == 0: (yb%(a-b))==0;
// for x
bool cxaaplusb = a+b==0 ? xa == 0: (xa%(a+b))==0;
bool cxaaminb = a-b==0 ? xa == 0: (xa%(a-b))==0;
// for y
bool cyaaplusb = a+b==0 ? ya == 0: (ya%(a+b))==0;
bool cyaaminb = a-b==0 ? ya == 0: (ya%(a-b))==0;
if ( (cxbaplusb || cxbaminb || cxaaplusb || cxaaminb) && (cybaplusb || cybaminb || cyaaplusb || cyaaminb) )
std::cout << "YES" << std::endl;
else
std::cout << "NO" << std::endl;
But this is not working ... Am I missing any conditions ? Any suggestions ??

The following mathematical explanation may help you achieve your goal.
Source: https://hr-filepicker.s3.amazonaws.com/infinitum-jun14/editorials/2372-possible-path.pdf

Please check the input size
1 ≤ a,b,x,y ≤ 10^18
https://www.hackerrank.com/challenges/possible-path
CPP won't support this much size, it will throw garbage value resulting in wrong answer
def gcd(a, b):
if(b == 0):
return a
return gcd(b, a%b)
t=input()
for i in range(t):
a = map(int, raw_input().split())
if(gcd(a[0],a[1]) == gcd(a[2],a[3])):
print "YES"
else:
print "NO"

#include<iostream>
using namespace std;
int gcd(int a, int b){
return b ? gcd(b, a%b) : a;
}
int main(){
int t;
cin >> t;
while (t--){
int a, b, x, y;
cin >> a >> b >> x >> y;
if (gcd(abs(a), abs(b)) == gcd(abs(x), abs(y)))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}

Initially I had same doubt as you , but its not " x and y must be a sum of some multiple of a and b " because we can move from (a,b) to any point in (a+b,b), (a-b,b),(a,b+a),(a,b-a) in case if you move (a+b,b) now a=a+b,b=b so for this value of a,b ( not the given one here a is updated to a+b) only you can do the above operation so its not that x and y always must be sum of some multiple of a,b . so that you have to go with gcd method

public class Solution {
public static void main(String[] args) {
int a,b,x,y;
if(gcd(x,y)=gcd(a,b))
System.out.println("Adam can reach")
else
System.out.println("Adam cannot reach")
}
}

Related

Like Bezout's identity but with Natural numbers and an arbitrary constant. Can it be solved?

I'm an amateur playing with discrete math. This isn't a
homework problem though I am doing it at home.
I want to solve ax + by = c for natural numbers, with a, b and c
given and x and y to be computed. I want to find all x, y pairs
that will satisfy the equation.
This has a similar structure to Bezout's identity for integers
where there are multiple (infinite?) solution pairs. I thought
the similarity might mean that the extended Euclidian algorithm
could help here. Below are two implementations of the EEA that
seem to work; they're both adapted from code found on the net.
Could these be adapted to the task, or perhaps can someone
find a more promising avenue?
typedef long int Int;
#ifdef RECURSIVE_EEA
Int // returns the GCD of a and b and finds x and y
// such that ax + by == GCD(a,b), recursively
eea(Int a, Int b, Int &x, Int &y) {
if (0==a) {
x = 0;
y = 1;
return b;
}
Int x1; x1=0;
Int y1; y1=0;
Int gcd = eea(b%a, a, x1, y1);
x = y1 - b/a*x1;
y = x1;
return gcd;
}
#endif
#ifdef ITERATIVE_EEA
Int // returns the GCD of a and b and finds x and y
// such that ax + by == GCD(a,b), iteratively
eea(Int a, Int b, Int &x, Int &y) {
x = 0;
y = 1;
Int u; u=1;
Int v; v=0; // does this need initialising?
Int q; // quotient
Int r; // remainder
Int m;
Int n;
while (0!=a) {
q = b/a; // quotient
r = b%a; // remainder
m = x - u*q; // ?? what are the invariants?
n = y - v*q; // ?? When does this overflow?
b = a; // A candidate for the gcd - a's last nonzero value.
a = r; // a becomes the remainder - it shrinks each time.
// When a hits zero, the u and v that are written out
// are final values and the gcd is a's previous value.
x = u; // Here we have u and v shuffling values out
y = v; // via x and y. If a has gone to zero, they're final.
u = m; // ... and getting new values
v = n; // from m and n
}
return b;
}
#endif
If we slightly change the equation form:
ax + by = c
by = c - ax
y = (c - ax)/b
Then we can loop x through all numbers in its range (a*x <= c) and compute if viable natural y exists. So no there is not infinite number of solutions the limit is min(c/a,c/b) ... Here small C++ example of naive solution:
int a=123,b=321,c=987654321;
int x,y,ax;
for (x=1,ax=a;ax<=c;x++,ax+=a)
{
y = (c-ax)/b;
if (ax+(b*y)==c) here output x,y solution somewhere;
}
If you want to speed this up then just iterate y too and just check if c-ax is divisible by b Something like this:
int a=123,b=321,c=987654321;
int x,y,ax,cax,by;
for (x=1,ax=a,y=(c/b),by=b*y;ax<=c;x++,ax+=a)
{
cax=c-ax;
while (by>cax){ by-=b; y--; if (!y) break; }
if (by==cax) here output x,y solution somewhere;
}
As you can see now both x,y are iterated in opposite directions in the same loop and no division or multiplication is present inside loop anymore so its much faster here first few results:
method1 method2
[ 78.707 ms] | [ 21.277 ms] // time needed for computation
75044 | 75044 // found solutions
-------------------------------
75,3076776 | 75,3076776 // first few solutions in x,y order
182,3076735 | 182,3076735
289,3076694 | 289,3076694
396,3076653 | 396,3076653
503,3076612 | 503,3076612
610,3076571 | 610,3076571
717,3076530 | 717,3076530
824,3076489 | 824,3076489
931,3076448 | 931,3076448
1038,3076407 | 1038,3076407
1145,3076366 | 1145,3076366
I expect that for really huge c and small a,b numbers this
while (by>cax){ by-=b; y--; if (!y) break; }
might be slower than actual division using GCD ...

FINDING total number of paths using backtracking

I'm trying to count total paths in a 20x20 grid(ProjectEuler #15) using backtracking.I've played around with it but the answer is always None. Any help would be appreciated(I know it can be solved using recursion or memoization but i want to solve it using backtracking)
def isvalid(maze,n,x,y):
if x<0 or y<0 or x>n or y>n :
return False
else: return True
def countPaths(maze,x,y,n,used,count):
if x==n-1 or y==n-1:
count+=1
return
if isvalid(maze,n,x,y):
used[x][y]=True
if (x+1<n and used[x+1][y]==False):
countPaths(maze,x+1,y,n,used,count)
if (x-1>0 and used[x-1][y]==False):
countPaths(maze,x-1,y,n,used,count)
if (y+1<n and used[x][y+1]==False):
countPaths(maze,x,y+1,n,used,count)
if (y-1>0 and used[x][y-1]==False):
countPaths(maze,x,y-1,n,used,count)
used[x][y]=False
return
Since in the base case, you are only returning 1 whenever end of row or column occurs it would yield wrong answer.
You should increment a counter signifying the number of times you are able to reach the final [n-1][n-1] i.e rightmost bottom cell.
bool isValid(int x, int y)
{
if (x < 0 || x >= n || y < 0 || y >= n)
return false;
return true;
}
void countPaths(int x, int y)
{
// cout << x << y << endl;
if (x == n - 1 && y == n - 1)
{
paths++;
return;
}
if (isValid(x, y))
{
visited[x][y] = true;
countPaths(x, y + 1);
countPaths(x + 1, y);
}
return;
}
Keeping paths & visited as global variables , I implemented the above approach.
For n=2 (1+1): 2
For n=3 (2+1): 6
For n=4 (3+1): 20
For n=5 (4+1): 70
however, this approach would not be viable for n=20.
I would suggest trying Dynamic Programming as it would simplify the process!

How do I use recursion to calculate the greatest common divisor (GCD) of 2 numbers and find the maximum number of modulus operations it took?

The program needs to measure the maximum number of modulus operations it took to calculate the GCD of 2 integers at each value of "i" from 8 to n.
For example, if i = 8, I have to find the combination of (a,b) that took the most modulus operations to calculate the GCD.
I have to calculate GCD for all values of 'a' (1-i) for every value of 'b' between (1-i) and do this at every value of "i" until it reaches n.
For example, if n = 15, the output must look like this:
At i = 8; GCD (5, 8) = 1 took 4 modulus operations
At i = 9; GCD (5, 8) = 1 took 4 modulus operations
At i = 10; GCD (5, 8) = 1 took 4 modulus operations
At i = 11; GCD (5, 8) = 1 took 4 modulus operations
At i = 12; GCD (5, 8) = 1 took 4 modulus operations
At i = 13; GCD (8, 13) = 1 took 5 modulus operations
At i = 14; GCD (8, 13) = 1 took 5 modulus operations
At i = 15; GCD (8, 13) = 1 took 5 modulus operations
Here's my code so far because I'm so confused on the implementation:
class Euclidean
{
public:
//Finds the GCD using modulus operations until the remainder is 0
int calcGCD(int x , int y)
{
int remainder;
while(y != 0)
{
remainder = x % y;
x = y;
y = remainder;
}
return x;
}
//Calculates the maximum amount of oprations required to calculate GCD
//at (a,b) for every i from 8 to n
int CalculateMaxOperations(int n)
{
int GCD;
int a;
int b;
for(i = 8; i <= n; i++)
{
for(b = 1; b <= i; b++)
{
if( b <= i)
{
for(a = 1; a <= i; a++)
{
if(a <= i)
{
GCD = calcGCD(a, b);
}
}
}
}
}
}
//Print statement reveals the set (a,b) that took the most operations to calculate
//the GCD at every single value 'i' until it eventually reaches 'n.'
void PrintResults(int c, int d, int operations)
{
cout << "At i = " << i << ";" << " GCD (" << c << "," << d << ")" << " = " <<
calcGCD (c, d) << " took " << operations << " operations " << endl;
}
private:
int i;
};
int main()
{
Euclidean e;
int x = e.CalculateMaxOperations(15);
return 0;
}

What's wrong with my dynamic programming solution for uva 10739?

I'm solving this problem on uva. I've found the recurrence relation and it works perfectly for the given test cases. However, without memoization, it exceeds time limit. I cached the values and returned the cache(basic memoization). With caching, I'm getting an answer of 1 more than the actual answer for the last two test cases. I can't understand what might be the bug because it works if you take out the caching. Thanks for your help.
Code:
#include<iostream>
using namespace std;
string a;
int n;
int dp[1005][1005];
int solve(int i, int j, int moves)
{
if(j<=i)
return dp[i][j] = moves;
if(dp[i][j]!=-1)
return dp[i][j];
if(a[i]==a[j])
return dp[i][j] = solve(i+1, j-1, moves);
else
return dp[i][j] = min(min(solve(i+1, j-1, moves+1), solve(i+1, j, moves+1)), solve(i, j-1, moves+1));
}
int main()
{
int T;
cin >> T;
while(T--)
{
cin >> a;
n = a.length();
memset(dp, -1, sizeof(dp));
int ans = solve(0, n-1, 0);
cout << ans << "\n";
}
}
Expected O/P for:
sadrulhabibchowdhury: 8
My Output: 9

What is the most efficient way to calculate the least common multiple of two integers?

What is the most efficient way to calculate the least common multiple of two integers?
I just came up with this, but it definitely leaves something to be desired.
int n=7, m=4, n1=n, m1=m;
while( m1 != n1 ){
if( m1 > n1 )
n1 += n;
else
m1 += m;
}
System.out.println( "lcm is " + m1 );
The least common multiple (lcm) of a and b is their product divided by their greatest common divisor (gcd) ( i.e. lcm(a, b) = ab/gcd(a,b)).
So, the question becomes, how to find the gcd? The Euclidean algorithm is generally how the gcd is computed. The direct implementation of the classic algorithm is efficient, but there are variations that take advantage of binary arithmetic to do a little better. See Knuth's "The Art of Computer Programming" Volume 2, "Seminumerical Algorithms" § 4.5.2.
Remember
The least common multiple is the least whole number that is a multiple of each of two or more numbers.
If you are trying to figure out the LCM of three integers, follow these steps:
**Find the LCM of 19, 21, and 42.**
Write the prime factorization for each number. 19 is a prime number. You do not need to factor 19.
21 = 3 × 7
42 = 2 × 3 × 7
19
Repeat each prime factor the greatest number of times it appears in any of the prime factorizations above.
2 × 3 × 7 × 19 = 798
The least common multiple of 21, 42, and 19 is 798.
I think that the approach of "reduction by the greatest common divider" should be faster. Start by calculating the GCD (e.g. using Euclid's algorithm), then divide the product of the two numbers by the GCD.
Best solution in C++ below without overflowing
#include <iostream>
using namespace std;
long long gcd(long long int a, long long int b){
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b){
if(a>b)
return (a/gcd(a,b))*b;
else
return (b/gcd(a,b))*a;
}
int main()
{
long long int a ,b ;
cin>>a>>b;
cout<<lcm(a,b)<<endl;
return 0;
}
First of all, you have to find the greatest common divisor
for(int i=1; i<=a && i<=b; i++) {
if (i % a == 0 && i % b == 0)
{
gcd = i;
}
}
After that, using the GCD you can easily find the least common multiple like this
lcm = a / gcd * b;
I don't know whether it is optimized or not, but probably the easiest one:
public void lcm(int a, int b)
{
if (a > b)
{
min = b;
max = a;
}
else
{
min = a;
max = b;
}
for (i = 1; i < max; i++)
{
if ((min*i)%max == 0)
{
res = min*i;
break;
}
}
Console.Write("{0}", res);
}
Here is a highly efficient approach to find the LCM of two numbers in python.
def gcd(a, b):
if min(a, b) == 0:
return max(a, b)
a_1 = max(a, b) % min(a, b)
return gcd(a_1, min(a, b))
def lcm(a, b):
return (a * b) // gcd(a, b)
Using Euclidean algorithm to find gcd and then calculating the lcm dividing a by the product of gcd and b worked for me.
int euclidgcd(int a, int b){
if(b==0)
return a;
int a_rem = a % b;
return euclidgcd(b, a_rem);
}
long long lcm(int a, int b) {
int gcd=euclidgcd(a, b);
return (a/gcd*b);
}
int main() {
int a, b;
std::cin >> a >> b;
std::cout << lcm(a, b) << std::endl;
return 0;
}
Take successive multiples of the larger of the two numbers until the result is a multiple of the smaller.
this might work..
public int LCM(int x, int y)
{
int larger = x>y? x: y,
smaller = x>y? y: x,
candidate = larger ;
while (candidate % smaller != 0) candidate += larger ;
return candidate;
}
C++ template. Compile time
#include <iostream>
const int lhs = 8, rhs = 12;
template<int n, int mod_lhs=n % lhs, int mod_rhs=n % rhs> struct calc {
calc() { }
};
template<int n> struct calc<n, 0, 0> {
calc() { std::cout << n << std::endl; }
};
template<int n, int mod_rhs> struct calc<n, 0, mod_rhs> {
calc() { }
};
template<int n, int mod_lhs> struct calc <n, mod_lhs, 0> {
calc() { }
};
template<int n> struct lcm {
lcm() {
lcm<n-1>();
calc<n>();
}
};
template<> struct lcm<0> {
lcm() {}
};
int main() {
lcm<lhs * rhs>();
}
Euclidean GCD code snippet
int findGCD(int a, int b) {
if(a < 0 || b < 0)
return -1;
if (a == 0)
return b;
else if (b == 0)
return a;
else
return findGCD(b, a % b);
}
Product of 2 numbers is equal to LCM * GCD or HCF. So best way to find LCM is to find GCD and divide the product with GCD. That is, LCM(a,b) = (a*b)/GCD(a,b).
There is no way more efficient than using a built-in function!
As of Python 3.8 lcm() function has been added in math library. And can be called with folowing signature:
math.lcm(*integers)
Returns the least common multiple of the specified integer arguments. If all arguments are nonzero, then the returned value is the smallest positive integer that is a multiple of all arguments. If any of the arguments is zero, then the returned value is 0. lcm() without arguments returns 1.
Extending #John D. Cook answer that is also marked answer for this question. ( https://stackoverflow.com/a/3154503/13272795), I am sharing algorithm to find LCM of n numbers, it maybe LCM of 2 numbers or any numbers. Source for this code is this
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Returns LCM of array elements
ll findlcm(int arr[], int n)
{
// Initialize result
ll ans = arr[0];
// ans contains LCM of arr[0], ..arr[i]
// after i'th iteration,
for (int i = 1; i < n; i++)
ans = arr[i] * ans/gcd(arr[i], ans);
return ans;
}
Since we know the mathematic property which states that "product of LCM and HCF of any two numbers is equal to the product of the two numbers".
lets say X and Y are two integers,
then
X * Y = HCF(X, Y) * LCM(X, Y)
Now we can find LCM by knowing the HCF, which we can find through Euclidean Algorithm.
LCM(X, Y) = (X * Y) / HCF(X, Y)
Hope this will be efficient.
import java.util.*;
public class Hello {
public static int HCF(int X, int Y){
if(X == 0)return Y;
return HCF(Y%X, X);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt(), Y = scanner.nextInt();
System.out.print((X * Y) / HCF(X, Y));
}
}
Yes, there are numerous way to calculate LCM such as using GCD (HCF).
You can apply prime decomposition such as (optimized/naive) Sieve Eratosthenes or find factor of prime number to compute GCD, which is way more faster than calculate LCM directly. Then as all said above, LCM(X, Y) = (X * Y) / GCD(X, Y)
I googled the same question, and found this Stackoverflow page,
however I come up with another simple solution using python
def find_lcm(numbers):
h = max(numbers)
lcm = h
def check(l, numbers):
remainders = [ l%n==0 for n in numbers]
return all(remainders)
while (check(lcm, numbers) == False):
lcm = lcm + h
return lcm
for
numbers = [120,150,135,225]
it will return 5400
numbers = [120,150,135,225]
print(find_lcm(numbers)) # will print 5400

Resources