Basics of Java : Project Euler problems - java

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not exceed four million.
My code:
int x = 0;
int y = 1;
int z;
int sum = 0;
for(int i = 0; i <= 4000000; i++)
{
z = x + y;
x = y;
y = z;
if(y % 2 == 0)
{
sum = sum + y;
}
}
System.out.println(sum);
}
That outputs 1110529254 but, the correct answer is 4613732.
Help would be very much appreciated.

Your code does iteration 4 million times but it does not check the sum of all the even-valued terms in the sequence whether do not exceed four million or not.
Below you can find my variant of getting sum of all the even-valued terms in the sequence which dont exceed for million.
public class Example_1 {
public static void main(String args[]) {
int x = 0;
int y = 1;
int z;
int sum = 0;
while (true) {
z = x + y;
x = y;
y = z;
if(y % 2 == 0) {
sum = sum + y;
}
if (sum >= 4000000){
break;
}
}
System.out.println("Sum: " + sum);
}
}
The answer which I get from this code is 4613732 as we expected.

Related

Java: How to add variable in a loop together, multiple times

public class R {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
int x = 0;
int y = 0;
int j = 0;
int distance = 0;
while (trials>j) {
j = j + 1;
int i = -1;
double counter = 1.0 * distance;
double sum = (distance + counter);
while (i<=n) {
i = i + 1;
if (i == n) {
distance = ((x*x) + (y*y));
}
if (i<n) {
int random = (int )(Math.random() * 4 + 1);
if (random == 1) x = x + 1;
if (random == 2) y = y + 1;
if (random == 3) x = x - 1;
if (random == 4) y = y - 1;
}
}
}
double average= (sum)/(trials);
System.out.println("mean " + "squared " + "distance " + "= " + average);
}
}
Hey guys I'm wondering how it's possible to compute a value within a loop, and then every single time the loop finishes (and the value in computed) to average them together. I can't wrap my head around the concept and I tried doing it in the code above but I can't quite figure it out.
As you can see there are two while loops, and inside one of them a random value (distance) is computed. So essentially I need to average the distances together, but I can't imagine how it's possible to add the distances that are computed each time together into one number. Let's say the loop goes through one time and outputs a singular distance, how would I go about adding a new distance (for the new loop) together with the old one, and then keep doing that for each trial?
You just have to divide the total distance per trials.
public class R {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
int x = 0;
int y = 0;
int j = 0;
int distance = 0, distance_total = 0;
while (trials>j) {
j = j + 1;
int i = -1;
distance = 0;
while (i<=n) {
i = i + 1;
if (i == n) {
distance += ((x*x) + (y*y));
}
if (i<n) {
int random = (int )(Math.random() * 4 + 1);
if (random == 1) x = x + 1;
if (random == 2) y = y + 1;
if (random == 3) x = x - 1;
if (random == 4) y = y - 1;
}
}
distance_total += distance;
}
System.out.println(distance_total/j);
}
}

Split an array into four sub-array

Given an array, it contains N element, which are all positive integers; if we can find three elements, and they divide the array into four parts (Notice: the three elements are not contained in any part of the four), and the sum of each part are equal, then we call the array a "balanced" array. Design an algorithm to judge whether an array is balance, with limit: Time O(N), Space O(N).
Here is an example:
a = [1,7,4,2,6,5,4,2,2,9,8];
b = [1,8,10,5,3,1,2,3]
a is balanced, 'cause the element 4, 5, 9 divide the array into [1,7], [2,6], [4,2,2], [8], the sum of each is 8.
b is not balanced, because we can not find a solution.
Any idea is appreciated!
Hints
Consider the first element to be removed.
Once you know this position, you can compute the size of the first part.
Once you know the size of the first part, you can compute the location of the second element to be removed, and so on (because all elements are positive integers).
Now you need to find a way to perform this in O(N). Try thinking about what you can do to reuse computations that have already been done, e.g. by keeping a rolling sum of the size of each of your parts.
You can try with this solution:
class BalancedArray
{
public static void main( String[] args ) throws java.lang.Exception
{
int[] a = { 1, 7, 4, 2, 6, 5, 4, 2, 2, 9, 8 }; //BALANCED
//int[] a = {7,0,6,1,0,1,1,5,0,1,2,2,2}; //BALANCED
//int[] a = {1}; //NOT BALANCED
int l = a.length;
if ( l < 7 )
{
System.out.println( "Array NOT balanced" );
} else
{
int maxX = l - 5;
int maxY = l - 3;
int maxZ = l - 1;
int x = 1;
int y = 3;
int z = 5;
int sumX = 0; //From 0 to x
int sumY = 0; //From x to y
int sumJ = 0; //From y to z
int sumZ = 0; //From z to l
for(x = 1; x < maxX; x++)
{
sumX = calcSum(a,0,x);
for(y = x + 2; y < maxY; y++)
{
sumY = calcSum(a,x+1,y);
if(sumY != sumX){
continue;
}
for(z = y + 2; z < maxZ; z++)
{
sumJ = calcSum(a,y+1,z);
if(sumJ != sumY)
{
continue;
}
sumZ = calcSum(a,z+1,l);
if(sumZ != sumJ){
continue;
}
if(sumZ == sumX && sumX == sumY && sumY == sumJ)
{
System.out.println( "Array balanced!!! Elements -> X:" + x + " Y: " + y + " Z:" + z );
return;
}
}
}
}
System.out.println("Array NOT balanced!!");
}
}
private static int calcSum(int[] src, int start, int end)
{
int toReturn = 0;
for ( int i = start; i < end; i++ )
{
toReturn += src[i];
}
return toReturn;
}
}
I made these assumptions:
between each of the three elements, which should split the array in 4 parts, there must be at least a distance of 2;
to be divided in 4 sub-arrays the source array must be at least 7 elements long;

