| CSCI A201/A597Lab Notes 2 Spring 2000 |
Read section 3.4.2 (page 79) in your text about Syracuse numbers. I will summarize it here. We work with positive numbers which are integers, and greater or equal than 2. For each such number consider the following iterative process:
n we are interested in how many times we need to execute
the first step (the if statement) until we reach 1 (the resulting value becomes 1).
Let's see how this works for a number, for example 5.
How long does it take for 8?
How about 3?
Or 27? (Can you do this one by hand?)
For 27 it actually takes over 100 iterations so doing it by
hand is likely to take a long time and produce errors too.
So let's write a program that given a number will count the number of
times we have to execute the if statement mentioned in the
pseudocode at the beginning of these notes before we reach a value of
1 (which, as the pseudocode says, is the end of the process).
Your program could work like this:
Try to write this program. If you cannot, simply highlight the portion between the horizontal bars below and you will see a solution for it. (The color of the font is white and that's why it doesn't appear unless you highlight the text).frilled.cs.indiana.edu%javac Syracuse.java frilled.cs.indiana.edu%java Syracuse 5 For 5 it takes 5 steps. frilled.cs.indiana.edu%java Syracuse 8 For 8 it takes 3 steps. frilled.cs.indiana.edu%java Syracuse 3 For 3 it takes 7 steps. frilled.cs.indiana.edu%java Syracuse 27 For 27 it takes 111 steps. frilled.cs.indiana.edu%
public class Syracuse {
public static void main(String[] args) {
int number = Integer.parseInt(args[0]);
int workingValue = number;
int count = 0;
while (workingValue > 1) {
if (workingValue % 2 == 0) {
workingValue = workingValue / 2;
} else {
workingValue = workingValue * 3 + 1;
}
count = count + 1;
}
System.out.println("For " + number + " it takes " + count + " steps.");
}
}Notice a few things about the solution above:
Integer.parseInt to turn the first argument into an int
number until the end so we use a copy of it for iterations
count, to count the number of times we go around the loop
2
Just think about computing the max value in a sequence of numbers?frilled.cs.indiana.edu%java Syracuse 15 30 15: 17 iterations. 16: 4 iterations. 17: 12 iterations. 18: 20 iterations. 19: 20 iterations. 20: 7 iterations. 21: 7 iterations. 22: 15 iterations. 23: 15 iterations. 24: 10 iterations. 25: 23 iterations. 26: 10 iterations. 27: 111 iterations. 28: 18 iterations. 29: 18 iterations. 30: 18 iterations. Max: 111 iterations, for [27] frilled.cs.indiana.edu%
How would you do it, if you were to do it by hand?
I would use a method such as this:
max to store the highest value
count for each number and once I found
a value that is bigger than the one I had stored in max I would store this
new, bigger value in max
max
would have the largest number of steps it takes to bring a number from the given range to 1
thought the process described. Can you see that? It is now quite easy to report the number for which that max number of iterations actually happens. I will leave it up to you to think about it.
Additional practice programs
Write a program that behaves like this:
That is it should be able to draw a triangle like the program in the lecture in which the size of the triangle is given by the user on the command line.frilled.cs.indiana.edu%javac Tri.java frilled.cs.indiana.edu%java Tri 3 * ** frilled.cs.indiana.edu%java Tri 6 * ** *** **** ***** frilled.cs.indiana.edu%java Tri 4 * ** *** frilled.cs.indiana.edu%java Tri 10 * ** *** **** ***** ****** ******* ******** ********* frilled.cs.indiana.edu%
Here's my solution:
public class Tri {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
for (int i = 0; i < size; i++) {
for (int j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
} frilled.cs.indiana.edu%javac Dia.java
frilled.cs.indiana.edu%java Dia 3
*
***
*****
*******
* *
** **
*** ***
*******
frilled.cs.indiana.edu%java Dia 4
*
***
*****
*******
*********
* *
** **
*** ***
**** ****
*********
frilled.cs.indiana.edu%java Dia 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
*********************
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********** **********
*********************
frilled.cs.indiana.edu%
That is, it draws a diamond in which the size of it
is given by the user on the command line. Also note that we switch the output mode when we draw the lower half of the diamond.
Here's my solution:
public class Dia {
public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
for (int i = size; i >= 0; i--) {
for (int j = 0; j < i; j++) {
System.out.print(" ");
}
for (int j = 0; j < 2 * (size - i) + 1; j++) {
System.out.print("*");
}
for (int j = 0; j < i; j++) {
System.out.print(" ");
}
System.out.println();
}
for (int i = 1; i <= size; i++) {
for (int j = 0; j < i; j++) {
System.out.print("*");
}
for (int j = 0; j < 2 * (size - i) + 1; j++) {
System.out.print(" ");
}
for (int j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
for (int j = 0; j < 2 * size + 1; j++) {
System.out.print("*");
}
System.out.println();
}
} Tri triangles, so maybe that would help. Or, two large triangles, if it's easier for you to think about it that way.
Either way, notice how there's a certain symmetry about it.