UVA 369-Combinations | Modular Arithmetic | Binary Exponentiation [closed] - java

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 am trying to solve uVa's 369(Combinations) problem using Modular Arthimetic and Binary Exponentiation instead of just using BigInteger class in java. I am able to pass the last two base test cases but not the first test case. Can anybody explain where my code is wrong ?
public class Main {
static long M = 1000000007;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
String s = br.readLine();
s = s.trim();
s = s.replaceAll("\\s{2,}", " ");
String[] str = s.split(" ");
long n = Long.parseLong(str[0]);
long m = Long.parseLong(str[1]);
if(n == 0 && m == 0) break;
long a = fact(n); long b = fact((n-m) % M); long c = fact(m);
long d = (b*c) % M;
long ans = divide(a,d);
System.out.println(n + " things taken " + m + " at a time is " + ans + " exactly");
}
}
public static long fact(long N){
long ans = 1;
for(int i=1; i<=N; ++i)
ans = (ans * i) % M;
return ans;
}
public static long divide(long a, long b){
return a * pow(b,M-2) % M;
}
public static long pow(long a, long b){
long res = 1;
while(b > 0){
if(b % 2 == 1) res = (res*a) % M;
a = (a*a) % M;
b /=2;
}
return res;
}
}

M is too small. For example for the input 100 6, the correct result is 1192052400, but since your code works modulo 1000000007 the result will be 1192052400 mod 1000000007 = 192052393, which is much smaller (not just 7 smaller).
Using M = 0x7fffffff (also a prime) may work.

Related

How to solve java reverse integer leetcode problem

Tried all the ways to pass the test case but it still shows only one error. I do not know how to rectify the error.
Input: 1534236469
Actual Output: 1056389759
Expected Output: 0
I do not know why my code does not give output 0.
class Solution
{
public static int reverse(int x)
{
boolean flag = false;
if (x < 0)
{
x = 0 - x;
flag = true;
}
int res = 0;
int p = x;
while (p > 0)
{
int mod = p % 10;
p = p / 10;
res = res * 10 + mod;
}
if (res > Integer.MAX_VALUE)
{
return 0;
}
if (flag)
{
res = 0 - res;
}
return res;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int revinteger = reverse(x);
System.out.println(revinteger);
}
}
The statement res > Integer.MAX_VALUE will never be true as res is of int datatype. And an int can never be larger than the Integer.MAX_VALUE (MAX_VALUE is itself the max we can store as int).
Use long datatype for reversing the number instead and at the end return the integer value of the result.
Because long based operations are relatively slow, I would only use a long to do the final check to determine if overflow is about to occur.
It should be obvious that no int will cause overflow if all the digits except the last are reversed. So process the last digit outside of the loop before returning the value. The border case for min is eliminated first to facilitate subsequent processing. Now only Integer.MAX_VALUE is of concern for both positive and negative numbers.
public static int reverse(int v) {
if (v == Integer.MIN_VALUE) {
return 0; // guaranteed overflow if reversed.
}
int rev = 0;
long ovflLimit = Integer.MAX_VALUE;
int sign = v < 0 ? -1 : 1;
v *=sign;
while (v > 9) {
int digit = v % 10;
rev = rev * 10 + digit;
v/=10;
}
long ovfl = (long)(rev)*10+v;
return ovfl > ovflLimit ? 0 : (int)(ovfl)*sign;
}
This problem can be solved in various ways but if we stick to Java and your solution then as it already have been pointed out in some of the answers that by using int the condition if(res > Integer.MAX_VALUE) will never be true.
Hence you would not get expected output as 0.
You can put a check before reversing last digit by casting the value in long and check if it's out of int limit. As suggested by WJS.
In case you want to stick to your solution without much change below is the working code for the same.
class Solution {
public static int reverse(int x) {
boolean flag = false;
long input = x;
if (input < 0) {
input = 0 - input;
flag = true;
}
long res = 0;
long p = input;
while (p > 0) {
long mod = p % 10;
p = p / 10;
res = res * 10 + mod;
}
if (res > Integer.MAX_VALUE) {
return 0;
}
if (flag) {
res = 0 - res;
}
return (int) res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int revInteger = reverse(x);
System.out.println(revInteger);
}
}
if (res > Integer.MAX_VALUE)
If it's the max possible value of the integer, how will it ever be greater than it? You'll have to detect it in another way.
One way would be to use the long data type instead of int. Then, it can become larger than Integer.MAX_VALUE, and that catch will work.
Otherwise, you can probably find another way to catch that case.