Making Hardy-Ramanujan nth number finder more efficient

I tried to make an algorithm to find the nth Hardy-Ramanujan number(a number which can be expressed in more than one way as a sum of 2 cubes). Except I'm basically checking every single cube with another to see if it equals a sum of another 2 cubes. Any tips on how to make this more efficient? I'm kind of stumped.
public static long nthHardyNumber(int n) {
PriorityQueue<Long> sums = new PriorityQueue<Long>();
PriorityQueue<Long> hardyNums = new PriorityQueue<Long>();
int limit = 12;
long lastNum = 0;
//Get the first hardy number
for(int i=1;i<=12;i++){
for(int j = i; j <=12;j++){
long temp = i*i*i + j*j*j;
if(sums.contains(temp)){
if(!hardyNums.contains(temp))
hardyNums.offer(temp);
if(temp > lastNum)
lastNum = temp;
}
else
sums.offer(temp);
}
}
limit++;
//Find n hardy numbers
while(hardyNums.size()<n){
for(int i = 1; i <= limit; i++){
long temp = i*i*i + limit*limit*limit;
if(sums.contains(temp)){
if(!hardyNums.contains(temp))
hardyNums.offer(temp);
if(temp > lastNum)
lastNum = temp;
}
else
sums.offer(temp);
}
limit++;
}
//Check to see if there are hardy numbers less than the biggest you found
int prevLim = limit;
limit = (int) Math.ceil(Math.cbrt(lastNum));
for(int i = 1; i <= prevLim;i++){
for(int j = prevLim; j <= limit; j++){
long temp = i*i*i + j*j*j;
if(sums.contains(temp)){
if(!hardyNums.contains(temp))
hardyNums.offer(temp);
if(temp > lastNum)
lastNum = temp;
}
else
sums.offer(temp);
}
}
//Get the nth number from the pq
long temp = 0;
int count = 0;
while(count<n){
temp = hardyNums.poll();
count++;
}
return temp;
}
These numbers are sometimes called "taxicab" numbers:
The mathematician G. H. Hardy was on his way to visit his collaborator
Srinivasa Ramanujan who was in the hospital. Hardy remarked to
Ramanujan that he traveled in a taxi cab with license plate 1729,
which seemed a dull number. To this, Ramanujan replied that 1729 was a
very interesting number — it was the smallest number expressible as
the sum of cubes of two numbers in two different ways. Indeed,
103 + 93 =
123 + 13 = 1729.
Since the two numbers x and y whose cubes are summed must both be between 0 and the cube root of n, one solution is an exhaustive search of all combinations of x and y. A better solution starts with x = 0 and y the cube root of n, then repeatedly makes a three-way decision: if x3 + y3 < n, increase x, if x3 + y3 > n, decrease y, or if x3 + y3 = n, report the success and continue the search for more:
function taxicab(n)
x, y = 0, cbrt(n)
while x <= y:
s = x*x*x + y*y*y
if s < n then x = x + 1
else if n < s then y = y - 1
else output x, y
x, y = x + 1, y - 1
Here are the taxicab numbers less than 100000:
1729: ((1 12) (9 10))
4104: ((2 16) (9 15))
13832: ((2 24) (18 20))
20683: ((10 27) (19 24))
32832: ((4 32) (18 30))
39312: ((2 34) (15 33))
40033: ((9 34) (16 33))
46683: ((3 36) (27 30))
64232: ((17 39) (26 36))
65728: ((12 40) (31 33))
I discuss this problem at my blog.
The basic difference between your approach is that you visit (i,j) and also (j,i).
The algorithm suggested by #user448810 visits only once because i will be always less than j in while condition.
Java Implementation of above code:
import java.util.*;
public class efficientRamanujan{
public static void main(String[] args) {
efficientRamanujan s=new efficientRamanujan();
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int i=0,k=1;
while(i<n){
if(s.efficientRamanujan(k))
{
i=i+1;
System.out.println(i+" th ramanujan number is "+k);
}
k++;
}
scan.close();
}
public boolean efficientRamanujan(int n){
int count=0;
int x = 1;
int y = (int) Math.cbrt(n);
while (x<y){
int sum = (int) Math.pow(x,3) + (int) Math.pow(y,3);
if(sum<n){
x = x+1;
}else if(sum>n){
y = y-1;
}else{
count++;
x = x+1;
y = y-1;
}
if(count>=2){
return true;
}
}
return false;
}
}

