I have a question which is actually requires a bit of understanding Euclidian Algorithm. Problem is simple. An int "First" and int "Second" numbers are given by the user via Scanner.
Than we need to find greatest common divisor of them. Than the process goes like explained below:
Now Assume that the First number is: 42 and the Second is: 30 - they've given by the user. -
int x, y;
(x * First) + (y * Second) = gcd(First, Second); // x ? y ?
To Find GCD you may use: gcd(First, Second); Code is below:
public static int gcd(int a, int b)
{
if(a == 0 || b == 0) return a+b; // base case
return gcd(b,a%b);
}
Sample Input: First: 24 Second: 48 and Output should be x: (-3) and y: 2
Sample Input: First: 42 Second: 30 and Output should be x: (-2) and y: 3
Sample Input: First: 35 Second: 05 and Output should be x: (0) and y: 1
(x * First) + (y * Second) = gcd(First, Second); // How can we find x and y ?
I would very appreciate it if you could show a solution code wise in java thanks for checking!
The Extended Euclidean Algorithm is described in this Wikipedia article. The basic algorithm is stated like this (it looks better in the Wikipedia article):
More precisely, the standard Euclidean algorithm with a and b as
input, consists of computing a sequence q1,...,
qk of quotients and a sequence r0,...,
rk+1 of remainders such that
r0=a r1=b ...
ri+1=ri-1-qi ri and 0 <
ri+1 < |ri| ...
It is the main property of Euclidean division that the inequalities on
the right define uniquely ri+1 from ri-1 and
ri.
The computation stops when one reaches a remainder rk+1
which is zero; the greatest common divisor is then the last non zero
remainder rk.
The extended Euclidean algorithm proceeds similarly, but adds two
other sequences defined by
s0=1, s1=0 t0=0,
t1=1 ...
si+1=si-1-qi si
ti+1=ti-1-qi ti
This should be easy to implement in Java, but the mathematical way it's expressed may make it hard to understand. I'll try to break it down.
Note that this is probably going to be easier to implement in a loop than recursively.
In the standard Euclidean algorithm, you compute ri+1 in terms of ri-1 and ri. This means that you have to save the two previous versions of r. This part of the formula:
ri+1=ri-1-qi ri and 0 <
ri+1 < |ri| ...
just means that ri+1 will be the remainder when ri-1 is divided by ri. qi is the quotient, which you don't use in the standard Euclidean algorithm, but you do use in the extended one. So Java code to perform the standard Euclidean algorithm (i.e. compute the GCD) might look like:
prevPrevR = a;
prevR = b;
while ([something]) {
nextR = prevPrevR % prevR;
quotient = prevPrevR / prevR; // not used in the standard algorithm
prevPrevR = prevR;
prevR = nextR;
}
Thus, at any point, prevPrevR will be essentially ri-1, and prevR will be ri. The algorithm computes the next r, ri+1, then shifts everything which in essence increments i by 1.
The extended Euclidean algorithm will be done the same way, saving two s values prevPrevS and prevS, and two t values prevPrevT and prevT. I'll let you work out the details.
Thank's for helping me out ajb I solved it after digging your answer. So for the people who would like to see code wise:
public class Main
{
public static void main (String args[])
{
#SuppressWarnings("resource")
System.out.println("How many times you would like to try ?")
Scanner read = new Scanner(System.in);
int len = read.nextInt();
for(int w = 0; w < len; w++)
{
System.out.print("Please give the numbers seperated by space: ")
read.nextLine();
long tmp = read.nextLong();
long m = read.nextLong();
long n;
if (m < tmp) {
n = m;
m = tmp;
}
else {
n = tmp;
}
long[] l1 = {m, 1, 0};
long[] l2 = {n, 0, 1};
long[] l3 = new long[3];
while (l1[0]-l2[0]*(l1[0]/l2[0]) > 0) {
for (int j=0;j<3;j++) l3[j] = l2[j];
long q = l1[0]/l2[0];
for (int i = 0; i < 3; i++) {
l2[i] = (l1[i]-l2[i]*q);
}
for (int k=0;k<3;k++) l1[k] = l3[k];
}
System.out.printf("%d %d %d",l2[1],l2[2],l2[0]); // first two Bezouts identity Last One gcd
}
}
}
Here is the code that I came up with if anyone is still looking. It is in C# but I am sure it similar to java. Enjoy
static void Main(string[] args)
{
List<long> U = new List<long>();
List<long> V = new List<long>();
List<long> W = new List<long>();
long a, b, d, x, y;
Console.Write("Enter value for a: ");
string firstInput = Console.ReadLine();
long.TryParse(firstInput, out a);
Console.Write("Enter value for b: ");
string secondInput = Console.ReadLine();
long.TryParse(secondInput, out b);
long temp;
//Make sure that a > b
if(a < b)
{
temp = a;
a = b;
b = temp;
}
//Initialise List U
U.Add(a);
U.Add(1);
U.Add(0);
//Initialise List V
V.Add(b);
V.Add(0);
V.Add(1);
while(V[0] > 0)
{
decimal difference = U[0] / V[0];
var roundedDown = Math.Floor(difference);
long rounded = Convert.ToInt64(roundedDown);
for (int i = 0; i < 3; i++)
W.Add(U[i] - rounded * V[i]);
U.Clear();
for (int i = 0; i < 3; i++)
U.Add(V[i]);
V.Clear();
for (int i = 0; i < 3; i++)
V.Add(W[i]);
W.Clear();
}
d = U[0];
x = U[1];
y = U[2];
Console.WriteLine("\nd = {0}, x = {1}, y = {2}", d, x, y);
//Check Equation
Console.WriteLine("\nEquation check: d = ax + by\n");
Console.WriteLine("\t{0} = {1}({2}) + {3}({4})", d, a, x, b, y);
Console.WriteLine("\t{0} = {1} + {2}", d, a*x, b*y);
Console.WriteLine("\t{0} = {1}", d, (a * x) + (b * y));
if (d == (a * x) + (b * y))
Console.WriteLine("\t***Equation is satisfied!***");
else
Console.WriteLine("\tEquation is NOT satisfied!");
}
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help with solving the second level of Google's Foobar challenge.
Commander Lambda uses an automated algorithm to assign minions randomly to tasks, in order to keep her minions on their toes. But you've noticed a flaw in the algorithm - it eventually loops back on itself, so that instead of assigning new minions as it iterates, it gets stuck in a cycle of values so that the same minions end up doing the same tasks over and over again. You think proving this to Commander Lambda will help you make a case for your next promotion.
You have worked out that the algorithm has the following process:
1) Start with a random minion ID n, which is a nonnegative integer of length k in base b
2) Define x and y as integers of length k. x has the digits of n in descending order, and y has the digits of n in ascending order
3) Define z = x - y. Add leading zeros to z to maintain length k if necessary
4) Assign n = z to get the next minion ID, and go back to step 2
For example, given minion ID n = 1211, k = 4, b = 10, then x = 2111, y = 1112 and z = 2111 - 1112 = 0999. Then the next minion ID will be n = 0999 and the algorithm iterates again: x = 9990, y = 0999 and z = 9990 - 0999 = 8991, and so on.
Depending on the values of n, k (derived from n), and b, at some point the algorithm reaches a cycle, such as by reaching a constant value. For example, starting with n = 210022, k = 6, b = 3, the algorithm will reach the cycle of values [210111, 122221, 102212] and it will stay in this cycle no matter how many times it continues iterating. Starting with n = 1211, the routine will reach the integer 6174, and since 7641 - 1467 is 6174, it will stay as that value no matter how many times it iterates.
Given a minion ID as a string n representing a nonnegative integer of length k in base b, where 2 <= k <= 9 and 2 <= b <= 10, write a function solution(n, b) which returns the length of the ending cycle of the algorithm above starting with n. For instance, in the example above, solution(210022, 3) would return 3, since iterating on 102212 would return to 210111 when done in base 3. If the algorithm reaches a constant, such as 0, then the length is 1.
Test Cases: Solution.solution("1211", 10) returns 1
Solution.solution("210022", 3) returns 3
Here is my code:
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public static int solution(String n, int b) {
int k = n.length();
String m = n;
ArrayList<String> minionID = new ArrayList<>();
while (!minionID.contains(m)) {
minionID.add(m);
char[] s = m.toCharArray();
Arrays.sort(s);
int y = Integer.parseInt(toString(s));
int x = Integer.parseInt(reverseString(s));
if (b == 10) {
int intM = x - y;
m = Integer.toString(intM);
} else {
int intM10 = ((int) Integer.parseInt(toBase10(x,b))) - ((int) Integer.parseInt(toBase10(y, b)));
m = toBaseN(intM10, b);
}
m = addLeadingZeros(k, m);
}
System.out.println(minionID);
return minionID.size() - minionID.indexOf(m);
}
private static String toBaseN (int intBase10, int b) {
int residual = intBase10;
ArrayList<String> digitsBaseN = new ArrayList<>();
while (residual >= b) {
int r = residual % b;
digitsBaseN.add(Integer.toString(residual));
residual = (residual - r) / b;
}
digitsBaseN.add(Integer.toString(residual));
StringBuilder reverseDigits = new StringBuilder();
for (int i = digitsBaseN.size() -1; i >= 0; i--) {
reverseDigits.append(digitsBaseN.get(i));
}
return reverseDigits.toString();
}
private static String toBase10 (int intBaseN, int b) {
int[] xArr = new int[Integer.toString(intBaseN).length()];
int count = 0;
for (int i = xArr.length - 1; i >= 0; i--) {
xArr[count] = Integer.toString(intBaseN).charAt(i) - '0';
count++;
}
int yBase10 = 0;
for(int i = 0; i < xArr.length; i++) {
yBase10 += xArr[i] * (Math.pow(b, i));
}
return Integer.toString(yBase10);
}
public static String toString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (char c : arr) {
newString.append(c);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(0);
}
return newString.toString();
}
public static String reverseString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (int i = arr.length - 1; i >= 0; i--) {
newString.append(arr[i]);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(newString.length()-1);
}
return newString.toString();
}
public static String addLeadingZeros(int k, String z) {
if (k > z.length()) {
String zeros = "";
for (int i = 0; i < (k - z.length()); i++) {
zeros += "0";
}
zeros += z;
return zeros;
}
return z;
}
It only works for three out of the ten test cases
def answer(n, b):
k = len(n)
m = n
mini_id = []
while m not in mini_id:
mini_id.append(m)
s = sorted(m)
x_descend = ''.join(s[::-1])
y_ascend = ''.join(s)
if b == 10:
int_m = int(x_descend) - int(y_ascend)
m = str(int_m)
else:
int_m_10 = int(to_base_10(x_descend, b)) - int(to_base_10(y_ascend, b))
m = to_base_n(str(int_m_10), b)
m = (k - len(m)) * '0' + m
return len(mini_id) - mini_id.index(m)
I need to write a code that gets 2 variables (n,k) and prints the answer to (2^n)%k.
I can use integers only, no methods, no arrays, no math. and so on.
so far i have this:
int n = myScanner.nextInt();
int k = myScanner.nextInt();
int num = 1;
int modulo = 1;
for (int i = 0; i < n; i++) {
num = num * 2;
modulo *= 2%k;
}
modulo = modulo%k;
System.out.println(modulo);
the problem is the range of the int itself, doesn't go more than 2^31... but still i need to make it work somehow, any help would be really appreciated!
You are dealing with Modular exponentiation. One possible solution is to avoid multiplication on large numbers, that will overflow the int, by taking advantage of below:
Given two integers a and b, the following two equations are equivalent:
c mod m = (a ⋅ b) mod m
c mod m = [(a mod m) ⋅ (b mod m)] mod m
In Java a simple solution based on algorithm explained in this section:
int mod(int base, int exponent, int modulus) {
if (modulus == 1) return 0;
int c = 1;
for (int i = 0; i < exponent; i++) {
c = (c * base) % modulus;
}
return c;
}
If your problem is that it can't store more than 2^31 it's because you need to use a long datatype to store the value. A long can store a maximum value of 2^63 (signed).
Task is to calculate expression for natural numbers entered.
I know I should calculate binominal coefficient here right?
Also I know that (-1)^p determines whether this array is decrementing or incrementing, but don't know how to use p in my code
I am not quite sure how to put it all together, this is what I came up with so far and it is really nothing special as I still can't grasp on the idea of how to write this in program.
public static int calculateExpression(int n, int k,int p) {
if(k<0 || n<k)
{
return 0;
}
// Find factorial of n
int n_fac = 1;
for (int j = 1; j <= n; j++) {
n_fac = n_fac * j;
}
// Find factorial of k
int k_fac = 1;
for(int i = 1; i<=k; i++) {
k_fac = k_fac * i;
}
// Find n-k fac
int n_k = n-k;
int n_k_fac = 1;
for(int l = 1; l<=n_k;l++) {
n_k_fac*=l;
}
// n/k = n!/k!(n-k)!
double resultOf_n_kDivision = n_fac/k_fac*n_k_fa;
System.out.println(resultOf_n_kDivision);
return n_k_fac;
}
The factorial function is a very fast-growing one, so calculating the numerator and denominator separately may not be a good idea, as it may lead to overflow for even relatively small values of n.
Let's look at an iterative method for calculating the coefficient:
We see that we can calculate the next coefficient of the row if we know the current one. Thus we can incrementally calculate each term in S, while being less concerned about overflow problems.
static int calculateExpression(int n, int k, int p)
{
// first term of the row is (n, 0) = 1
int binom = 1;
// Iteratively find (n, k)
for (int i = 0; i < k; i++)
binom = (binom * (n - i)) / (i + 1);
// sum the series
int S = binom;
for (int i = 0; i < p; i++) {
// "trick": multiply with a minus sign each time to flip the sign
binom = (-binom * (n - k - i)) / (k + i + 1);
S += binom;
}
return S;
}
UPDATE: Parallel numerical tests:
n k p | orig new
----------------------
5 3 2 | 6 6
10 4 1 | -42 -42
12 3 7 | 44 44
15 8 6 | 3433 8 // integer overflow occurred with the original method
As you can see the two functions were consistent until the last line with n = 15, as 15! = 1307674368000 is much bigger than the maximum positive value of int in most implementations of Java (32-bit).
Use abstraction for better tackling problems; define fac and over.
Then the problem becomes:
public static int calculateExpression(int n, int k,int p) {
int sum = 0;
int minus1toP = 1;
for (int i = 0; i <= p; i++) {
sum += minus1toP * over(n, ...);
minus1toP = -minus1toP;
}
return sum;
}
static int over(int n, int k) {
return fac(n) / fac(k) / fac(n - k);
}
static int fac(int n) {
int f = 1;
for(int i = 2; i <= n; i++) {
f *= i;
}
return f;
}
I did not give the entire solution (...), but maybe too much already.
I did not really get your question, but you can just use this.
public static double combination(int n, int k)
{
double nFactorial = getFactorialFromNToK(n, k);
double kFactorial = getFactorialFromNToK(k, 1);
return nFactorial / kFactorial;
}
public static double getFactorialFromNToK(double n, double k)
{
double factorial = 1;
for (; n - k + 1 > 0; n--)
{
factorial *= n;
}
return factorial;
}
This is the evaluation of nCk for the coef of a term in the binomial expansion.
If nCn is a term in the expansion, then it converges and if it does not exist as term in the expansion, then it will not converge. So if it is a natural number expansion, then it will always converge.
A better solution is to use the lngamma function instead of factorial. It's a more efficient way to calculate factorials. The natural log means that dividing large numbers will be less of a problem.
I had a problem where i had to calculate sum of large powers of numbers in an array and return the result.For example arr=[10,12,34,56] then output should be
10^1+12^2+34^3+56^4.Here the output could be very large so we were asked to take a mod of 10^10+11 on the output and then return it.I did it easily in python but in java initially i used BigInteger and got tle for half the test cases so i thought of using Long and then calculating power using modular exponential but then i got the wrong output to be precise all in negative as it obviously exceeded the limit.
Here is my code using Long and Modular exponential.
static long power(long x, long y, long p)
{
long res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if ((y & 1)==1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
static long solve(int[] a) {
// Write your code here
Long[] arr = new Long[a.length];
for (int i = 0; i < a.length; i++) {
arr[i] = setBits(new Long(a[i]));
}
Long Mod = new Long("10000000011");
Long c = new Long(0);
for (int i = 0; i < arr.length; i++) {
c += power(arr[i], new Long(i + 1),Mod) % Mod;
}
return c % Mod;
}
static long setBits(Long a) {
Long count = new Long(0);
while (a > 0) {
a &= (a - 1);
count++;
}
return count;
}
Then i also tried Binary Exponentiation but nothing worked for me.How do i achieve this without using big integer and as easily as i got it in python
You have added an extra zero the value of mod, it should be 1000000011.
Hope this will solve it
I'm working on a practice program at InterviewStreet and I have a solution that runs with a time of 5.15xx seconds, while the maximum time allowed for a java solution is 5 seconds. Is there anything I can do with what I've got here to get it under 5 seconds? There's also a limit of 256 MB so as near as I can tell this is both the most time and memory efficient solution to the problem...
edit:
The possible values for N and K are N <= 10^9 and K <= N, which is why I chose to do everything using BigInteger. The maximum number of trials is 10000. So basically, you input the number of trials, then a pair of integer values for each number of trials, and the program computes the three versions of the binomial coefficient for the equation in the second loop. I figured it would be faster to read everything into the arrays, then process the arrays and put the results into a third array to be processed by the third loop because I figured it might be faster that way. I tried doing everything in the same loop and it ran slower.
I've tried three or four different algorithms for calculating the binomial coefficient (nCr - or n choose r, all are different ways of saying the same thing). Some of the algorithms involve a two dimensional array like c[n][k]. This is the only solution I've submitted that didn't come back with some sort of memory error. The answer needs to be output mod (10 ^ 6) + 3 because the answers of nCr * nCr get pretty huge. A sample run of the program is:
3
4 1
5 2
90 13
2
5
815483
Can't run it on a faster machine because it needs to pass on their machine to count, basically I submit the code and they run it against their test cases, and I have no idea what their test case is, just that the inputs are within the bounds given above.
And the program itself:
import java.math.BigInteger;
import java.util.Scanner;
public class Solution {
public BigInteger nCr(int n, int r) {
if (r > n ) {
return BigInteger.ZERO;
}
if (r > n / 2) {
r = n - r;
}
BigInteger result = BigInteger.ONE;
for (int i = 0; i < r; i++) {
result = result.multiply(BigInteger.valueOf(n - i));
result = result.divide(BigInteger.valueOf(i + 1));
}
return result;
}
public static void main(String[] args) {
Scanner input = new Scanner( System.in );
BigInteger m = BigInteger.valueOf(1000003);
Solution p = new Solution();
short T = input.nextShort(); // Number of trials
BigInteger intermediate = BigInteger.ONE;
int[] r = new int[T];
int[] N = new int[T];
int[] K = new int[T];
short x = 0;
while (x < T) {
N[x] = input.nextInt();
K[x] = input.nextInt();
x++;
}
x = 0;
while (x < T) {
if (N[x] >= 3) {
r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
} else {
r[x] = 0;
}
x++;
}
x = 0;
while (x < T) {
System.out.println(r[x]);
x++;
}
}
}
Not entirely sure what the algorithm is trying to accomplish but I'm guessing something with binomial coefficients based on your tagging of the post.
You'll need to check if my suggestion modifies the result but it looks like you could merge two of your while loops:
Original:
while (x < T) {
N[x] = input.nextInt();
K[x] = input.nextInt();
x++;
}
x = 0;
while (x < T) {
if (N[x] >= 3) {
r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
} else {
r[x] = 0;
}
x++;
}
New:
x = 0;
while (x < T) {
//this has been moved from your first while loop
N[x] = input.nextInt();
K[x] = input.nextInt();
if (N[x] >= 3) {
r[x] = ((p.nCr(N[x] - 3, K[x]).multiply(p.nCr(N[x] + K[x], N[x] - 1))).divide(BigInteger.valueOf((N[x] + K[x]))).mod(m)).intValue();
} else {
r[x] = 0;
}
x++;
}
try to run using a profilerm for example the jvisualvm and run this class with
-Dcom.sun.management.jmxremote
attach to the process and start a profile.