Java Hailstone Sequence - java

I have to do a Hailstone Sequence code in Java for example it should go like this:
10 5 16 8 4 2 1 4 2 1
Mine goes like this:
10 5 16 8 4 2 1
How to fix this?
This is my code:
static int counter;
static int HailstoneNumbers(int Number)
{
System.out.print(Number+ " ");
if (Number == 1 && counter == 0) {
return counter;
}
else if (Number == 1 && counter != 0) {
counter++;
return counter;
}
else if (Number % 2 == 0) {
counter++;
HailstoneNumbers(Number / 2);
}
else if (Number % 2 != 0) {
counter++;
HailstoneNumbers(3 * Number + 1);
}
return counter;
}
public static void main(String[] args)
{
int Number;
KeyboardReader reader = new KeyboardReader();
System.out.println("What is your intial value? ");
Number = reader.readInt();
int x;
x = HailstoneNumbers(Number);
System.out.println();
System.out.println("Number of Steps: " +x);
}
}

Your code explicitly says to stop the sequence when it reaches the number 1. Maybe you meant the behavior to be different depending on the value of counter, but it isn't clear why it should not stop at the first 1 but should stop at the second (as counter will not be 0 for either).

Related

Issue with getting this java program to display the proper whitespace in the answer

So my problem is, my output seems to be correct except it is giving me 0/10 for credit because of the whitespace after the output counts down to one in each situation. It is saying I need a newline after the one but I have tried several things and it's the same output every time.
2.31 LAB: Hailstone sequence
Given a positive integer n, the following rules will always create a sequence that ends with 1, called the hailstone sequence:
If n is even, divide it by 2
If n is odd, multiply it by 3 and add 1 (i.e. 3n +1)
Continue until n is 1
Write a program that reads an integer as input and prints the hailstone sequence starting with the integer entered. Format the output so that ten integers, each separated by a tab character (\t), are printed per line.
The output format can be achieved as follows:
System.out.print(n + "\t");
Ex: If the input is:
25
the output is:
25 76 38 19 58 29 88 44 22 11
34 17 52 26 13 40 20 10 5 16
8 4 2 1
import java.util.Scanner;
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int n;
n = scnr.nextInt();
System.out.print(n + "\t");
int count = 1;
while (n > 1) {
if (n % 2 == 0) {
n = n * 1 / 2;
} else {
n = 3 * n + 1;
}
System.out.print(n + "\t");
count++;
if (count % 10 == 0) {
System.out.print("\n");
}
}
}
This is what I came up with and I am new to java so it is probably something I am overthinking, any thoughts would be appreciated.
"enter image description here" is not an image description
If nothing works, I guess you can trick it by just skipping the tab on the 10'th print. So instead of your normal System.out.print(n + "\t"); print try:
if ((count + 1) % 10 == 0) {
System.out.print(n);
} else {
System.out.print(n + "\t");
}
instead of your normal print.
I figured it out, I just needed to change the order of the code a little and make (n != 1) and System.out.print(n) at the very end. Thanks for the help.
try this, changed the print condition to exclude the tab for end value and when n is 1.
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int n;
n = scnr.nextInt();
System.out.print(n + "\t");
int count = 1;
while (n > 1) {
if (n % 2 == 0) {
n = n * 1 / 2;
} else {
n = 3 * n + 1;
}
count++;
if (count % 10 == 0) {
System.out.println(n);
}else{
if(n==1) {
System.out.print(n);
}else{
System.out.print(n + "\t");
}
}
}
}

Cannot print out 1 when doing Collatz contejure

I cannot print the 1 when wanting to program the Collatz contejure. Please help thanks.
Here is the problem: Given natural number n. Generate a sequence of integers, described in the Collatz conjecture:
Here is my code (Not snippet as it isn't clear (sample Input and Output at bottom):
import java.util.Scanner;
class test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
while (n > 1) {
System.out.println(n);
if (n % 2 == 0) {
n = n / 2;
} else {
n = (3 * n) + 1;
}
}
}
}
SAMPLE INPUT: 17
OUTPUT: 17 52 26 13 40 20 10 5 16 8 4 2
Need to print 1 as well
Just print 1 at the end of the loop.
while (n > 1) {
System.out.println(n);
if (n % 2 == 0) {
n = n / 2;
} else {
n = (3 * n) + 1;
}
}
System.out.println(1);
When demonstrating the Collatz Conjecture, you normally print after the computation, so move the print statement to the end of the loop. If you want to show what entered value was used to start the process, print it first, outside the loop.
System.out.println("Starting with " + n);
while (n > 1) {
if (n % 2 == 0) {
n = n / 2;
} else {
n = (3 * n) + 1;
}
System.out.println(n);
}

