Why is my solution to project euler 1 not working? - java

I decided to just try and get the small example of only going to 10 like the example shown.
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 >and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
public class project1 {
public static void main(String[] args) {
int three=0;
int tot3=0;
int five=0;
int tot5=0;
int total;
while (tot3<10) {
three+=3;
tot3=tot3+three;
};
while (tot5<10) {
five+=5;
tot5=tot5+five;
};
total=tot3+tot5;
System.out.println("Three's: " + tot3);
System.out.println("Five's: " + tot5);
System.out.println("Combined: " + total);
}
}
My output is as show:
Three's: 18
Five's: 15
Combined: 33

Numbers that are both multiples of 3 and 5 (like 15 for instance), are counted twice - once in each loop.

while (tot3<10) {
three+=3;
tot3=tot3+three;
};
I think you mean
while (tot3<10) {
three += tot3; // Add this multiple of 3 to the total.
tot3+=3; // increment the "next multiple"
}
(same for 5)
Lone nebula also makes a good point - you'd need to add logic to the "5" loop to check it's not already counted in the 3 loop. The mod (%) operator can help there.

First,
while (tot3<10) {
three+=3;
tot3=tot3+three;
};
while (tot5<10) {
five+=5;
tot5=tot5+five;
};
This should be
while (three<10) {
three+=3;
tot3=tot3+three;
};
while (five<10) {
five+=5;
tot5=tot5+five;
};
Because you're concerned about when you start counting numbers above 10, not when your TOTAL of those numbers is above 10.
Secondly, your solution will count numbers that are a multiple of three and of five twice. For example, 15 will be added twice. Learn about the modulo operator, %, to come up with a solution to this (for example, not adding five to the tot5 count if five % 3 == 0)

I would recommend looking into using the modular operator to solve this problem. In java % will allow you to perform modular arithmetic. For example any multiple of 3 such as 9 % 3 = 0 while 9 % 2 = 1. It can be thought of as what remains after you divide the first number by the second. All multiples of a number modded by that number will return zero.

Keep track of your variables through the loop and you'll see the problem:
for tot3
=3
=9
=18
=30
You're keeping track of the sum, instead of tracking the multiples. This problem is partially solved in by
while(three<10)
Again, keeping track of the variable through the loop you'll see that this is wrong- it stops at 12, not 9 as you want it. Change it to
While(three<9)
//ie the last divisible number before the limit, or that limit if its divisible (in the case of 5)
All said, an infinitely more elegant solution would involve modulus and a nice little if statement. I hope this helps!

public class project1 {
public static void main(String[] args) {
int number = 0;
int total = 0;
while (number < 10) {
System.out.println(number);
if ((number % 3) == 0) {
System.out.println(number + " is a multiple of 3");
total = total + number;
}
else if ((number % 5) == 0) {
System.out.println(number + " is a multiple of 5");
total = total+number;
}
number++;
}
System.out.println("total = "+ total);
}
}
Looking at how slow I was, I did roughly the same thing as everyone else but swapped to a modulus function. The modulus function gives you the remainder(int) of dividing the first number by the second number, and can be compared to another integer. Here I have used it to check if the current number is directly divisible by 3 or 5, and add it to the total if the value is true.

Try this
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
long n = in.nextLong()-1;
System.out.println((n-n%3)*(n/3+1)/2 + (n-n%5)*(n/5+1)/2 - (n-n%15)*(n/15+1)/2);
}
}
}

Related

Program isn't terminating for a specific input

I am trying to write a program that will let me know if a number has the odd divisor greater than one. Let's n be the number, and x be the divisor. x%2!=0 and x>1;
Code:
import java.util.Scanner;
public class Simple1{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
long n;
for(int i=0; i<t; i++) {
n=sc.nextLong();
if(n<3)System.out.println("NO");
else {
if(n%2!=0)System.out.println("YES");
else {
int ans=0;
for(long j=3; j<=n/2; j+=2) {
if(n%j==0) {
ans=1;
break;
}
}
if(ans==1)System.out.println("YES");
else System.out.println("NO");
}
}
}
}
}
This java code works fine. But it's not working for a specific input.. and that is n = 1099511627776. If I change the last digit to any int other than 6, then it works fine and gives output. Even numbers greater than that works. But only this number n=1099511627776, when I input this to my program, no terminating happens and no output. Help me to figure out what happens here.
The number 1099511627776 is two to the power 40. That means it has to check through the whole big for-loop to find no odd factors. You would get the same problem, to different extents, with 2199023255552 (2 to the 41) and 549755813888 (2 to the 39). You have to wait longer if you want to do it this way.
A much faster way is to divide n by 2 until you get an odd number.
E.g.
long n = sc.nextLong();
while (n > 1 && n % 2 == 0) {
n /= 2;
}
if (n > 1) {
System.out.println("Yes.");
} else {
System.out.println("No.");
}
An even faster way to tell if a number is a power of two is a bit-twiddling hack:
// Powers of 2 have the property that n & (n-1) is zero
if ((n & (n - 1)) != 0) {
System.out.println("Yes."); // Not a power of two, so has an odd factor
} else {
System.out.println("No."); // Is a power of two, so does not have an odd factor
}
Can you get rid of the powers of two another way?
long number = 1099511627776l;
long r = number >> Long.numberOfTrailingZeros​(number);
Then r is an odd divisor, which might be greater than one.
If you think in base 10, then you know a number is divisible by ten if has a trailing zero. You can remove all of the powers of 10 by removing all of the zeros. It is the same for base 2, you can remove all of the factors of 2 by removing all of the trailing zeros (in binary representation).

