public class problem14 {
public static void main(String[] args) {
int biggest = 0;
int biggestNum =0;
for(int i = 1; i<1000001;i++){
if(Solve(i)>biggest){
biggest = Solve(i);
biggestNum = i;
}
}
System.out.println("Chain: " + biggest + "Number: " + biggestNum);
}
public static boolean evenorodd(int num){
//returns true if even, and returns false if odd
int lastNum = num % 10;
if(lastNum==0||lastNum==2||lastNum==4||lastNum==6||lastNum==8){
return true;
}else{
return false;
}
}
public static int Solve(int num){
int count = 1;
int end = 0;
while(end!=1){
if(evenorodd(num)){
num = num/2;
count+=1;
if(num==1){
end=1;
return count;
}
}
if(!evenorodd(num)){
num = 3*num +1;
count+=1;
if(num==1){
end=1;
return count;
}
}
}
return count;
}
}
Sorry guys, I already look up those problem 14 solutions, and I still couldn't figure out why my code doesn't give me the right answer. Please help me, I have trying to figure out for almost a hour now. I just need to know why I am not getting the right answer, since I have been testing out a lot of numbers.
The problem with your algorithm is that in your Solve() method,you are checking if(evenorodd(num)) and if(!evenorodd(num)) separately! Because of this even in case,if your num is even and is processed to yield true result but num becomes 1 at last,and hence it is also getting processed by if(!evenorodd(num)) because it has turned 1 // an odd number.
Second,instead of directly returning count from if-else block,you should better use break statement for exiting the loop and finally returning count!
Try reducing it to if(evenorodd(num)){...} else {...}.
Workout for your int Solve(num) method to ease your effort :-
public static int Solve(int num){
int count = 1;
int end = 0;
while(end!=1){
if(evenorodd(num)){
num = num/2;
count+=1;
if(num==1){
end=1;
break;
}
}
else
{
num = 3*num +1;
count+=1;
if(num==1){
end=1;
break;
}
}
}
return count;
}
I hope it helps and you obtain the correct answer! BEST WISHES...
Your algorithm is fine. You're blowing out on the range of an int. Use longs instead.
A Groovy solution for Project Euler 14
I got the above down-voted, so here's some more detail.
Shekhar is right, you shouldn't be retesting the same condition, but it's actually non-material to your algorithm in this case. A cycle can only complete from the first condition, an even number, anyway. The blog post talks about this and other optimisations you can do to speed up the computation.
You need to make "num" a long, even with the revised non-repeated test algorithm or at various points in your cycle it will exceed the range of an int, and this'll then give you a wrong answer.
Also, you shouldn't call Solve() twice in the outer "i" loop either, store the result of the first call in a variable and just assign it if it's greater.
All that said, you don't need all that code. Less code means less stuff that can go wrong. Here's a simple implementation of a Solve() function that does the job.
public static int Solve(long num) {
int count = 1;
while (num > 1) {
num = (num & 1) == 0 ? num / 2 : 3 * num + 1;
count++;
}
return count;
}
(num & 1) masks off all the bits except the last, so it leaves 0 for an even number, and 1 for an odd number. It's just a shorthand way of doing your evenorodd() function.
The =?: syntax (if you've not seen it before - this is a ternery operator) does the test, then what to return if true, then what to return if false. Again, just a shorthand for an if-then-else where you need to do a single value assignment.
Hope this helps.
Related
Homework assignment: I've been asked to create a method that will count all the odd numbers from 1 to value assigned to variable but it has to be with a while loop.
I've been using modulus to try and determine whether or not it's even or odd. I've tried identifying odd numbers and then just using + 2. I suspect it's a simple logic error I don't quite see.
public static void sumOddNumber(int number){
int counter =1;
while (counter <= number){
if (counter % 2 !=0){
System.out.println (+ number);
counter++;
}
}
}
My expectation was for it to compare counter to number(the user defined variable) and to keep performing the modulus operation and printing the result, until counter exceeds number. However when I enter a number it just prints that number and keeps grinding away.
Agreed with #forpas, your counter++ is only called once.
Try this...
public static void printOddNumber(int number){
int counter = 1;
while (counter <= number) {
if (counter % 2 !=0) {
System.out.println(counter);
}
counter++;
}
}
A somewhat better answer from a readability standpoint...
public static void printOddNumber(int number){
int counter = 1;
while (counter <= number) {
if (isOddNumber(counter)) {
System.out.println(counter);
}
counter++;
}
}
public static boolean isOddNumber(int number) {
return number % 2 != 0;
}
Once I removed the counter++ statement outside of the loop, I started receiving the correct number of iterations but all showing the number that I had input. I just had to change my System.out.println to display the correct variable, in this case 'counter' not 'number' like I had. My method ended up looking like the first example hooknc put up. Thanks to everyone for all the help.
How to exit from a method, i.e how can i return from a function in this recursion in java?
public class solution {
public static int countZerosRec(int input){
int n=0;
int k =0;
int count=0;
//Base case
if(n==0)
{
return; // How can i return the method from here, i.e how can i stop the execution of the recursive program now.
}
k=input%10;
count++;
n=input/10;
countZerosRec(n);
int myans=count;
return myans;
}
}
Please help me getting out of this method.
This is a program to count number of zeroes.
Example, 34029030 ans = 3
You can try below approach:
public class MyClass {
public static void main(String args[]) {
System.out.println("total zeroes = " + returnZeroesCount(40300));
}
public static int returnZeroesCount(int input){
if(input == 0)
return 0;
int n = input % 10;
return n == 0 ? 1 + returnZeroesCount(input / 10) : returnZeroesCount(input / 10);
}
}
How it works: Assuming your input > 0, we try to get the last digit of the number by taking the modulus by 10. If it is equal to zero, we add one to the value that we will return. And what will be the value that we would be returning? It will be the number of zeroes present in the remaining number after taking out the last digit of input.
For example, in the below case, 40300: we take out 0 in first step, so we return 1+number of zeroes in 4030. Again, it appears as if we have called our recursive function for the input 4030 now. So, we again return 1+number of zeroes in 403.
In next step, since last number is 3, we simply return 0+total number of zeroes in 40 or simply as total number of zeroes present in 40 and so on.
For ending condition, we check if the input is itself 0. If it is zero then this means that we have exhausted the input number and there are no further numbers to check for. Hence, we return zero in that case. Hope this helps.
If your main focus is to find number of zeroes in a given number , You can use this alternatively:
int numOfZeroes =0;
long example = 670880930;
String zeroCounter = String.valueOf(example);
for(int i=0; i< example.length();i++){
if(zeroCounter.charAt(i) ==0){
numOfZeroes++;
}
}
System.out.print("Num of Zeros are"+ numOfZeroes);` `
Instead of posting a code answer to your question, I'll post a few pointers to get you moving.
As #jrahhali said, as your code is, it'll not get past the return
statement inside the if block(which is an error BTW, because you have an int return
type).
I'd recommend that you move the last two lines to some calling
function(such as a main method). That way all this function will
need to do is do some basic processing and move forward.
You aren't checking k at all. As it is, your count is going to
always increment.
Hope this much is enough for you to figure things out.
int count =0;
private int getZeroCount(int num){
if(num+"".length == 1){
if(num==0){
count++;
}
return count;
}
if(num%10 == 0){
count++;
}
num /= 10;
getZeroCount();
}
Method1 :
public static int countZero1(int input) {
int count = 0;
//The loop takes the remainder for the value of the input, and if it is divided by 10, then its number of digits is 0.
// When the value of the input is less than 0, the cycle ends
while (input >0){
if (input % 10 == 0){
count ++;
}
input /= 10;
}
return count;
}
Method2 :
private static int count = 0;
public static int countZero2(int input) {
//Recursive call function
if (input % 10 == 0){
count ++;
}
input /= 10;
if (input <= 0){
return count;
}else {
return countZero2(input);
}
}
I was trying to make a method to do the prime factorization of a number, and it's probably not the most efficient, but I don't see why it shouldn't work.
public static ArrayList<Integer> primeFactorize(int num) {
ArrayList<Integer> primeFactors = new ArrayList<Integer>();
for (int i = 2; i < Math.sqrt((double) num); i++) {
if (isPrime(i) && factor(num).contains(i)) {
primeFactors.add(i);
num /= i;
if (isPrime(num)) {
primeFactors.add(num);
break;
}
i = 2;
}
}
return primeFactors;
}
It calls upon two other methods that I wrote named factor() and isPrime(), which do exactly what you would expect them to (returns an ArrayList of factors and either true or false depending on if the input is prime, respectively).
I went through the debugger with num being 12, and it worked fine for the first loop, where it added 2 to primeFactors. However, when it got to the top of the array again with num being 6 and i being 2, it exited the loop as if i < Math.sqrt((double) num) returned false.
But that wouldn't make sense, because the square root of 6 is a bit over 2. I also tried (double) i < Math.sqrt((double) num), but it just did the same exact thing.
Can anyone see what I'm missing? Thanks for any replies.
EDIT: Here is my code now, thanks for the help! I know for sure I could make it more efficient, so I might do that later, but for now this is perfect.
public static ArrayList<Integer> primeFactorize(int num) {
ArrayList<Integer> primeFactors = new ArrayList<Integer>();
int i = 2;
while (i < Math.sqrt((double) num)) {
if (isPrime(i) && num % i == 0) {
primeFactors.add(i);
num /= i;
if (isPrime(num)) {
primeFactors.add(num);
break;
}
i = 2;
}
else
i++;
}
return primeFactors;
}
In your for loop, the i++ section will get called at the end of every loop. So in your code, you set i equal to 2. Then, the loop ends, and adds 1 to i, making it be 3. Then the comparison happens, and 3 is more than sqrt(6), so the loop exits.
If you want i to be 2 in the next iteration, you need to set it to a value so that after the increment operation runs it will be 2, not before; in this case, you should set it to 1. A better solution would be to change your code structure so it's not necessary though. As pointed out by biziclop, a while loop will let you decide whether or not to increment, and will avoid this problem.
Since you already accepted an answer I assume your problem is solved. The thing I want to point out is that casting integers to doubles is generally a bad idea if there is another way. Therefore I want to show you the below implementation, which doesn't use floating-point arithmetic. Also I think it's a bad idea to check whether or not num is a prime number, because this slows down the algorithm. Moreover if num % i == 0 evaluates to true, i is always a prime number, thus the isPrime(i) check is superfluous and also slows down your algorithm.
List <Integer> primeFactors(int n) {
List<Integer> factors = new ArrayList<>();
for (int i = 2; i <= n / i; ++i) {
while (n % i == 0) {
factors.add(i);
n /= i ;
}
}
if (n > 1) {
factors.add(n);
}
return factors ;
}
Given a non-negative int n, how do i return the count of the occurrences of a digit e.g 7, so for example 717 yields 2? (no loops). Here is my code but it doesn't work well.
public int count7(int n) {
int count = 0;
if(n==7){
count++;
return count;
}
else if(n>7 && n<100)
return count7(n/10)+count7(n%10);
else if( n>100)
return count7(n/10)+count7(n%10);
else return 0;
}
Your code seems like it should be working. Not sure what you mean by "doesn't work well".
Here is an a bit cleaner/shorter version of the same solution:
int count7(int n) {
if(n == 0) return 0;
return (n%10 == 7 ? 1 : 0) + count7(n/10);
}
For the fun of it:
public static int count7( int n ) {
return Integer.toString( n )
.replaceAll( "[^7]" , "" )
.length();
}
Probably better fits to code golf ,-)
Here is a solution :
public int count(int number, int digit){
String numberToString = new Integer(number).toString();
String digitToString = new Integer(digit).toString();
return StringUtils.countMatches(numberToString,digitToString);
}
It will count for you how many digit are in number
So count(717,7) will return 2
A fast solution :
return Integer.toString(n).split("7").length-1;
When you want to look at the digits in the decimal representation of a number, it's usually reasonable to let the already available and optimized number stringification function do the job (that is Integer.toString(yournumber)). Of course there are loops behind, but there's even loops in the implementation of your recursive calls...
I am doing an excercise in the book "Java how to program". The excercise wants me to write a method that determines if a number is "prime". (A "Prime number" is a positiv integer which is only dividable with itself and 1). Then I am supposed to implement the method in an application that displays all integers up to 10 000.
I use "double-values" to test whether the remainder is 0 or not, to test dividability.
Anyway, I just don´t get the program to work, it displays all numbers fro 3, with an increement on how many times each number is displayed (3 44 555 etc). Can anyone please tell me what I´m doing wrong?
The code is the following:
public class Oppgave625
{
public static void main(String[] args)
{
for(double a = 2; a <= 10000; a++)
{
for(double b = 1; b < a; b++)
{
if (prime(a, b) !=0)
{
System.out.printf("%.0f ", prime(a, b));
}
}
}
}
static double prime(double x, double y)
{
if (x % y != 0)
{
return x;
}
else
{
return 0;
}
}
}
Use int instead. double is not good for this purpose
you might want to read this article to understand the use of the % Operator for floating point numbers.
Actually, there were many individual errors in here. I shortened the prime() function to the point where it was only a modulo op, so I was able to inline it. Second, I inverted the test so it checked for numbers that do not have a remainder, and continues to the next number as soon as it finds a divisor. Third, I changed b = 1 so that we do not check for numbers divisible by 1, because this would result to all numbers. Finally, I only print out the numbers for which we do not discover a divisor. The final result:
public static void main(String[] args) {
outer:
for (int a = 2; a <= 1000; a++) {
for (int b = 2; b < a; b++) {
if (a % b == 0) {
continue outer;
}
}
System.out.println(a);
}
}
Edit: I forgot to mention, I also changed the types from floats to ints, since I'm sure that's what you meant.
It's great that you posted sample code for this, but there are several things that are wrong:
you should not use a floating point type for this, but an int or a long. Floating point types should never be used for precise values.
you are making two calls to your prime function, effectively doubling the required steps
your prime function only tells you whether two numbers divide themselves evenly, it does not tell you whether one is a prime or not
for prime numbers, you should use a more efficient algorithm instead of calculating the same values over and over for each number. Look up Sieve of Eratosthenes.
You are approaching the problem like this: The number A is NOT prime, whenever i can find a number B that can divide A without a remainder.
Bur right now, you print out A whenever it is not dividable by B.
Instead you could say: whenever A not divisible by B, increase B. When i found a B to divide A, quit the inner loop, print nothing.
When i found no B, print A and quit loop.
Furthermore, you only have to test for divisibility of A until (a/2)-1.
A prime number is a number that is only divisible by one and itself. That is: one number. Your code is comparing two numbers as in the Euclidean algorithm for testing coprime-ness. This is very different than testing if a number is prime.
Your code should look something like this:
for i = 2 to 10,000 {
if( isPrime(i) ){
print i
}
}
function isPrime( int n ){
for i = 2 to n {
next if i == n
if( n % i == 0 ){
return 0;
}
}
return 1;
}
boolean isPrime = true;
for (int i = 2; i<=100; i++){
for(int j = 2; j<=i/2; j++){
isPrime = true;
if (i%j==0){
isPrime = false;
break;
}
}
if (isPrime){
Log.d("PrimeNumber",""+i);
}
}