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
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
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
*/
}
}
I am here again at my wits end wrestling with Project Euler Problem 12. It asks for the first triangle number to have over 500 divisors. https://projecteuler.net/problem=12
Here is my previous attempt:
Project Euler 12, Java solution attempt, recursion error?
I received many great pointers which I diligently tried to apply.
Thanks to your replies, now I can: sieve prime numbers up to a very high value and do prime factorization of any number and count the divisors.
But I just can't tie these techniques with the problem of finding the triangle number with 500 divisors. So I have sieved the primes up to a large number, then what should I do? I factorized any number and counted its divisors, then how do I use this to solve the problem?
I went back to my old trial solution and cleaned up the code. Now it can find triangle numbers with low divisor count. But up to 500, the compiler keeps on running.
Here is my cleaned up solution:
public static void main(String[] args) {
long c=2;
long d=(c*(c+1)/2);
while (numDivs(d)<=500) {
c++;
d=(c*(c+1)/2);
}
System.out.println(d);
System.out.println(c);
}
public static long numDivs(long a) {
long foo=2;
for (long b=1;b*2<=a;b++ ) {
if (a%b==0)
foo++;
}
return foo;
}
Is there any way I can speed up this process? Or should I just give up on this solution?
Thanks for reading and I will appreciate all the input.
I think the first thing, one can do, is count the number of divisors twice as fast, simply by cutting at sqrt of the number:
public static long numDivs(long a) {
if(a == 1)
return 1;
long num = 2;
int sqrt = (int) Math.sqrt(a);
if(sqrt*sqrt == a) {
num++;
}
for (long b = 2;b < sqrt; b++) {
if (a%b == 0) {
num += 2;
}
}
return num;
}
Rationale: if the dividor is larger than the square root of the number, it has a co-dividor who is less, instead of counting them separately, you can count them both at once.
This definitely has an impact because numDivs will now have a timecomplexity O(sqrt n) instead of O(n).
I think the algorithm you're trying to apply is quite naive.
Check my code, which uses, I think, better approach.
Finding Primes
private static List<Integer> sieve(int maxPrime) {
boolean[] isPrime = new boolean[maxPrime];
List<Integer> primes = new ArrayList<>();
Arrays.fill(isPrime, true);
for (int i = 2; i * i < maxPrime; i++) {
if (isPrime[i]) {
primes.add(i);
for (int j = i; i * j < maxPrime; j++) isPrime[i * j] = false;
}
}
return primes;
}
Factorization
Here we get a map, where key is the factor, and value is the number of times it occurs.
private static Map<Integer, Integer> factorize(List<Integer> primes, int number) {
Map<Integer, Integer> factors = new HashMap<>();
int tempNumber = number;
for (Integer prime : primes) {
while (tempNumber % prime == 0) {
tempNumber = tempNumber / prime;
if (factors.containsKey(prime)) factors.put(prime, factors.get(prime) + 1);
else factors.put(prime, 1);
}
}
return factors;
}
Counting Divisors
private static int countDivisors(Map<Integer, Integer> factors) {
int result = 1;
for (Integer c : factors.values()) {
result *= c + 1;
}
return result;
}
The execution
public static void main(String[] args) {
final int MAX_PRIME = (int) Math.sqrt(Integer.MAX_VALUE);
List<Integer> primes = sieve(MAX_PRIME);
int triangularNumber = 0;
for (int i = 1; i < Integer.MAX_VALUE; i++) {
triangularNumber += i;
Map<Integer, Integer> factors = factorize(primes, triangularNumber);
int total = countDivisors(factors);
if (total > 500) {
break;
}
}
System.out.println("The number " + triangularNumber);
}
You don't have to calculate the triangle number anew each time, you can just add on c as
T(n) = T(n-1) + n
so code wise
long c=2;
long d=(c*(c+1)/2);
while (numDivs(d)<=500) {
c++;
d += c;
}
which should hopefully cut down on the time taken
I've recently been given question for uni that is in regards to a credit card statement which says i have a string of numbers, then i convert these numbers to separate integers then i increment them by the power of 10 depending on their position in the string using horners method
i then have to add the values i get from the loop to make 1 whole integer.
I Know this is an odd way to convert a string to an int but my assignment states that i have to use horners method to convert the string rather than use the inbuilt java classes/methods
My question is, How can i add the separate weighted numbers and concatenate them into one single number.
If it helps an example would be,
Given a card number 1234, the number is weighted according to its position and length so:
1 - 1000
2 - 200
3 - 30
4 - 4
Then these are added to create a whole number
1, 2, 3,4 ---> 1234
Here is my code thus far
public static long toInt(String digitString) {
long answer = 0;
long val = 0;
String s = "";
for (int j = 0; j < digitString.length(); j++) {
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
System.out.println(val);
}
return answer;
}
Most probably I am not following you, because this sounds too simple.
But to return a long (or integer) all you have to do is to sum these numbers:
public static long toLong(String digitString) {
long answer = 0;
long val = 0;
for (int j = 0; j < digitString.length(); j++) {
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
answer += val; // here! :)
//System.out.println(val);
}
return answer;
}
Please note that this is not going to work with negative numbers, so here is a more complex version:
public static long toLong(String digitString) {
long answer = 0;
long val = 0;
boolean negative = false;
int j = 0;
if (digitString.charAt(0) == '-') {
negative = true;
j = 1;
} else if (digitString.charAt(0) == '+')
j = 1;
for (; j < digitString.length(); j++) {
if (!Character.isDigit(digitString.charAt(j)))
throw new NumberFormatException(digitString);
val = digitString.charAt(j) - '0';
val = (long) (val * Math.pow(10, (digitString.length() - 1) - j));
answer += val;
}
return negative ? -answer : answer;
}
This code will work with negative numbers and with weird numbers that start with a + sign as well. If there is any other character, it will throw an exception.
I think your code is not Object-Oriented and really hard to read and understand.
Basic, the problem is a mapping and really simple.
If you are writing code in Java, better to use in OO way, though I don't like java very much.
Checkout my code
#Test
public void testCardScoreSystem() {
Map<String, String> scoreMapping = new HashMap<String, String>();
scoreMapping.put("1", "1000");
scoreMapping.put("2", "200");
scoreMapping.put("3", "30");
scoreMapping.put("4", "4");
String[] input = {"1", "2", "3", "4"};
long score = 0;
for (String str : input) {
String mappedValue = scoreMapping.get(str);
if (mappedValue == null) {
throw new RuntimeException("Hey dude, there is no such score mapping system! " + str);
}
score += Long.valueOf(mappedValue);
}
System.out.println(score);
}
I am trying to create a program that will tell if a number given to it is a "Happy Number" or not. Finding a happy number requires each digit in the number to be squared, and the result of each digit's square to be added together.
In Python, you could use something like this:
SQUARE[d] for d in str(n)
But I can't find how to iterate through each digit in a number in Java. As you can tell, I am new to it, and can't find an answer in the Java docs.
You can use a modulo 10 operation to get the rightmost number and then divide the number by 10 to get the next number.
long addSquaresOfDigits(int number) {
long result = 0;
int tmp = 0;
while(number > 0) {
tmp = number % 10;
result += tmp * tmp;
number /= 10;
}
return result;
}
You could also put it in a string and turn that into a char array and iterate through it doing something like Math.pow(charArray[i] - '0', 2.0);
Assuming the number is an integer to begin with:
int num = 56;
String strNum = "" + num;
int strLength = strNum.length();
int sum = 0;
for (int i = 0; i < strLength; ++i) {
int digit = Integer.parseInt(strNum.charAt(i));
sum += (digit * digit);
}
I wondered which method would be quickest to split up a positive number into its digits in Java, String vs modulo
public static ArrayList<Integer> splitViaString(long number) {
ArrayList<Integer> result = new ArrayList<>();
String s = Long.toString(number);
for (int i = 0; i < s.length(); i++) {
result.add(s.charAt(i) - '0');
}
return result; // MSD at start of list
}
vs
public static ArrayList<Integer> splitViaModulo(long number) {
ArrayList<Integer> result = new ArrayList<>();
while (number > 0) {
int digit = (int) (number % 10);
result.add(digit);
number /= 10;
}
return result; // LSD at start of list
}
Testing each method by passing Long.MAX_VALUE 10,000,000 times, the string version took 2.090 seconds and the modulo version 2.334 seconds. (Oracle Java 8 on 64bit Ubuntu running in Eclipse Neon)
So not a lot in it really, but I was a bit surprised that String was faster
In the above example we can use:
int digit = Character.getNumericValue(strNum.charAt(i));
instead of
int digit = Integer.parseInt(strNum.charAt(i));
You can turn the integer into a string and iterate through each char in the string. As you do that turn that char into an integer
This code returns the first number (after 1) that fits your description.
public static void main(String[] args) {
int i=2;
// starting the search at 2, since 1 is also a happy number
while(true) {
int sum=0;
for(char ch:(i+"").toCharArray()) { // casting to string and looping through the characters.
int j=Character.getNumericValue(ch);
// getting the numeric value of the current char.
sum+=Math.pow(j, j);
// adding the current digit raised to the power of itself to the sum.
}
if(sum==i) {
// if the sum is equal to the initial number
// we have found a number that fits and exit.
System.out.println("found: "+i);
break;
}
// otherwise we keep on searching
i++;
}
}
I'm trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the factorial of the number, and count the trailing zeros. However, when the number is about as large as 25!, numZeros don't work.
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
double fact;
int answer;
try {
int number = Integer.parseInt(br.readLine());
fact = factorial(number);
answer = numZeros(fact);
}
catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static double factorial (int num) {
double total = 1;
for (int i = 1; i <= num; i++) {
total *= i;
}
return total;
}
public static int numZeros (double num) {
int count = 0;
int last = 0;
while (last == 0) {
last = (int) (num % 10);
num = num / 10;
count++;
}
return count-1;
}
I am not worrying about the efficiency of this code, and I know that there are multiple ways to make the efficiency of this code BETTER. What I'm trying to figure out is why the counting trailing zeros of numbers that are greater than 25! is not working.
Any ideas?
Your task is not to compute the factorial but the number of zeroes. A good solution uses the formula from http://en.wikipedia.org/wiki/Trailing_zeros (which you can try to prove)
def zeroes(n):
i = 1
result = 0
while n >= i:
i *= 5
result += n/i # (taking floor, just like Python or Java does)
return result
Hope you can translate this to Java. This simply computes [n / 5] + [n / 25] + [n / 125] + [n / 625] + ... and stops when the divisor gets larger than n.
DON'T use BigIntegers. This is a bozosort. Such solutions require seconds of time for large numbers.
You only really need to know how many 2s and 5s there are in the product. If you're counting trailing zeroes, then you're actually counting "How many times does ten divide this number?". if you represent n! as q*(2^a)*(5^b) where q is not divisible by 2 or 5. Then just taking the minimum of a and b in the second expression will give you how many times 10 divides the number. Actually doing the multiplication is overkill.
Edit: Counting the twos is also overkill, so you only really need the fives.
And for some python, I think this should work:
def countFives(n):
fives = 0
m = 5
while m <= n:
fives = fives + (n/m)
m = m*5
return fives
The double type has limited precision, so if the numbers you are working with get too big the double will be only an approximation. To work around this you can use something like BigInteger to make it work for arbitrarily large integers.
You can use a DecimalFormat to format big numbers. If you format your number this way you get the number in scientific notation then every number will be like 1.4567E7 this will make your work much easier. Because the number after the E - the number of characters behind the . are the number of trailing zeros I think.
I don't know if this is the exact pattern needed. You can see how to form the patterns here
DecimalFormat formater = new DecimalFormat("0.###E0");
My 2 cents: avoid to work with double since they are error-prone. A better datatype in this case is BigInteger, and here there is a small method that will help you:
public class CountTrailingZeroes {
public int countTrailingZeroes(double number) {
return countTrailingZeroes(String.format("%.0f", number));
}
public int countTrailingZeroes(String number) {
int c = 0;
int i = number.length() - 1;
while (number.charAt(i) == '0') {
i--;
c++;
}
return c;
}
#Test
public void $128() {
assertEquals(0, countTrailingZeroes("128"));
}
#Test
public void $120() {
assertEquals(1, countTrailingZeroes("120"));
}
#Test
public void $1200() {
assertEquals(2, countTrailingZeroes("1200"));
}
#Test
public void $12000() {
assertEquals(3, countTrailingZeroes("12000"));
}
#Test
public void $120000() {
assertEquals(4, countTrailingZeroes("120000"));
}
#Test
public void $102350000() {
assertEquals(4, countTrailingZeroes("102350000"));
}
#Test
public void $1023500000() {
assertEquals(5, countTrailingZeroes(1023500000.0));
}
}
This is how I made it, but with bigger > 25 factorial the long capacity is not enough and should be used the class Biginteger, with witch I am not familiar yet:)
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number : ");
long number = in.nextLong();
long numFactorial = 1;
for(long i = 1; i <= number; i++) {
numFactorial *= i;
}
long result = 0;
int divider = 5;
for( divider =5; (numFactorial % divider) == 0; divider*=5) {
result += 1;
}
System.out.println("Factorial of n is: " + numFactorial);
System.out.println("The number contains " + result + " zeroes at its end.");
in.close();
}
}
The best with logarithmic time complexity is the following:
public int trailingZeroes(int n) {
if (n < 0)
return -1;
int count = 0;
for (long i = 5; n / i >= 1; i *= 5) {
count += n / i;
}
return count;
}
shamelessly copied from http://www.programcreek.com/2014/04/leetcode-factorial-trailing-zeroes-java/
I had the same issue to solve in Javascript, and I solved it like:
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count) // console shows 4
This solution gives you the number of trailing zeros.
var number = 1000010000;
var str = (number + '').split(''); //convert to string
var i = str.length - 1; // start from the right side of the array
var count = 0; //var where to leave result
for (;i>0 && str[i] === '0';i--){
count++;
}
console.log(count)
Java's doubles max out at a bit over 9 * 10 ^ 18 where as 25! is 1.5 * 10 ^ 25. If you want to be able to have factorials that high you might want to use BigInteger (similar to BigDecimal but doesn't do decimals).
I wrote this up real quick, I think it solves your problem accurately. I used the BigInteger class to avoid that cast from double to integer, which could be causing you problems. I tested it on several large numbers over 25, such as 101, which accurately returned 24 zeros.
The idea behind the method is that if you take 25! then the first calculation is 25 * 24 = 600, so you can knock two zeros off immediately and then do 6 * 23 = 138. So it calculates the factorial removing zeros as it goes.
public static int count(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
int zeroCount = 0;
BigInteger mult = new BigInteger("1");
while (number > 0) {
mult = mult.multiply(new BigInteger(Integer.toString(number)));
while (mult.mod(ten).compareTo(zero) == 0){
mult = mult.divide(ten);
zeroCount += 1;
}
number -= 1;
}
return zeroCount;
}
Since you said you don't care about run time at all (not that my first was particularly efficient, just slightly more so) this one just does the factorial and then counts the zeros, so it's cenceptually simpler:
public static BigInteger factorial(int number) {
BigInteger ans = new BigInteger("1");
while (number > 0) {
ans = ans.multiply(new BigInteger(Integer.toString(number)));
number -= 1;
}
return ans;
}
public static int countZeros(int number) {
final BigInteger zero = new BigInteger("0");
final BigInteger ten = new BigInteger("10");
BigInteger fact = factorial(number);
int zeroCount = 0;
while (fact.mod(ten).compareTo(zero) == 0){
fact = fact.divide(ten);
zeroCount += 1;
}
}