Methods That Return Values Quiz

I am super new to programming and I had a question on a quiz and the output answer was 36. I don't understand how that outcome came out of this code.
public class Method {
public static int method(int number) {
int result = 0;
while ( number > 0) {
result += number % 10;
number = number / 10;
}
return result;
}
public static void main (String[] args) {
System.out.println(method(9999));
}
}
Clearly within this code the part we need to look at is the while loop, this is the area of interest because it's where all of the calculation occurs.
while(number > 0){
result += number % 10;
number = number/10;
}
So the first line within the loop will add a value to the result:
result += number % 10;
The % operator in Java and many other languages can be thought of as a remainder of division, hence we are adding the remainder of division by 10 to the result.
9999 / 10 = 999 remainder 9.
So result has 9 added.
Then we call:
number = number / 10;
In Java when dividing an int we do not consider the remainder, so 9999/10 = 999.
And then we repeat. So essentially we are adding up the digits of the number.
9 + 9 + 9 + 9 = 36.
Even if you are new at programming, you could try to use an IDE like Eclipse.
Using an IDE you can use the breakpoints and follow the code line by line and the variable line by line. So you will understand what happens.
You could create a watch expression that will show on a tab the variable to you or use the inspect to do this.
A video: https://www.youtube.com/watch?v=drk_ldaRMaY

Wrong results for bigger values

