Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000
I'm using Java.. I think I can modpow function for this question. (BigInteger) Here is my Java code but it isnt work. How can I do that?
public static void main(String[] args) {
BigInteger a;
BigInteger b = null;
BigInteger c = new BigInteger("10000000000");
for (int i = 0; i <= 1000; i++) {
a = new BigInteger("" + i);
b.add(a.modPow(a, c));
}
System.out.println(b);
}
I get the error of NullPointerException.. Sorry my english, thanks.
BigInteger b = null;
therefore, in the first iteration, when you do b.add(a.modPow(a, c));, b is null
I think you have two basic errors, first you never initialized b - that could be
BigInteger b = BigInteger.ZERO;
Then you need to assign the result of the b.add(a.modPow(a, c)); to b (since BigInteger add doesn't modify in-place). That is,
b = b.add(a.modPow(a, c));
When I make those two changes I get the output
4629110846701
import java.math.BigInteger;
class Main {
public static void main(String[] args) {
BigInteger num = BigInteger.ZERO;
for (int i = 1; i <= 1000; i++) {
num = num.add(BigInteger.valueOf(i).pow(i));
}
BigInteger res = num.mod(new BigInteger("10000000000"));
System.out.println(res);
}
}
output :
9110846700
More efficient solution taken from http://www.mathblog.dk/project-euler-48-last-ten-digits/ as biginteger gets very slow on very large numbers
import java.io.InputStream;
class Main {
public static void main(String[] args) {
long result = 0;
long modulo = 10000000000L;
for (int i = 1; i <= 1000; i++) {
long temp = i;
for (int j = 1; j < i; j++) {
temp *= i;
temp %= modulo;
}
result += temp;
result %= modulo;
}
System.out.println(result);
}
output :
9110846700
null is not a zero value. Initialize your variable with 0 like this
BigInteger b = new BigInteger("0");
Even if, as peter.petrov said, this problem could be solved with one more simple solution without using big integers
Related
The problem below was given in one of my exams and was asked to solve the following problem using Java only.
The problem is, I got stuck in the part where the program is supposed to return the given non-negative integer as an array of digits. Can anyone provide a solution to this?
Thanks in advance.
Two positive numbers A and B are said to be connected (denoted by "A ↔ B") if one of these conditions holds:
(1) A and B have the same length and differ in exactly one digit; for example, 123 ↔ 173.
(2) Adding one digit to the left of A (or B) makes B (or A); for example, 23 ↔ 223 and 123 ↔ 23.
We call a prime P a 2's relative if there exists a chain of connected primes between 2 and P and no prime in the chain exceeds P.
For example, 127 is a 2's relative. One of the possible chains is shown below:
2 ↔ 3 ↔ 13 ↔ 113 ↔ 103 ↔ 107 ↔ 127
However, 11 and 103 are not 2's relatives.
Let F(N) be the sum of the primes ≤ N which are not 2's relatives.
We can verify that F(103) = 431 and F(104) = 78728.
Find F(107).
Edited: my part
I am sorry I don't carbon copy remember my solution as I don't have my results given to me. But just for the sake of this question, I think the part where it was supposed to return non-negative number, I had something like this -
private static int[] toDigits(int n) {
if (n < 0)
throw new IllegalArgumentException();
int[] temp = new int[10];
int len = 0;
do {
temp[len] = n % 9;
n /= 9;
len++;
} while (n > 0);
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Queue;
public final class infinitybyone implements TestSolution {
public static void main(String[] args) {
System.out.println(new infinitybyone().run());
}
private static final int LIMIT = Library.pow(10, 7);
public String run() {
boolean[] isPrime = Library.listPrimality(LIMIT);
int[] pathMax = new int[isPrime.length];
Arrays.fill(pathMax, Integer.MAX_VALUE);
Queue<IntPair> queue = new PriorityQueue<>();
queue.add(new IntPair(2, 2));
while (!queue.isEmpty()) {
IntPair item = queue.remove();
int n = item.b;
int pmax = item.a;
if (pmax >= pathMax[n]) {
continue;
}
pathMax[n] = pmax;
int[] digits = toDigits(n);
int[] tempDigits = digits.clone();
for (int i = 0; i < tempDigits.length; i++) {
for (int j = 0; j < 10; j++) {
tempDigits[i] = j;
int m = toNumber(tempDigits);
int nextPmax = Math.max(m, pmax);
if (m < isPrime.length && isPrime[m] && nextPmax < pathMax[m])
queue.add(new IntPair(nextPmax, m));
}
tempDigits[i] = digits[i];
}
}
long sum = 0;
for (int i = 0; i < isPrime.length; i++) {
if (isPrime[i] && pathMax[i] > i)
sum += i;
}
return Long.toString(sum);
}
private static int[] toDigits(int n) {
if (n < 0)
throw new IllegalArgumentException();
//************This is PROBABLY where you made the error************
int[] temp = new int[11];
int len = 0;
do {
temp[len] = n % 10;
n /= 10;
len++;
} while (n > 0);
int[] result = new int[len + 1];
for (int i = 0; i < result.length; i++)
result[i] = temp[len - i];
return result;
}
private static int toNumber(int[] digits) {
int result = 0;
for (int x : digits)
result = result * 10 + x;
return result;
}
private static class IntPair implements Comparable<IntPair> {
public final int a;
public final int b;
public IntPair(int a, int b) {
this.a = a;
this.b = b;
}
public int compareTo(IntPair other) {
return Integer.compare(a, other.a);
}
}
}
I can't really tell where you messed up but at least from the code you shared, tell me why would you use 10 instead of 11? It should extract base-10 in little endian.
My program displays Pascal's triangle. For enlarging the portion of the triangle that may be calculated and displayed, I've rewritten the code using BigInteger instead of primitive types.
Here's the code:
import java.math.BigInteger;
public class ptrig {
public static void main(String args[]) {
BigInteger no = BigInteger.valueOf(5);
// Creating the array
String doubledim[][] = new String[no.intValue()][];
BigInteger k;
for (k = BigInteger.ZERO; k.compareTo(no) < 0; k.add(BigInteger.ONE)) {
doubledim[k.intValue()] = new String[k.intValue() + BigInteger.ONE.intValue()];
}
// Assigning values
BigInteger i, j, p, n;
BigInteger l = BigInteger.ONE;
for (i = BigInteger.ZERO; i.compareTo(no) < 0; i.add(BigInteger.ONE)) {
for (j = BigInteger.ZERO; j.compareTo(i.add(BigInteger.ONE)) < 0; j.add(BigInteger.ONE)) {
BigInteger m = i.subtract(j);
if (j.compareTo(m) > 0) {
for (p = BigInteger.ZERO; p.compareTo(m) < 0; p = p.add(BigInteger.ONE)) {
n = i.subtract(p);
l = l.multiply(n);
}
doubledim[i.intValue()][j.intValue()] = l.divide(factorial.factmet(m)).toString();
l = BigInteger.ONE;
}
if (m.compareTo(j) > 0) {
for (p = BigInteger.ZERO; p.compareTo(j) < 0; p = p.add(BigInteger.ONE)) {
n = i.add(p.add(BigInteger.ONE)).subtract(j);
l = l.multiply(n);
}
doubledim[i.intValue()][j.intValue()] = l.divide(factorial.factmet(j)).toString();
l = BigInteger.ONE;
}
if (m.compareTo(j) == 0) {
for (p = BigInteger.ZERO; p.compareTo(j) < 0; p = p.add(BigInteger.ONE)) {
n = i.subtract(p);
l = l.multiply(n);
}
doubledim[i.intValue()][j.intValue()] = l.divide(factorial.factmet(j)).toString();
l = BigInteger.ONE;
}
}
}
// Printing
for (i = BigInteger.ZERO; i.compareTo(no) < 0; i.add(BigInteger.ONE)) {
for (j = BigInteger.ZERO; j.compareTo(i.add(BigInteger.ONE)) < 0; j.add(BigInteger.ONE)) {
System.out.print(doubledim[i.intValue()][j.intValue()] + " ");
}
System.out.println();
}
}
}
The problem is it displays nothing. I've read on Stack Overflow I need to convert the array values into strings for that they're displayed, so I did. I've also checked the System.out.println statements - they seem to be fine. The error persisted.
The algorithm itself worked fine on a previous version with primitive types.
What's the error here? I did my best to find an answer on the web, I couldn't. Thanks.
Your for-loops aren't incrementing their indices, and will therefor loop forever.
i.add(BigInteger.ONE) doesn't mutate i, it creates a new BigInteger and returns it. If you want to increment the value of i, you need to write i = i.add(BigInteger.ONE)
This means that when you try to initialize your array, you're entering an infinite loop, where you re-initialize doubledim[0] forever.
e.g.
for (k = BigInteger.ZERO; k.compareTo(no) < 0; k.add(BigInteger.ONE)) {
doubledim[k.intValue()] = new String[k.intValue() + BigInteger.ONE.intValue()];
}
should be
for (k = BigInteger.ZERO; k.compareTo(no) < 0; k = k.add(BigInteger.ONE)) {
doubledim[k.intValue()] = new String[k.intValue() + BigInteger.ONE.intValue()];
}
and you'll need to likewise fix the loops that control the population of data in your arrays, and printing of their data later in your program.
I wrote a program in java and php. In which a loop runs 64 times. And keep adding n to n:
Java Code:
public static void main(String[] args) {
double n = 1;
double p = 1;
for(int i = 1;i <= 64;i++){
n = n + n;
p = p + n;
}
System.out.println(p);
}
PHP code:
<?php
$n = 1;
$p = 0;
for($i = 1;$i <= 64;$i++){
$n = $n + $n;
$p = $p + $n;
}
echo($p);
?>
And the output of both of these is:
3.6893488147419E+19
Now I want to know is it possible to convert this big float to int? if yes, Then how. In both languages.
I would use the BigInteger type,
public static void main(String[] args) {
BigInteger n = BigInteger.ONE;
BigInteger p = BigInteger.ONE;
for(int i = 1;i <= 64;i++){
n = n.add(n);
p = p.add(n);
}
System.out.println(p);
}
Output is
36893488147419103231
Edit Based on your comment, you really wanted something more like The Legend of the Chessboard -
BigInteger n = BigInteger.ONE;
BigInteger p = BigInteger.ZERO;
BigInteger TWO = new BigInteger("2");
for (int i = 1; i <= 64; i++) {
StringBuilder sb = new StringBuilder();
sb.append("For square #: " + i);
sb.append(", Grains on square: " + n);
p = p.add(n);
n = n.multiply(TWO);
sb.append(", Running Total: " + p);
System.out.println(sb.toString());
}
The number is too large to fit in a long. To get the closest integral approximation, convert the double to a BigInteger by way of a BigDecimal:
BigDecimal bd = BigDecimal.valueOf(p);
BigInteger bi = bd.toBigInteger();
However, to get an exact result, perform all the calculations using BigIntegers:
import static java.math.BigInteger.ONE;
BigInteger n = ONE;
BigInteger p = ONE;
for (int i = 1; i <= 64; i++) {
n = n.add(n);
p = p.add(n);
}
System.out.println(p);
The difference between the approximate and exact values is:
36893488147419103000
36893488147419103231
Java: Math.round(float), PHP: round(value,precision) However you will precision
I'm trying to recursively compute the fibonacci sequence to 100, store those returned values into an array using a the buildArray method, then print values stored in the array. I am getting a "cannot be resolved to a variable" compilation error when I try to print A[N] in the main method. I'm using longs because I'm computing the series up to 100, although I don't know if it's necessary to use longs.
If I substitute F(N) for A[N] the code works, but I need to put the values into an array and print that array. Does this code even store the values in an array? I'm just starting java, thanks.
public class MyFibonacci {
public static final int MAX = 100;
public static long[] buildArray(int MAX, int N) {
long[] A = new long[MAX];
A[0] = 0;
A[1] = 1;
for(N = 2; N < MAX; N++)
A[N] = F(N);
return A;
}
public static long F(int N) {
if(N == 0)
return 0;
if(N == 1)
return 1;
return F(N - 1) + F(N - 2);
}
public static void main(String[] args) {
for(int N = 0; N < MAX; N++)
System.out.println(N + " " + A[N]);
}
}
You have declared A[] within the scope of buildArray(int MAX, int N). As a result, A[] is not accessible outside of buildArray. You need to move your declaraction of long A[] to a class variable.
Additionally, you actually need to run buildArray for the array to be constructed.
For future reference, I highly recommend using proper tabbing structures. It makes it much easier to see what's happening. I've edited your code (though it will have to be approved) to include this.
Here's the code for what you need, I think:
public class MyFibonacci{
public static final int MAX = 100;
long[] A = new long[MAX];
public static long[] buildArray(int N){
A[0] = 0;
A[1] = 1;
for (N = 2; N < MAX; N++){
A[N] = F(N);
}
return A;
}
public static long F(int N)
{
if (N == 0) return 0;
if (N == 1) return 1;
return F(N-1) + F(N-2);
}
public static void main(String[] args)
{
buildArray(<some number - not sure where you get it from? N by the way in buildArray()>);
for (int N = 0; N < MAX; N++)
StdOut.println(N + " " + A[N]);
}
}
The main problem is that you're never calling the buildArray function.
To get your code to work, you only need to add this to main:
long[] A = buildArray(MAX, 0);
Some other things:
You can remove the parameter N and just declare it in the function (or remove it all-together, see below).
You already have access to MAX, no need to pass it to the function.
The for-loop in buildArray is rather inefficient, you can set up the array inside F.
Given the below, A as a class variable is cleaner than passing it around.
Finally, the code:
static int MAX = 100;
static long[] A;
public static void buildArray()
{
A = new long[MAX+1];
F(MAX);
}
public static long F(int N)
{
long val;
if (N < 2)
val = N;
else if (A[N] != 0) // HEY! It's already calculated! Awesome! Just return it.
return A[N];
else
val = F(N-1) + F(N-2);
A[N] = val;
return val;
}
public static void main(String[] args)
{
buildArray();
for (int N = 0; N <= MAX; N++)
System.out.println(N + " " + A[N]);
}
Since you can allocate array memory, it makes good sense to utilize it during calculation. Consider this method:
public static long[] f_a(int n) {
long[] a = new long[n];
a[1] = 1;
for (int i = 2; i < n; i++)
a[i] = a[i-1] + a[i-2];
return a;
}
When I run Countdown.class I get the following output:
263845041
-1236909152
-973064111
2084994033
1111929922
-1098043341
13886581
-1084156760
-1070270179
2140540357
Blast Off!
The numbers before "Blast Off!" ought to be the first 10 Fibonacci numbers. My source code is as follows.
public class Fibonacci {
public static long fib(int n) {
if (n <= 1) return 1;
return fib(n-1) + fib(n-2);
}
public static long fastfib(int n) {
int a = 0;
int b = 1;
int c = 0;
for (int i = 0; i <= n; n++) {
c = a + b;
a = b;
b = c;
}
return c;
}
}
and the class that implements the fastfib method is:
public class Countdown {
public static void countdown(int n) {
if (n == 0) System.out.println("Blast Off!");
else {
System.out.println(Fibonacci.fastfib(n));
countdown(n - 1);
}
}
public static void main(String[] args) {
countdown(10);
}
}
Though your fastfib() method returns long, the calculations are done on ints.
You are encountering integer overflow.
Make sure to declare a,b,c as longs and NOT as ints. If you want even larger numbers (that are out of range for longs as well) - you might want to have a look on BigInteger (and use it).
EDIT: As mentioned by #ExtremeCoders in comment, there is another issue in the code in your for loop:
for (int i = 0; i <= n; n++) should be for (int i = 0; i <= n; i++), you want to increase i - not n.
In addition to the other answers,
for (int i = 0; i <= n; n++) {
should be
for (int i = 0; i <= n; i++) {
// ^ that's an i
Change the datatypes of a,b and c to long, and it will start working fine. Your numbers are crossing the limits for int.
You should user BigInteger insted of long
import java.math.BigInteger;
public class Fibonacci {
public static BigInteger fib(BigInteger n) {
int result = n.compareTo(BigInteger.valueOf(1)); // returns -1, 0 or 1 as this BigInteger is numerically less than, equal to, or greater than val.
if (result != 1) return BigInteger.valueOf(1);
return fib(
n.subtract(
BigInteger.valueOf(1).add
(n.subtract
(
BigInteger.valueOf(-2)
)
)
)
);
}
public static BigInteger fastfib(int n) {
BigInteger a = BigInteger.valueOf(0);
BigInteger b = BigInteger.valueOf(1);
BigInteger c = BigInteger.valueOf(0);
for (int i = 1; i < n; i++) {
c = a.add(b);
a = b;
b = c;
}
return c;
}
}