find the sum of even number not exceed four million - java

class fibo {
//int firstNumber = 0;
public static void main(String args[]){
//int firstNumber = 0;
int length = 4000000;
int[] series = new int[length];
//long[] sum = new long[4000000];
long sum =0;
series[0] = 0;
series[1] = 1;
for (int i = 2; i<4000000; i++){
//firstNumber = firstNumber + i;
//System.out.println("fibo" + i);
series[i] = series[i-1] + series[i-2];
if(series[i] %2 == 0) {
sum = sum + series[i];
}
}
for(int j=0;j<length; j++){
System.out.println("fibo Series" + series[j]);
}
}
}
I got the answer, but the approach was different. What's wrong with this code?. Can anyone give an insight on this.
The same code works when the length is 10. I am not getting any expection on this, but the answer seems to be different. Its something -92719184589087346 which is incorrect.

What's wrong with this code?
Well it's taking the sum of the even numbers within the first four million Fibonacci numbers, not the even numbers within the sequence of Fibonacci numbers less than four million.
It's also creating an array of all the Fibonacci numbers it's seen, for no reason: you only ever need the last two at a time, so you can do that in constant space.

I'm guessing you are trying to get the sum where the sum is less than 4million? because that isn't what you are calculating. You are calculating the sum at the 4 millionth index which is completely different.
The reason your answer is wrong (besides your logic being wrong) is that a long can't fit the number you are calculating. The 4 millionth entry in the fibonacci sequence is some number so incredibly large that it is overflowing your long. The overflow will make it wrap back into the negatives (probably multiple times).

Related

Getting Time limit exceeded error in java

class Check {
static void countOddEven(int a[], int n) {
int countEven = 0, countOdd = 0;
for (int item : a) {
if (item % 2 == 0) {
countEven++;
}
}
countOdd = n - countEven;
System.out.println(countOdd + " " + countEven);
}
}
Code is to calculate even and odd numbers in an array. Please help to optimise the code.
You’re code is not correct.
If you were meant to count the even and odd numbers in a, then you are counting the even numbers correctly. If n is not equal to the length of a, then your calculation of the count of odd numbers is incorrect.
If on the other hand — and I’m just guessing — you were meant to count the even and odd numbers among the first n elements, then you are counting the even numbers incorrectly since you are iterating over all of a. Also in this case, if n is much smaller than the length of a, there is an optimization in only iterating over the first n elements as you should.
Finally you may try the following version. I doubt that it buys you anything, but I am leaving the measurements to you.
int countOdd = 0;
for (int ix = 0; ix < n; ix++) {
countOdd += a[ix] & 1;
}
int countEven = n - countOdd;
The trick is: a[ix] & 1 gives you the last bit of a[ix]. This is 1 for odd numbers and 0 for even numbers (positive or negative). So we are really adding a 1 for each odd number.
You should try running code with for loop instead of for each loop
Because ,
When accessing arrays, at least with primitive data for loop is dramatically faster.
however
When accessing collections, a foreach is significantly faster than the basic for loop’s array access.
but if you are getting some another errors , so might have done something wrong while calling the method (make sure n=length of your array)
here is the whole code with main method.
class Check{
static void countOddEven(int a[], int n){
int countEven=0,countOdd=0;
for(int i=0;i<n;i++)
if(a[i]%2==0)
{
countEven++;
}
countOdd=n-countEven;
System.out.println(countOdd+" "+countEven);
}
public static void main(String[] arg){
int a[]={2,3,4,5,6};
int n = 5;
countOddEven(a,n);
}
}

I'm trying to find the sum of primes below 2 million in Java [duplicate]