I am working with fibonacci numbers, where the "n" for the n-th number is in 5-6 digits. how can i reduce the time taken for execution? [closed]

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
In this specific problem, what I had to do is find the Fibonacci numbers, square them, and then find the sum of those squared numbers. Which was fine up until the range limit of the long data type.
Here's what I've got till now... I switched to BigInteger after noticing that the range of long couldn't handle the large Fibonacci numbers, and that did the trick but increased the time complexity exponentially. And since I needed to retain most of the numbers, I needed to make an array for the numbers to store them.
import java.util.*;
import java.math.*;
public class FibonacciSumSquares {
private static BigInteger getFibonacciSumSquares(int n) {
if (n <= 1)
return BigInteger.valueOf(n);
BigInteger sum = BigInteger.valueOf(0);
BigInteger a[] = new BigInteger[n];
a[0] = a[1] = BigInteger.ONE;
for (int i = 2; i < n; i++) {
a[i] = a[i - 1].add(a[i - 2]);
a[i] = a[i].pow(2);
sum = sum.add(a[i]);
}
return sum;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println(getFibonacciSumSquares(n));
}
}
After accepting the first answer I ran some stress tests on the code snippet and the correction that was needed was an "=" sign in the code. hope that helps. For more details please refer to the answer's comments.
BigInteger runs more slower than java primitive types, so use primitive in long range.
here is my code and result:
public class FibonacciSumSquares {
private static BigInteger getFibonacciSumSquares(int n) {
if (n <= 1)
return BigInteger.valueOf(n);
BigInteger sum = BigInteger.ZERO;
long last = 1, lastTwo = 1, current = 0;
BigInteger lastBigInteger = BigInteger.ONE;
BigInteger lastTwoBigInteger = BigInteger.ONE;
BigInteger currentBigInteger;
boolean isUsePrimary = true;
for (int i = 2; i <= n; i++) {
if (isUsePrimary) {
current = last + lastTwo;
current = current * current;
if (current > (last + lastTwo)) {
lastTwo = last;
last = current;
sum = sum.add(BigInteger.valueOf(current));
} else {
isUsePrimary = false;
lastTwoBigInteger = BigInteger.valueOf(lastTwo);
lastBigInteger = BigInteger.valueOf(last);
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
} else {
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
}
return sum;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(getFibonacciSumSquares(10000));
System.out.println("used time(ms): " + (System.currentTimeMillis() - start));
/**
* On: MacBook Pro (Retina, 15-inch, Mid 2014)
*
* n = 10000
* 811453295998950457153326378602357232029212
* used time(ms): 24
*
* n = 20000
* 1623556274380606238932066737816445867589212
* used time(ms): 32
*
* n = 999999
* 81209566945485034687670444066761210743605656
* used time(ms): 368
*/
}
}

Fastest Way To Reverse Long Java [duplicate]

This question already has answers here:
Reverse a string in Java
(36 answers)
how to reverse an inputted number [duplicate]
(3 answers)
Closed 2 years ago.
What's the fastest way to reverse a Long value?
For example, 9876543210 should return 0123456789.
This is what I have right now:
long n = 0, c = 987654321 * 10; // *10 is to get 9876543210 as long value;
while (c > 0) n = n * 10 + c % 10;
System.out.println(n);
Your program encounters an infinite loop because you never change the value of c. Add c /= 10 at the end of each iteration and it will work, albeit the leading zero will be dropped due to it being a number.
long n = 0, c = 9876543210L;
while (c > 0){
n = n * 10 + c % 10;
c /= 10;
}
System.out.println(n);
If you need to have the leading zero, you should consider using Strings instead.
long c = 9876543210L;
final StringBuilder sb = new StringBuilder();
while (c > 0){
sb.append(c % 10);
c /= 10;
}
System.out.println(sb.toString());
I think this can be fast
long x = 1234567890L;
String reversed = new StringBuilder(Long.toString(x)).reverse().toString();
// reversed = "0987654321"
If You want to convert a reversed value to a long again:
long x = -1234567890000L;
StringBuilder reversed = new StringBuilder(Long.toString(x)).reverse();
System.out.println(reversed); // 0000987654321-
if (reversed.charAt(reversed.length() - 1) == '-') //remove `-` at last position
{
reversed.setLength(reversed.length() - 1);
}
while (reversed.charAt(0) == '0') //remove all `0` at the beginning
{
reversed.replace(0, 1, "");
}
System.out.println(reversed); // 987654321
long newLong = Long.parseLong(reversed.toString());
You can simply convert to string and then revert the String, in particular if you want string output in the end anyway. This should be quite straight forward and it has the leading 0, it might also be faster than doing calculations for each positions (but the cost of conversion in valueOf might cancel that advantage):
long c = 9876543210L;
String cAsString = String.valueOf(c);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
System.out.println(builder.toString());
or as a one liner
long c = 9876543210L;
String reverted = new StringBuilder(String.valueOf(c)).reverse().toString();
System.out.println(reverted);
I did a little comparison between the options of the current answers:
public static void main(String[] args) {
Instant start = Instant.now();
for (long i = 0; i < 100_000_000; i++) {
stringbuilderWithDirectCalcs(i);
}
Duration duration = Duration.between(start, Instant.now());
System.out.println("Took " + duration);
}
protected static void stringbuilderWithDirectCalcs(long value) {
final StringBuilder sb = new StringBuilder();
while (value > 0) {
sb.append(value % 10);
value /= 10;
}
// System.out.println(sb.toString());
}
protected static void stringbuilderConvenient(long value) {
String reverted = new StringBuilder(String.valueOf(value)).reverse().toString();
//System.out.println(reverted);
}
protected static void stringbuilderHandCrafted(long value) {
String cAsString = String.valueOf(value);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cAsString.length(); i++) {
builder.append(cAsString.substring(cAsString.length() - (i + 1), cAsString.length() - i));
}
//System.out.println(builder.toString());
}
I did three runs each. The outcome:
stringbuilderConvenient
Took PT6.988S / Took PT6.8S / Took PT6.68S
stringbuilderWithDirectCalcs:
Took PT6.17S / Took PT6.776S / Took PT6.692S
stringbuilderHandCrafted
Took PT18.205S / Took PT16.035S / Took PT17.025S
So, scanning the String by hand and sticking the StringBuilder together step by step seems out of the question. Obviously Stephen C was right in his comment that the calculations happen anyway when converting to String. But the approach based on Stringbuilder.reverse and handcalculating each position are pretty close (and any difference might be due to minor runtime fluctuations). So, one might choose the StringBuilder.reverse method over calculating each position by hand for readability with about the same performance.

How can I get my program to return -1/4 and NOT 1/-4? [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
\Help! My homework is due by 12am tonight and I can't seem to get my program to output a negative number as -1/4 rather than 1/-4! It's frustrating me because the thing is, I cannot just place a "-" in front of my numbers (which as you can see in my program below, I have commented out).
My attempt at getting fraction to be -1/4 (just using this fraction as an example) is under the "public RationalNumber(int...) { line: you see the part where I have *-1 written? Where did I go wrong in that step that led me to get 1/-4? This is frustrating me... Thanks in advance.
private int n;
private int d;
public RationalNumber(int numerator, int denominator) {
if (denominator == 0) {
throw new IllegalArgumentException();
}
if (denominator < 0) {
denominator = denominator * -1;
numerator = numerator * -1;
}
n = numerator;
d = denominator;
simplified();
}
public RationalNumber add(RationalNumber rn) {
int comDenom = d * rn.getDenominator();
int num1 = n * rn.d;
int num2 = rn.n * d;
d = comDenom;
return new RationalNumber(num1 + num2, d);
}
public RationalNumber subtract(RationalNumber rn) {
int num1 = n * rn.d;
int num2 = rn.n * d;
return new RationalNumber(num1 - num2, d);
}
public RationalNumber multiply(RationalNumber rn) {
int numer = n * rn.n;
int denom = d * rn.d;
return new RationalNumber(numer, denom);
}
public RationalNumber divide(RationalNumber rn) {
int numer = n * rn.d;
int denom = d * rn.n;
return new RationalNumber(numer, denom);
}
public RationalNumber() {
n = 0;
d = 1;
}
public boolean equals(RationalNumber o) {
return (n == o.getNumerator() && d == o.getDenominator());
}
public int getDenominator() {
return d;
}
public int getNumerator() {
return n;
}
public String toString() { //Prints everything here.
if (d == 1) {
return "" + n;
}
if (n == 0) {
return "0";
}
/*if ((n < 0) || (d < 0)) {
return "-" + Math.abs(n) + "/" + Math.abs(d);
}*/
return n + "/" + d;
}
private void simplified() {
if (n != 0) {
int cDenom = gcd(n, d);
n = n / cDenom;
d = d / cDenom;
}
}
private int gcd(int gcdNum1, int gcdNum2) {
while (gcdNum1 != 0 && gcdNum2 != 0) {
int tempNum = gcdNum2;
gcdNum2 = gcdNum1 % gcdNum2;
gcdNum1 = tempNum;
}
return gcdNum1 + gcdNum2;
}
Because this is homework, it is in your best interest to find and fix the problem yourself.
Here are a couple of hints to get you started:
Figure out what the values of n and d are before and after the constructor calls simplified().
You could do this with your Java IDE's debugger, or by using trace prints; i.e. calls to System.out.println(...)
You could put back in the commented out section of your toString method, just make it an XOR (^) rather than OR (||)
The problem is that the gcd() method may return a negative result. When you call the simplified() method, you divide n and c with a possibly negative number, and you change their sign. To fix it, you can change the gcd() method to return always a positive result.
Change this line:
return gcdNum1 + gcdNum2;
to
if (gcdNum1 + gcdNum2 < 0) {
return -(gcdNum1 + gcdNum2);
} else {
return gcdNum1 + gcdNum2;
}
And then check if you get the correct results.
return n + "/" + d;
Change to:
return ((n>=0 && d>=0) || (n<0 && d<0))?(""):("-")+Math.abs(n)+"/"+Math.abs(d);
Just a simple work around.

Sum of the digits of the number 2^1000 [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2 power of 1000 (2^1000)?
Can anyone provide the solution or algorithm for this problem in java?
Here is my solution:
public static void main(String[] args) {
ArrayList<Integer> n = myPow(2, 100);
int result = 0;
for (Integer i : n) {
result += i;
}
System.out.println(result);
}
public static ArrayList<Integer> myPow(int n, int p) {
ArrayList<Integer> nl = new ArrayList<Integer>();
for (char c : Integer.toString(n).toCharArray()) {
nl.add(c - 48);
}
for (int i = 1; i < p; i++) {
nl = mySum(nl, nl);
}
return nl;
}
public static ArrayList<Integer> mySum(ArrayList<Integer> n1, ArrayList<Integer> n2) {
ArrayList<Integer> result = new ArrayList<Integer>();
int carry = 0;
int max = Math.max(n1.size(), n2.size());
if (n1.size() != max)
n1 = normalizeList(n1, max);
if (n2.size() != max)
n2 = normalizeList(n2, max);
for (int i = max - 1; i >= 0; i--) {
int n = n1.get(i) + n2.get(i) + carry;
carry = 0;
if (n > 9) {
String s = Integer.toString(n);
carry = s.charAt(0) - 48;
result.add(0, s.charAt(s.length() - 1) - 48);
} else
result.add(0, n);
}
if (carry != 0)
result.add(0, carry);
return result;
}
public static ArrayList<Integer> normalizeList(ArrayList<Integer> l, int max) {
int newSize = max - l.size();
for (int i = 0; i < newSize; i++) {
l.add(0, 0);
}
return l;
}
This code can be improved in many ways ... it was just to prove you can perfectly do it without BigInts.
The catch is to transform each number to a list. That way you can do basic sums like:
123456
+ 45
______
123501
int result = 0;
String val = BigInteger.valueOf(2).pow(1000).toString();
for(char a : val.toCharArray()){
result = result + Character.getNumericValue(a);
}
System.out.println("val ==>" + result);
It's pretty simple if you know how to use the biginteger.
I won't provide code, but java.math.BigInteger should make this trivial.
This problem is not simply asking you how to find the nearest big integer library, so I'd avoid that solution. This page has a good overview of this particular problem.
Create a vector of length 302, which is the length of 2^1000. Then, save 2 at index 0, then, double 1000 times. Just look at every index separetly and add 1 to the next index if the previous exeeds 10. Then just sum it up!
something like that sould do it bute force: - although there is a nice analytic solution (think pen& paper) using mathematics - that may also work for numbers greater than 1000.
final String bignumber = BigInteger.valueOf(2).pow(1000).toString(10);
long result = 0;
for (int i = 0; i < bignumber.length(); i++) {
result += Integer.valueOf(String.valueOf(bignumber.charAt(i)));
}
System.out.println("result: " + result);
How can 2^1000 be alternatively expressed?
I don't remember much from my maths days, but perhaps something like (2^(2^500))? And how can that be expressed?
Find an easy way to calculate 2^1000, put the result in a BigInteger, and the rest is perhaps trivial.
Here is my code... Please provide the necessary arguments to run this code.
import java.math.BigInteger;
public class Question1 {
private static int SumOfDigits(BigInteger inputDigit) {
int sum = 0;
while(inputDigit.bitLength() > 0) {
sum += inputDigit.remainder(new BigInteger("10")).intValue();
inputDigit = inputDigit.divide(new BigInteger("10"));
}
return sum;
}
public static void main(String[] args) {
BigInteger baseNumber = new BigInteger(args[0]);
int powerNumber = Integer.parseInt(args[1]);
BigInteger powerResult = baseNumber.pow(powerNumber);
System.out.println(baseNumber + "^" + powerNumber + " = " + powerResult);
System.out.println("Sum of Digits = " + Question1.SumOfDigits(powerResult));
}
}
2^1000 is a very large value, you would have to use BigIntegers. The algorithm would be something like:
import java.math.BigInteger;
BigInteger two = new BigInteger("2");
BigInteger value = two.pow(1000);
int sum = 0;
while (value > 0) {
sum += value.remainder(new BigInteger("10"));
value = value.divide(new BigInteger("10"));
}
Alternatively, you could grab a double and manipulate its bits. With numbers that are the power of 2, you won't have truncation errors. Then you can convert it to string.
Having that said, it's still a brute-force approach. There must be a nice, mathematical way to make it without actually generating a number.
In[1162] := Plus ## IntegerDigits[2^1000]
Out[1162] = 1366

Categories