I was trying a programming problem, the statement is
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Like this we have to find the sum of multiples for 't' test cases with 'n' value each, I have tried to find the solution and my code is
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
long t,n,sum;
Scanner in=new Scanner(System.in);
t=in.nextLong();
for(int i=0;i<t;i++)
{
sum=0;
n=in.nextLong();
long l3=0,l5=0,l15=0;
for(int j=3;j>0;j--)
if((n-j)%3==0&&j<n)
{
l3=n-j;
break;
}
for(int j=5;j>0;j--)
if((n-j)%5==0&&j<n)
{
l5=n-j;
break;
}
for(int j=15;j>0;j--)
if((n-j)%15==0&&j<n)
{
l15=n-j;
break;
}
sum+=(float)(((float)l3/(float)3)/(float)2)*(float)(l3+3);
sum+=(float)(((float)l5/(float)5)/(float)2)*(float)(l5+5);
sum-=(float)(((float)l15/(float)15)/(float)2)*(float)(l15+15);
System.out.println(sum);
}
}
}
And the input I gave was,
12
10
11
12
13
1000
1001
1002
1003
100000000
100000001
100000002
100000003
Here 12 is the number of test cases.
And the output I got was
23
33
33
45
233168
234168
234168
235170
2333333593784320
2333333593784320
2333333593784320
2333333593784320
The problem here is the answer is correct for values in the test case 10,11,12,13,1000,1001,1002,1003 but the output is wrong for remaining bigger inputs. I cant find what i am missing. Could you please help me on why I am getting this kind of wrong result and how to rectify it.
You can get a higher precision and a larger numbers by using BigDecimal and BigInteger:
package test;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
long t,n;
BigInteger sum;
Scanner in=new Scanner(System.in);
t=in.nextLong();
for(int i=0;i<t;i++)
{
sum = BigInteger.ZERO;
n=in.nextLong();
long l3=0,l5=0,l15=0;
for(int j=3;j>0;j--)
if((n-j)%3==0&&j<n)
{
l3=n-j;
break;
}
for(int j=5;j>0;j--)
if((n-j)%5==0&&j<n)
{
l5=n-j;
break;
}
for(int j=15;j>0;j--)
if((n-j)%15==0&&j<n)
{
l15=n-j;
break;
}
BigDecimal x = BigDecimal.valueOf(l3)
.divide(BigDecimal.valueOf(6))
.multiply(BigDecimal.valueOf(l3+3));
sum=sum.add(x.toBigIntegerExact());
x = BigDecimal.valueOf(l5)
.divide(BigDecimal.valueOf(10))
.multiply(BigDecimal.valueOf(l5+5));
sum=sum.add(x.toBigIntegerExact());
x = BigDecimal.valueOf(l15)
.divide(BigDecimal.valueOf(30))
.multiply(BigDecimal.valueOf(l15+15));
sum=sum.subtract(x.toBigIntegerExact());
System.out.println(sum);
}
}
}
Without deeper analysis of your code I would guess the problem is that you are using float, which has a quite short value range. Could you try double instead? Not sure what the correct answer would be, but at least you get different results (I just tried)
The solution looks too complex for such a task. I don't understand why do you need to perform the divisions at the end. You can try the following code:
int t = <some number> // the upper bound
int[] dividers = [...] // those are divisors against which we have to test
long sum = 0;
// check all the number up the bound
for (int number = 1; number < t; number++) {
for (int i = 0; i < dividers.length; i++) {
if (number % dividers[i] == 0) {
// the number is divisible without remainder -> add it to the sum
sum += number;
break;
}
}
}
The idea is to iterate all the numbers you want to check and see if they are divisible by some of the N dividers. If you find a number, you add it to the sum and continue with the next one.
Edit:
After the clarifications from OP, I came up with another way to do this.
int t = <some number> // the upper bound
int dividers = [3, 5];
int dividerProduct = dividers[0] * dividers[1];
long sum = calculateSumForDivider(dividers[0], t) + calculateSumForDivider(dividers[1], t) - calculateSumForDivider(dividerProduct, t);
public static int calculateSumForDivider(int divider, int number) {
int n = number / divider;
return divider * n * (n + 1) / 2;
}
What is the logic behind all this?
By dividing the target number, we can calculate how many times does the divider "fit" in the target. This is also the number of numbers in the interval [1, number] that are divisible by the divider. Let's see an example:
t = 10, divider = 3
10 / 3 = 3, so they are 3 numbers in the interval [1, 10], divisible by 3
the numbers are: 1 * 3, 2 * 3, 3 * 3
if we calculate the sum we get 1 * 3 + 2 * 3 + 3 * 3 = 3 * (1 + 2 + 3) = 18
analogically, for = 10, divider = 5
10 / 5 = 2
1 * 5 + 2 * 5 = 5 * (1 + 2) = 15
As a conclusion, we have the following formula for the sum:
sum = divider * n * (n + 1) / 2
where n is the result of the division.
The gotcha here is that numbers, divisible by both 3 and 5 (in other words divisible by 15) are going to be added twice to the sum. To correct this we use the same formula as above to calculate their sum and subtract it from the resulting some, reaching the result.
This solution will only work well for 2 dividers, since with multiple the number of numbers that will be added multiple times to the sum will grow exponentially. F.e. if we want to divide be 3, 4 or 5, we will need to take care of 12, 15, 20, 60, etc.
This will also not work if the two one of the dividers is a power of the other, like 3 and 9. In that case we only need the numbers, divisible by 3.
I am not sure about your algorithm because the simplest one should be like:
sum=0;
n=100100000;
for(int j=1;j<n;j++)
if(j%3==0 || j%5==0)
{
sum+=j;
}
System.out.println(sum);
System.out.println(n*n);
And to get a better idea on what should be the result, it is always less than n*n.
The output I found was:
2338002249916668
10020010000000000
So, as your results where less than n*n, if you are sure about you algorithm, then they are correct.

How to find prime factorization of number using loop?