This question already has answers here:
Project Euler #10 Java solution not working
(6 answers)
Closed 9 years ago.
I'm trying to find the sum of primes below millions. My code works when I try to find the sum of primes below hundred thousands but when I go large numbers it doesn't work. So I need some help to get this work for big numbers...
import java.util.Scanner;
public class sumPrime {
public static void main (String args []){
long n = 2000000; int i; int j;int sum =0;
for (i=2; i <n; i++){
for (j=2; j<i; j++){
if (i%j==0){
break;
}
}
if (i==j){
sum +=i;
}
}
System.out.print(sum);
}
}
Your code could be improved by making the inner loop stop earlier. If a number N is not prime, then it must have at least one factor (apart from 1) that is less or equal to sqrt(N). In this case, this simple change should make the program roughly 1000 times faster.
For a simple and (more) efficient algorithm, read up on the Sieve of Eratosthenes.
Bug - your sum needs to be a long. An int will probably overflow.
Note that the classic formulation of Sieve of Eratosthenes needs a large array of booleans (or a bitmap) whose size depends on the largest prime candidate you are interested in. In this case that means a 2Mbyte array (or smaller if you use a bitmap) ... which is too small to worry about. Also, you can reduce the memory usage by sieving in stages, though it makes the code more complicated.
Rather than trying to divide by all the numbers below i you could potentially keep the found prime numbers in a list and try to divide by those prime numbers (since any non prime number will be divisible by a prime number less than that).
public static long sumPrime2() {
List<Long> primes = new ArrayList<>();
primes.add(2L);
primes.add(3L);
long primeSum = 5;
for (long primeCandidate = 5; primeCandidate < 2000000; primeCandidate = primeCandidate + 2) {
boolean isCandidatePrime = true;
double sqrt = Math.sqrt(primeCandidate);
for (int i = 0; i < primes.size(); i++) {
Long prime = primes.get(i);
if (primeCandidate % prime == 0) {
isCandidatePrime = false;
break;
}
if (prime > sqrt) {
break;
}
}
if (isCandidatePrime) {
primes.add(primeCandidate);
primeSum += primeCandidate;
}
System.out.println(primeCandidate);
}
System.out.println(primes.size());
return primeSum;
}
This gave the answer in 8 seconds
I suspect integer overflow in i, j, sum - try making them all longs. In the sample code you shouldn't be getting overflows as Java ints are meant to be 32 bit but at some stage you certainly will.
As already mentioned - i only needs to iterate to the square root of n. So I would replace this line:
for (i=2; i <n; i++){
With:
long limit=sqrt(n);
for (i=2; i <limit; i++){
Note that calculating the square root outside the program loops will also speed things up a bit.
Also the sieve algorithm would be faster but requires Java to create an array containing n elements and at some stage that is going to fail with insufficient memory.
The best algorithm for this program uses the Sieve of Eratosthenes:
function sumPrimes(n)
sum, sieve := 0, makeArray(2..n, True)
for p from 2 to n
if sieve[p]
sum := sum + p
for i from p*p to n step p
sieve[i] := False
return sum
Then sumPrimes(2000000) returns the sum of the primes less than two million, in about a second. I'll leave it to you to translate to Java, with an appropriate data type for the sum. If you're interested in programming with prime numbers, I modestly recommend this essay at my blog.

How to get a 50/50 chance in random generator

I am trying to get a 50/50 chance of get either 1 or 2 in a random generator.
For example:
Random random = new Random();
int num = random.nextInt(2)+1;
This code will output either a 1 or 2.
Let's say I run it in a loop:
for ( int i = 0; i < 100; i++ ) {
int num = random.nextInt(2)+1 ;
}
How can I make the generator make an equal number for 1 and 2 in this case?
So I want this loop to generate 50 times of number 1 and 50 times of number 2.
One way: fill an ArrayList<Integer> with fifty 1's and fifty 2's and then call Collection.shuffle(...) on it.
50/50 is quite easy with Random.nextBoolean()
private final Random random = new Random();
private int next() {
if (random.nextBoolean()) {
return 1;
} else {
return 2;
}
}
Test Run:
final ListMultimap<Integer, Integer> histogram = LinkedListMultimap.create(2);
for (int i = 0; i < 10000; i++) {
nal Integer result = Integer.valueOf(next());
histogram.put(result, result);
}
for (final Integer key : histogram.keySet()) {
System.out.println(key + ": " + histogram.get(key).size());
}
Result:
1: 5056
2: 4944
You can't achieve this with random. If you need exactly 50 1s and 50 2s, you should try something like this:
int[] array = new int[100];
for (int i = 0; i < 50; ++i)
array[i] = 1;
for (int i = 50; i < 100; ++i)
array[i] = 2;
shuffle(array); // implement shuffling algorithm or use an already existing one
EDIT:
I understand that if you are looking to accomplish exactly 50-50 results, then my answer was not accurate. You should use a pre-filled collection, since it is impossible to achive that using any kind of randomness. This considered, my answer is still valid for the title of the question, so, this is it:
Well, you do not need the rnd generator to do this.
Comming from javascript, I would go with a single liner:
return Math.random() > 0.5 ? 1: 2;
Explanation: Math.random() returns a number between 0(inclusive) and 1(exclusive), so, we just examine weather is larger than 0.5 (middle value). In theory there is a 50% change that does.
For a more generic use, you can just replace 1:2 to true:false
You can adjust the probability along the way so that the probability of getting a one decreases as you get more ones. This way you don't always have a 50% chance of getting a one, but you can get the result you expected (exactly 50 ones):
int onesLeft = 50;
for(int i=0;i<100;i++) {
int totalLeft = 100 - i;
// we need a probability of onesLeft out of (totalLeft)
int r = random.nextInt(totalLeft);
int num;
if(r < onesLeft) {
num = 1;
onesLeft --;
} else {
num = 2;
}
}
This has an advantage over shuffling because it generates numbers incrementally so it desn't need memory to store the numbers.
You have already successfully created a random generator that returns 1 or 2 with equal probability.
As (many) other's have mentioned, your next request, to force an exact 50/50 distributions in 100 trials, does not fall in line with random number generation. As shown in https://math.stackexchange.com/questions/12348/probability-of-getting-50-heads-from-tossing-a-coin-100-times, the realistic expectation of that occurring is only around 8%. So even while you might expect 50 of each, that exact outcome is actually rather rare.
The Law of Large Numbers states that you should close in on expected value as your number of trials increases.
So for your actual question: How can I make the generator make an equal number for 1 and 2 in this case?
The best (humorous) answer I can come up with is: "Run it in an infinite loop."

Project Euler 14: Issue with array indexing in a novel solution

The problem in question can be found at http://projecteuler.net/problem=14
I'm trying what I think is a novel solution. At least it is not brute-force. My solution works on two assumptions:
1) The less times you have iterate through the sequence, the quicker you'll get the answer. 2) A sequence will necessarily be longer than the sequences of each of its elements
So I implemented an array of all possible numbers that could appear in the sequence. The highest number starting a sequence is 999999 (as the problem only asks you to test numbers less than 1,000,000); therefore the highest possible number in any sequence is 3 * 999999 + 1 = 2999998 (which is even, so would then be divided by 2 for the next number in the sequence). So the array need only be of this size. (In my code the array is actually 2999999 elements, as I have included 0 so that each number matches its array index. However, this isn't necessary, it is for comprehension).
So once a number comes in a sequence, its value in the array becomes 0. If subsequent sequences reach this value, they will know not to proceed any further, as it is assumed they will be longer.
However, when i run the code I get the following error, at the line introducing the "wh:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3188644
For some reason it is trying to access an index of the above value, which shouldn't be reachable as it is over the possible max of 29999999. Can anyone understand why this is happening?
Please note that I have no idea if my assumptions are actually sound. I'm an amateur programmer and not a mathematician. I'm experimenting. Hopefully I'll find out whether it works as soon as I get the indexing correct.
Code is as follows:
private static final int MAX_START = 999999;
private static final int MAX_POSSIBLE = 3 * MAX_START + 1;
public long calculate()
{
int[] numbers = new int[MAX_POSSIBLE + 1];
for(int index = 0; index <= MAX_POSSIBLE; index++)
{
numbers[index] = index;
}
int longestChainStart = 0;
for(int index = 1; index <= numbers.length; index++)
{
int currentValue = index;
if(numbers[currentValue] != 0)
{
longestChainStart = currentValue;
while(numbers[currentValue] != 0 && currentValue != 1)
{
numbers[currentValue] = 0;
if(currentValue % 2 == 0)
{
currentValue /= 2;
}
else
{
currentValue = 3 * currentValue + 1;
}
}
}
}
return longestChainStart;
}
Given that you can't (easily) put a limit on the possible maximum number of a sequence, you might want to try a different approach. I might suggest something based on memoization.
Suppose you've got an array of size 1,000,000. Each entry i will represent the length of the sequence from i to 1. Remember, you don't need the sequences themselves, but rather, only the length of the sequences. You can start filling in your table at 1---the length is 0. Starting at 2, you've got length 1, and so on. Now, say we're looking at entry n, which is even. You can look at the length of the sequence at entry n/2 and just add 1 to that for the value at n. If you haven't calculated n/2 yet, just do the normal calculations until you get to a value you have calculated. A similar process holds if n is odd.
This should bring your algorithm's running time down significantly, and prevent any problems with out-of-bounds errors.
You can solve this by this way
import java.util.LinkedList;
public class Problem14 {
public static void main(String[] args) {
LinkedList<Long> list = new LinkedList<Long>();
long length =0;
int res =0;
for(int j=10; j<1000000; j++)
{
long i=j;
while(i!=1)
{
if(i%2==0)
{
i =i/2;
list.add(i);
}
else
{
i =3*i+1;
list.add(i);
}
}
if(list.size()>length)
{
length =list.size();
res=j;
}
list.clear();
}
System.out.println(res+ " highest nuber and its length " + length);
}}

Java unknown output

Soo this problem involves me rolling a pair of dice and estimate the probability that the first roll is a losing roll (2, 3, or 12).
output is the count of rolls that were losers (2,3, or 12) and calculated probability (count/N)
public static void main(String [] args){
int N1 = (int) (Math.random()*6 + 1);
int N2 = (int) (Math.random()*6 + 1);
int count = N1 + N2;
for (int i = 0; i<=1; i++)
if (count==2 || count = 3 || count == 12)
I just don't seem to know what to do get the output...... This is my attempt
It seems that you will want to roll the dice N times (where N is some large number) and count the number of times that it was a loser, correct?
So you will need to store in memory the total number of rolls, and the number of losing rolls. You can store those in int variables.
An int variable can be incremented using the ++ operator.
int rolls = 0;
rolls++;
is equivalent to
int rolls = 0;
rolls = rolls + 1;
You also don't want to call your main function a million times, so you can set the upper limit of your loop to the amount of rolls you want to have.
To calculate the probability, you will want to use floats rather than ints - you can cast an int to a float like this:
int a = 10;
float b = (float) a;
Finally, if you want to see your output via standard out, use System.out.println(). The argument to the println() function should be whatever you want to output.
Since this sounds like homework, I'm avoiding writing much code for now. Let me know if it isn't.
The simplest way to get output from a command-line app (like you are writing) is to use System.out.println(...). For example:
int digits = 5;
System.out.println("Hello world");
System.out.println("I have " + digits + " fingers");
This should be enough of a hint for you to make progress.

Categories

Resources