0

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.

8
  • Please format your code! Commented Dec 20, 2015 at 8:18
  • 4
    Re-read your assignment. I very much doubt a method named getHailstoneSequence()and returning a list is supposed to return a list of a single element. Commented Dec 20, 2015 at 8:19
  • it does not state that it must be a single element, it just gives me an error whenever I try and include anything other than an int, or if I try and simply print an int. It wants the arrayList and I am unsure how to use this. @JBNizet Commented Dec 20, 2015 at 8:21
  • you said negative number is not a valid input but then you said "if it is negative number multiply n*3+1" Commented Dec 20, 2015 at 8:24
  • It is a sequence: plus.maths.org/content/… You have to return the sequence which is more than 1 number. Use a while/for loop for that. Commented Dec 20, 2015 at 8:24

5 Answers 5

2

A possible answer can be found here:

Hailstone Sequence (Java)

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

1

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.

Comments

1

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:

66 Result

Error Result:

-5 result

2 Comments

The printed result is wrong. How can you go from 76 to 19 by dividing by 2? An iterative solution is much simpler (and efficient, and scalable).
shame :-) was more showing him how to split the main class and preconditions from his work. (fixed - it was missing adding it to the list when 1st recursed)
0

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);    
         }    

     }    
}  

3 Comments

Don't solve the assignment. If you do it, at least explain your solution, and format it correctly.
I thought it is not difficult at all to understand, still i explain it, i had just uses the recursion to solve the problem..
in my solution if n==1 the function return the list otherwise it call recursively itself based on value of n i had passed the arraylist as parameter so each time on function call it prevent creation of new arraylist object..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.