Reputation: 21
I am working on a question from an assignment. It is called the 3n+1 problem. The task is to get an integer from user (not 1 or negative number) and based on the number input (n), if it is even - divide by 2, and if it is negative - multiple n * 3 + 1.
The method I MUST use is as follows:
public static ArrayList<Integer> getHailstoneSequence(int n) {
^ this part is mandatory for my assignment, so it is necessary for me to work with an ArrayList of Integers.
I am struggling to make my program work. I can't figure out if I should store the input in the main method OR in my definition class. I also am not sure how to have the loop execute for even numbers in the main method without the redundancy of already having it stated in the definition class ( where my getHailstoneSequence() method is located).
Here is the code I have: (DEFINITION CLASS)
package question7;
import java.util.ArrayList;
public class HailstoneSequence {
// Method for computing the Hailstone Sequence:
public static ArrayList<Integer> getHailstoneSequence(int n) {
ArrayList<Integer> hailstoneSequence = new ArrayList<Integer>();
if (n % 2 == 0) {
n = n / 2;
hailstoneSequence.add(n);
}
else {
n = (n * 3) + 1;
hailstoneSequence.add(n);
}
return hailstoneSequence;
}
}
I am unsure how to include the method I created above into the main method for printing. I want the output to look like this (example):
5 is odd, so we make 3N+1: 16 16 is even, so we take half: 8 8 is even, so we take half: 4 4 is even, so we take half: 2 2 is even, so we take half: 1
And have the program stop whe n = 1
Here is what I have in my main method to date:
package question7;
import java.util.ArrayList;
import java.util.Scanner;
public class HailstoneSequenceTest {
public static void main(String[] args) {
Scanner hailstone = new Scanner(System.in);
System.out.println("To begin, please enter a positive integer that is not 1:");
int n = hailstone.nextInt();
ArrayList<Integer> list = HailstoneSequence.getHailstoneSequence(n);
for (int sequence : list) {
try {
if (n > 1) {
System.out.println("Great choice! Let's begin!");
System.out.println();
while (n % 2 == 0) {
System.out.println(n +
" is even, so we take half: " +
HailstoneSequence.getHailstoneSequence(n));
list.add(n);
if (n == 1) break;
while (n % 2 != 0) {
System.out.println(n +
" is odd, so I make 3n+1: " +
HailstoneSequence.getHailstoneSequence(n));
list.add(n);
if (n == 1) break;
}
// while (n == 1) {
// System.out.println(sequence);
// break;
}
}
}
catch (Exception error) {
while (n <= 1) {
System.out
.println("You did not enter a valid positive, greater than 1 integer. Please try again: ");
System.out.println();
n = hailstone.nextInt();
}
// End of HailstoneSequenceTest class
hailstone.close();
}
}
}
}
// }
Does anyone have any idea where I am going wrong? I know my code is probably wrong if multiple ways, I am just not sure where to start.
Do I need a for loop to hold the characteristics and increment ect.. ?
When I try to do this the way I know, it says I must return a ArrayList not an Int .
Please advise.
Upvotes: 0
Views: 13624
Reputation: 1517
A possible answer can be found here:
You can simply adapt this code to work with the arraylist instead of just assigning it to the variable
So something like this:
public static ArrayList<Integer> getHailstoneSequence(int n) {
ArrayList<Integer> result = new ArrayList<Integer>();
while(n !=1)
{
result.add(number);
if(n % 2 == 0) //even
{
n = n/2;
}
else //odd
{
n= n*3 + 1;
}
}
return result;
}
Upvotes: 2
Reputation: 53
I think that what you want.....
import java.util.ArrayList;
import java.util.List;
public class HailstoneSequence
{
public static ArrayList<Integer> getHailstoneSequence( ArrayList<Integer> hailstoneSequence,int n)
{
if(n==1)
return hailstoneSequence;
if (n % 2 == 0)
{
n = n / 2;
hailstoneSequence.add(n);
getHailstoneSequence(hailstoneSequence,n);
}
else
{
n = (n * 3) + 1;
hailstoneSequence.add(n);
getHailstoneSequence(hailstoneSequence, n);
}
return hailstoneSequence;
}
public static void main(String ar[])
{
ArrayList<Integer> hailstoneSequence = new ArrayList<Integer>();
int n=5;
List<Integer> list=getHailstoneSequence(hailstoneSequence,n);
for(Integer i:list)
{
System.out.println(i);
}
}
}
Upvotes: 0
Reputation: 1011
Here your code i have modified and its working,
public static ArrayList<Integer> getHailstoneSequence(int n) {
ArrayList<Integer> hailstoneSequence = new ArrayList<Integer>();
while(true)
{
if(n==1)break;
if (n % 2 == 0) { //if the remainder of n/2 is 0, then the number is even
hailstoneSequence.add(n);
n = n / 2;
}
else {
hailstoneSequence.add(n);
n = (n * 3) + 1;
}
}
return hailstoneSequence;
}
public static void main(String[] args) {
Scanner hailstone = new Scanner(System.in);//ask user for initial number input
System.out.println("To begin, please enter a positive integer that is not 1:");
int n = hailstone.nextInt();
ArrayList<Integer> list = AS.getHailstoneSequence(n);
int i=0;
// loop through all the numbers
for (int sequence : list) {
try
{
if(sequence==1)break;
if(sequence%2==0)
{
System.out.println(sequence + " is even, so I take half: " + (sequence/2));
}
else
System.out.println(sequence+ " is odd, so I make 3n+1: " + ((3*sequence)+1));
i++;
}
catch (Exception error) {
while (n <= 1) {
System.out
.println("You did not enter a valid positive, greater than 1 integer. Please try again: ");
System.out.println();
n = hailstone.nextInt();
}
}
and its out put is as,
To begin, please enter a positive integer that is not 1:
12
12 is even, so I take half: 6
6 is even, so I take half: 3
3 is odd, so I make 3n+1: 10
10 is even, so I take half: 5
5 is odd, so I make 3n+1: 16
16 is even, so I take half: 8
8 is even, so I take half: 4
4 is even, so I take half: 2
2 is even, so I take half: 1
The process took 9 to reach 1.
Upvotes: 1
Reputation: 76536
I had a go, here you check the preconditions of your input in the main method. Then call your rules recursively until you hit the end condition.
public class MakeItRain {
public static void main(String[] args) {
System.out.println("To begin, please enter a positive integer that is not 1:");
Scanner userInput = new Scanner(System.in);
int n = userInput.nextInt();
if (n <= 0) {
throw new IllegalArgumentException("I told you to enter a positive number! Wtf is " + n);
}
if (n == 1) {
throw new IllegalArgumentException("I told you to not enter 1! Come on man!");
}
List<Integer> hailstones = HailstoneSequence.getHailstoneSequence(n);
System.out.println(hailstones);
}
private static class HailstoneSequence {
public static List<Integer> getHailstoneSequence(int n) {
List<Integer> sequence = new ArrayList<>();
if (recurse(sequence, n)) {
return sequence;
}
return sequence;
}
private static boolean recurse(List<Integer> sequence, int input) {
int currentHailstone = getNewHailstone(input);
sequence.add(currentHailstone);
if (sequenceComplete(currentHailstone)) {
return true;
}
return recurse(sequence, currentHailstone);
}
private static int getNewHailstone(int hailstone) {
if (isEven(hailstone)) {
hailstone /= 2;
} else {
hailstone = (hailstone * 3) + 1;
}
return hailstone;
}
private static boolean isEven(int n) {
return n % 2 == 0;
}
private static boolean sequenceComplete(int rollingResult) {
return rollingResult == 1;
}
}
}
66 Result:
Error Result:
Upvotes: 1
Reputation: 692013
This method should return the whole sequence.
The sequence starts with the number entered by the user. So that should be the first element in the returned list:
list.add(n);
It ends when the number becomes 1. You should thus have a loop that ends when n
becomes 1:
while (n != 1) {
...
}
Inner elements should be obtained by computing the next sequence value from the previous one, and adding it to the list:
n = computeNextSequenceValue(n);
list.add(n);
I let you assemble the pieces of the puzzle. This is an assignment after all.
Upvotes: 1