Coin Combinations Through Brute Force

I have some code that will brute force solve the following problem:
Given a set of x coins and a target sum to reach, what is the fewest number of coins required to reach that target?
The code so far:
import java.util.ArrayList;
import java.util.Arrays;
public class coinsSum {
public static int min = Integer.MAX_VALUE;
public static int[] combination;
public static final int TARGET = 59;
public static void main(String[] args) {
long start = System.nanoTime();
int[] validCoins = new int[] {1, 2, 5, 10, 20};
Arrays.sort(validCoins);
int len = validCoins.length;
ArrayList<Integer> maxList = new ArrayList<Integer>();
for(int c : validCoins) {
maxList.add(TARGET / c);
}
int[] max = new int[len];
for(int i = 0; i < len; i++) {
max[i] = maxList.get(i).intValue();
}
permutations(new int[len], max, validCoins, 0); // bread&butter
if(min != Integer.MAX_VALUE) {
System.out.println();
System.out.println("The combination " + Arrays.toString(combination) + " uses " + min + " coins to make the target of: " + TARGET);
} else {
System.out.println("The target was not reachable using these coins");
}
System.out.println("TOOK: " + (System.nanoTime() - start) / 1000000 + "ms");
}
public static void permutations(int[] workspace, int[] choices, int[] coins, int pos) {
if(pos == workspace.length) {
int sum = 0, coinCount = 0;
System.out.println("TRYING " + Arrays.toString(workspace));
for(int a = 0; a < coins.length; a++) {
sum += workspace[a] * coins[a];
coinCount += workspace[a];
}
if(sum == TARGET) {
// System.out.println(Arrays.toString(n)); //valid combinations
if(coinCount < min) {
min = coinCount;
combination = workspace;
System.out.println(Arrays.toString(combination)+" uses " + min + " coins");
}
}
return;
}
for(int i = 0; i <= choices[pos]; i++) {
workspace[pos] = i;
permutations(workspace, choices, coins, pos + 1);
}
}
}
This solution uses recursion, is there any way to do compute combinations in java using loops?
How else can all possible combinations be iterated through?
You can sort the array of coins. Then go from right to left, keep subtracting from the target value, untill the coin is bigger from the remaining value of target. Move left in the array of coins and repeat the process.
Example:
{1, 2, 5, 10, 20}
num = 59
Try coins from right to left:
59 - 20 = 39
So far coins used [20]
39 - 20 = 19
So far coins used [20,20]
19 - 20 = -1, Can't use 20!
19 - 10 = 9
So far coins used [20,20,10]
9 - 10 = -1, Can't use 10!
9 - 5 = 4
So far coins used [20,20,10,5]
4 - 5 = -1, Can't use 5!
4 - 2 = 2
So far coins used [20,20,10,5,2]
2 - 2 = 0
So far coins used [20,20,10,5,2,2]
Total coin used 6
Here is a solution in python that uses dynamic programming to find the minimum number of coins to reach a target value.
The algorithm works as follow
dp[i][target] = minimum number of coins required required to acheive target using first i coin
dp[i][target] = min(dp[i-1][target],dp[i-1][target-coin[i]]+1)
dp[i-1][target] denotes not using the ith coin
dp[i-1][target-coin[i]] denotes making use of ith coin
Since for each coin your are checking wheather to include it or not the algorithm is enumerating through all possible combination.
Here is an space optimized version of the above algorithm
maxvalue = 10 ** 9
def minchange(coins, target):
no_of_coins = len(coins)
dp = [maxvalue for i in range(target + 1) ]
dp[0] = 0
for i in range(no_of_coins):
for j in range(coins[i], target + 1):
dp[j] = min(dp[j], dp[j - coins[i]] + 1)
return dp[target]
I found a dynamic programming approach which is definitely not optimised, but isn't too bad for target numbers up to 10000 if anyone is interested
import java.util.*;
public class coinSumMinimalistic {
public static final int TARGET = 12003;
public static int[] validCoins = {1, 3, 5, 6, 7, 10, 12};
public static void main(String[] args) {
Arrays.sort(validCoins);
sack();
}
public static void sack() {
Map<Integer, Integer> coins = new TreeMap<Integer, Integer>();
coins.put(0, 0);
int a = 0;
for(int i = 1; i <= TARGET; i++) {
if(a < validCoins.length && i == validCoins[a]) {
coins.put(i, 1);
a++;
} else coins.put(i, -1);
}
for(int x = 2; x <= TARGET; x++) {
if(x % 5000 == 0) System.out.println("AT: " + x);
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = 0; i <= x / 2; i++) {
int j = x - i;
list.add(i);
list.add(j);
}
coins.put(x, min(list, coins));
}
System.out.println("It takes " + coins.get(TARGET) + " coins to reach the target of " + TARGET);
}
public static int min(ArrayList<Integer> combos, Map<Integer, Integer> coins) {
int min = Integer.MAX_VALUE;
int total = 0;
for(int i = 0; i < combos.size() - 1; i += 2) {
int x = coins.get(combos.get(i));
int y = coins.get(combos.get(i + 1));
if(x < 0 || y < 0) continue;
else {
total = x + y;
if(total > 0 && total < min) {
min = total;
}
}
}
int t = (min == Integer.MAX_VALUE || min < 0) ? -1:min;
return t;
}
public static void print(Map<Integer, Integer> map) {
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("[" + entry.getKey() + ", " + entry.getValue() + "]");
}
System.out.println();
}
}