Print odd numbers in a descending order

The program needs to take an odd number and output it in a descending order
For example: if the input is 11 the output needs to be 11 , 9 , 7 , 5 , 3, 1.
I tried using a for loop but I can only seem to get it to work with even numbers not odd numbers
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int number = input.nextInt();
for (int i = number - 1; i >= 0; i--) {
if (i % 2 == 0) {
int descend = i;
System.out.println(descend + " ");
}
}
}
The output is the number in descending order but as even only. If I add a 1 into the descend variable the numbers would seem to descend in an odd manner but its not ideal.
This line returns true if the number is even:
if (i % 2 == 0) {
If you want to know when the number is odd:
if (i % 2 != 0) {
Also, why are you starting your count at 1 less than the input value:
int i = number - 1;
I think you want to do this:
for (int i = number; i > 0; i--) { // tests for numbers starting at the input and stopping when i == 0
Just replace (i%2==0) to (i%2==1)
Asking if the number % 2 is equal to zero is basically asking if the number is even, so what you really have to do is ask if the number % 2 is not equal to zero, or equal to 1
if (i % 2 != 0) {
int descend = i;
System.out.println(descend + " ");
}
Also, there's no need to subtract 1 from the user input so your for loop can be written like this
for (int i = number; i >= 0; i--) {
if (i % 2 == 0) {
int descend = i;
System.out.println(descend + " ");
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an an odd number: ");
int number = input.nextInt();
while(number%2==0){
System.out.print("Number must be odd number:" +
"(Ex:1, 3,5)\nTry again: ");
number=input.nextInt();
}
for (int i = number; i >= 0; i--) {
if(number%2!=0){
System.out.println(number);}
number-=1;
}
}

Terminated due to timeout error [duplicate]

I am working on a program that takes an integer and finds the number of combinations of consecutive sums that the integer has:
The number 13 can be expressed as a sum of consecutive positive
integers 6 + 7. Fourteen can be expressed as 2 + 3 + 4 + 5, also a sum
of consecutive positive integers. Some numbers can be expressed as a
sum of consecutive positive integers in more than one way. For
example, 25 is 12 + 13 and is also 3 + 4 + 5 + 6 + 7.
I researched and read that it's the number of odd factors minus one. So I wrote a program that finds the number of odd factors and my answer is still wrong in certain cases. Any insight?
Code seems to work fine but there is a crash due to Timeout which is probably due to optimization error.
The constraints for possible input size is
1 to 10^(12)
The code below is copied from alfasin's answer below:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
static long consecutive(long num) {
while (num % 2 == 0) num /= 2;
return consecutiveHelper(num);
}
public static long consecutiveHelper(long num) {
return LongStream.rangeClosed(3, (num / 2)).parallel().filter(x -> x % 2 != 0).map(fn -> (num % fn == 0) ? 1 : 0).sum();
}
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
final String fileName = System.getenv("OUTPUT_PATH");
BufferedWriter bw = null;
if (fileName != null) {
bw = new BufferedWriter(new FileWriter(fileName));
}
else {
bw = new BufferedWriter(new OutputStreamWriter(System.out));
}
int res;
long num;
num = Long.parseLong(in.nextLine().trim());
res = consecutive(num);
bw.write(String.valueOf(res));
bw.newLine();
bw.close();
}
}
This is what i currently have
As the post i answered to was duplicate, I copied my answer here as well.Let's try to find a pseudo-optimized method to resolve your problem :
What you need to do is to decompose your number in prime factors.
For example, if you take 1200 :
1200 = 2*2*2*2*3*5*5 = 1 * 2^4 * 3^1 * 5^2
You can then analyze how you could get odd factors with those prime factors. A quick analyze will tell you that :
odd * odd = odd
odd * even = even
even * even = even
With that in mind, let's find all the factors we get with odd * odd :
1 * 1 = 1
3 * 1 = 3
5 * 1 = 5
5 * 3 = 15
5 * 5 = 25
5 * 5 * 3 = 75
A quick way to find these combinations without writing them all is the "plus 1 method" : add 1 to the number of occurences of each prime odd factor, and multiply them together :
We found that 1200 = 1 * 2^4 * 3^1 * 5^2, so we can do :
("number of 3" + 1) ("number of 5" + 1) = (1 + 1) ( 2 + 1) = 6
There are 6 odd factors for the number 1200, and as you stated, remove 1 from that number to get the number of combinations of consecutive sums that 1200 has :
6 - 1 = 5 <-- woohoo ! finally got the result !
Now, let's look at the code. What we want to have is a Map, the keys being the prime factors and the values being the number of their occurences :
/*
If number is odd,
find the number in the keys and add 1 to its value.
If the number is not in the keys, add it with value = 1.
*/
public static void addValue(Map<Integer, Integer> factors, int i) {
if(i % 2 != 0) {
int count = factors.containsKey(i) ? factors.get(i) : 0;
factors.put(i, ++count);
}
}
/*
Classic algorithm to find prime numbers
*/
public static Map<Integer, Integer> oddPrimeFactors(int number) {
int n = number;
Map<Integer, Integer> factors = new HashMap<>();
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
addValue(factors, i);
n /= i;
}
}
if(n > 1) addValue(factors, n);
return factors;
}
With that, let's try to print what the map contains for number 1200 :
public static void main(String[] args) {
int n = 1200;
System.out.println(oddPrimeFactors(n));
}
$n : {3=1, 5=2}
Good ! Now let's finish the program with the method we developed before :
public static int combinations = 1;
public static void main(String[] args) {
int n = 1200;
oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
combinations--;
System.out.println(combinations);
}
$combinations = 5
Finished ! feel free to ask if you did not understand something !
Note : I tried my program with the max value Integer can handle and it took less than one second for my program to proceed, which seems pretty fast to me. It could probably be faster though, it's up to you to find the most optimized version of this code !
Here are the optimizations that we discussed in the comments section, see comments as markers:
static int consecutive(long num) {
while (num % 2 == 0) num /= 2; // 1st opt.
return consecutiveHelper(num)-1;
}
public static int consecutiveHelper(long num) {
long factorNumber = 1;
int count = 0;
while(factorNumber <= num / 2) { // 2nd opt.
if(num % factorNumber == 0) {
count++;
}
factorNumber += 2; // 3rd opt.
}
if (num % 2 != 0) {
count++;
}
return count;
}
UPDATE
I managed to reduce ~50% runtime for big-numbers (10^12) by using Java 8 Stream interface and running in parallel:
static long consecutive(long num) {
while (num % 2 == 0) num /= 2;
return consecutiveHelper(num);
}
public static long consecutiveHelper(long num) {
return LongStream
.rangeClosed(3, (num / 2))
.parallel()
.filter(x -> x % 2 != 0)
.map(fn -> (num % fn == 0) ? 1 : 0)
.sum();
}
That said, parallel will be more expensive when you're dealing with smaller numbers. If you want your answer to be optimal you should use both methods: for smaller numbers use the first and for large numbers use the latter.