I'm supposed to find the prime factorization of this number: 600851475.
Prime factorization, according to my teacher and this website, http://www.mathsisfun.com/prime-factorization.html, are prime numbers that multiplied give you that number. So for example 12, even though its factors are 2,3,4,6, the prime factors WON'T be just 2 & 3, but 2,2,3.
I have the algorithm to find a prime factor allready, but I can't find a way to loop so that it keeps finding the rest until there are no more prime factors.
This is what i got:
public class primeFactors {
public static void main(String[] args) {
int d= 600851475;
int i = 2;
if (d%i!=0) {i++;}
if (d%i==0) {d=d/i;}
System.out.println(i);
}
}
and it prints this: 3.
If i copy paste it multiple times it does print different things:
public class primeFactors {
public static void main(String[] args) {
int d= 600851475;
int i = 2;
if (d%i!=0) {i++;}
if (d%i==0) {d=d/i;}
System.out.println(i);
if (d%i!=0) {i++;}
if (d%i==0) {d=d/i;}
System.out.println(i);
if (d%i!=0) {i++;}
if (d%i==0) {d=d/i;}
System.out.println(i);
if (d%i!=0) {i++;}
if (d%i==0) {d=d/i;}
System.out.println(i);
}
}
That one prints: 3, 3, 4, 5, 5.
How can I do this with loops? I tried with do while loops( do { if section} while (d>i) {print i} ), but it doesn't work. I also tried with for loop (i=2;i<=d;i++) & it doesn't work. It gives me composite numbers too.
HELP PLEASE!!
Since this is an assignment, the most I'll give you is a general direction: the easiest way to write this will be to try candidate divisors and reduce. For example:
130 - try 2, it divides, so reduce
65 - maybe there's another 2 in there? try 2 again. It doesn't divide, so move on
65 - try 3 - no. 4? no. 5? yes, it divides, so reduce.
13 - Is there another 5 in there? no. try 6, 7, 8, 9, 10, 11, 12. Okay, you're done.
So you need to try candidate divisors in a loop, and you need an inner loop to make sure you cast out any repeated factors (for example, 525 will have the prime factors 3, 5, and 7 but you still want to get rid of that second 5). That should get you on the right track.
Clearly, there will be more efficient ways to write this, but if you're stuck, start with the simplest possible thing that could work, and get that working.
You only need something like this (Perhaps this is not the most efficient way but it was pretty straight forward and easier to understand) :
int d= 600851475;
for (int i = 2 ; i < (d / 2) ; i++){
if(isPrime(i)){
if(d % i ==0){
System.out.println(i + "Is a prime factor of " + d);
}
}
}
But first you will need to have this method that check if it is a prime number or not
public static boolean isPrime(int n){
for(int i = 2 ; i < n ; i++){
if(n % i == 0){
return false;
}
}
return true;
}
Try to use a for loop.
for (int i = 2; i <= d; i++)
{
//implement if statement here
}
This should point you in the right direction.
You have the right idea. You need to divide each factor until it no longer divides.
// this will print all prime divisors for n
for (int i = 2; n != 1; i++)
{
while (n % i == 0)
{
System.out.println (i);
n /= i;
}
}
How to find the prime factorization of a number?
Here is what I tried:
def p_factorization(n):
#Finding the factors of n.
num=[i for i in range(1,n+1) if n%i==0]
#Finding the prime factors of n.
#Now prime_num checks to see if any of the factors of 36 have more than two "subfactors".
prime_num=[i for i in range(2,max(num)) if len([j for j in range(1,i+1) if i%j==0])<=2 and max(num)%i==0]
return prime_num
#Explanation:
#The num list is self-explanatory. It finds all of the factors of the number n.
#The prime_num list comprehension is where it gets complicated:
#The i represents all of the numbers in the range of the original factors that we found,
#then we know that a number is prime if it has two or fewer factors, hence the if condition
#applying to the len of the factors of i, which is being iterated through.
#For example, 4 is not a prime number because the length of the list of factors is
#3 [1,2,4].
And of course, we still need max(num) to be divisible by i.
You are very welcome!

Euler Challenge 1 in Java - I'm doing something wrong?

http://projecteuler.net/problem=1
Hey. I'm a high schooler trying to get a good grasp on programming problems, so I visited Project Euler. For Problem 1, I wrote up some code in Java that would of solved it, but something is evidently going wrong. Can I get some insight as to what?
Explanation:
I stop everything at the index value of 332 because Java counts from 0, and 333 * 3 is 999 which is below 1,000. Apples is a seperate class with pretty much the same code, although it counts for 5. At the end, I manually add together the two answers, but it wasn't right. What am I doing wrong?
The two final sums are:
Three: 164838
Five: 97515
public class Learning {
public static void main(String[] args){
int three[] = new int[333];
int counter = 0;
three[332] = 0;
int totalthree = 0;
int threeincrementer = 1;
int grandtotal;
boolean run = true;
boolean runagain = true;
for (counter = 1; counter<=332; counter++){
three[counter] = 3 * counter;
if (!(three[332] == 0)){
System.out.println("Finished three.");
while (run == true){
totalthree = totalthree + three[threeincrementer];
threeincrementer++;
if (threeincrementer >= 332){
run = false;
System.out.println("Three final is: " + totalthree);
}
}
}
if (runagain == true){
apples ApplesObject = new apples();
ApplesObject.rerun(0);
runagain = false;
}
}
}
}
Some numbers are at the same time multiplication of 3 AND 5 like 15 so you shouldn't separately calculate sum of all multiplications of 3 and multiplications of 5 and than add them because you will end up doing something like
sum3 = 3,6,9,12,15,...
sum5 = 5,10,15,...
so first sum3 will include 15, and sum5 will also include it which means you will add 15 two times. Now to balance your calculations you will need to subtract from your sum3+sum5 sum which will add all multiplications of 15
sum15 = 15,30,45,...
So using your approach your final formula should look like sum3+sum5-sum15.
But simpler solution for this problem can look like
sum = 0
for each X in 1...999
if (X is multiplication of 3) OR (X is multiplication of 5)
add X to sum
To check if some number X is multiplication of number Y you can use modulo operator % (example reminder = X % Y) which finds the remainder of division of one number by another.
You can find more Java operators here

Categories

Resources