Reputation: 11
My assignment for class is to write a method that Returns a string consisting of a Hailstone sequence beginning with the positive integer n and ending with 1. The string should consist of a sequence of numerals, with each numeral followed by a single space. When a numeral m (other than 1) appears in the sequence, it should be followed by nextHailstone(m). For example, nextHailstone(1) should return "1 " and nextHailstone(5) should return "5 16 8 4 2 1 ".
I have the following code and can't figure out why it gets stuck in an infinite loop.
public static int nextHailstone (int n)
{
if (n==1)
{
return n;
}
if (n%2 == 0)
{
return n/2;
}
else
{
return ((3*n)+1);
}
}
public static String hailstones (int n)
{
String result = "";
result+=n;
result+= ' ';
while (true)
{
if (result.charAt(result.length()-2)=='1')
{
return result;
}
else
{
result +=(nextHailstone(result.charAt(result.length()-2)) + ' ');
}
}
}
Test cases:
public void testHailstones ()
{
assertEquals("1 ", hailstones(1));
assertEquals("16 8 4 2 1 ", hailstones(16));
assertEquals("7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 ", hailstones(7));
}
Upvotes: 1
Views: 179
Reputation: 393946
You are passing result.charAt(result.length()-2)
to nextHailstone
. This means you are passing a char
and your nextHailstone
operates on its int
value, and not on the digit represented by that char
. In addition, you only pass a single char
to the nextHailstone
. You don't handle multi-digit numbers.
For example, suppose you try halstones (1)
:
You set result
to "1 ". Then you pass '1' to nextHailstone
. But the char '1' is 49
as int
. So instead of returning 1
as you expect, it would return 49*3+1=148
. result
would be updated to "1 148 ".
At the next step you'll pass the char '8' (ignoring the 14
) to nextHailstone
, which is 56
as int. You can see why your loop will never terminate.
You should probably store the sequence in a List
of int
s, and only convert it to String
when you are ready to return the output.
You can do something like this :
public static String hailstones (int n)
{
List<Integer> seq = new ArrayList<Integer>();
seq.add(n);
while (true)
{
if (seq.get(seq.size()-1)==1)
{
return seq.toString(); // You might have to change that if you require
// the output in a different format
}
else
{
seq.add(nextHailstone(seq.get(seq.size()-1)));
}
}
}
Upvotes: 1
Reputation: 664
The reason your stuck in an infinite is that you have a while(true) loop. This will run infinitely unless broken. You never have the if statement true so it will continually run.
Upvotes: 1