Numbers to stop at the user's input

How do I make my program to stop at the user's input?
Here is my code:
public class H {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input x: ");
int x = input.nextInt();
for (int i = 0; i < x; i++) {
if (i < x)
System.out.print(printFib(i) + " ");
else if (i > x)
break;
}
}
public static int printFib(int number) {
if (number == 0 || number == 1)
return number;
else
return printFib(number - 1) + printFib(number - 2);
}
}
So, if I enter 10 my program should stop before the number. Example:
Input: 10
Output: 0 1 1 2 3 5 8
But instead I get 0 1 1 2 3 5 8 13 21 34
How can I fix it?
int x = input.nextInt();
int fib = 0;
while (fib < x){
System.out.print(printFib(fib)+ " ");
fib++;
}
}
Don't use a for loop which right now you're using to print out Fibonacci numbers until the number of items printed is less than the entered number. Instead use a while loop that stops when the Fibonacci number itself is greater than the entered number.
Since this is likely homework, I'm just going to give this suggestion and not a code solution, but please give a solution a try, and if still stuck, come back with questions.
Pseudocode
Get value of x
create fibonacci variable and assign it 0
while fibonacci is less than x
display current fibonacci number
calculate next fibonacci number and place in variable
end while loop
public class H {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input x: ");
int x = input.nextInt();
int i = 0;
while ( printFib(i) <= x ) {
System.out.print(printFib(i) + " ");
i ++ ;
}
}
public static int printFib(int number) {
if (number == 0 || number == 1)
return number;
else
return printFib(number - 1) + printFib(number - 2);
}
}
While the number return from the printFib() method is less than and equal to the user input, it then runs the method. I've tried the code and it works.

Categories