Summing integers recursive with Java

I have to calculate a sum of two integers by using a recursive algorithm, but sincerely i have no idea how to do so. Here are the conditions:
sum(x,y) = ?
if x = 0 then sum (x,y) = y otherwise sum(x,y) = sum(predecessor(x),successor(y)).
Does someone have an idea how i could write this in an algorithm? I would be glad about any advice.
I won't give you the code since this seems to be a homework but here is the rough algorithm:
predecessor(x) = x - 1
successor(x) = x + 1
sum(x, y) =
if x = 0
then y
otherwise sum(predecessor(x), successor(y))
That's the simplest I could immagine
public static void main(String[] args) {
System.out.println("4+5 = " + sum(4, 5));
System.out.println("4+(-5) = " + sum(4, -5));
System.out.println("-4+5 = " + sum(-4, 5));
System.out.println("-4+5 = " + sum(-4, -5));
}
public static int sum(int x, int y) {
if (x < 0) {
x *= -1;
y *= -1;
}
return (x == 0 ? y : sum(--x, ++y));
}
Here is my solution for i&j both >= 0. set sum = 0; and subtract 1 until it is <= 0
public static int sum(int i, int j){
return sum(i,j,0);
}
private static int sum(int i, int j, int sum) {
if (i <= 0 && j <= 0) {
return sum;
} else if (i <= 0) {
return sum(0, j - 1, sum + 1);
} else if (j <= 0) {
return sum(i - 1, 0, sum + 1);
} else {
return sum(i - 1, j - 1, sum + 2);
}
}
public static void main(String[] args) {
System.out.println(sum(60, 7));
}
To handle negative numbers based on #aioobe's answer.
sum(x, y): return x == 0 ? y : x < 0 ? ~sum(~x, -y) : sum(x-1, y+1)
Note: the rather optimisic use of ~ to avoid blowing up on x=MIN_VALUE. ;)
Javaish pseudo code corresponding to your code in your question
sum(x, y): return x == 0 ? y : sum(x-1, y+1)
Works for any pair of numbers where x is a non-negative integer.

Categories