CSCI A201/A597

Lab Notes 2

Spring 2000


Take the lab quiz (Lab 2). Work on homework assignment 1 due at the end of the labs January 27-28.

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:

  1. if the number is even divide it by 2
    otherwise multiply it by 3 and add 1

  2. if the resulting value is not 1 repeat step 1
    otherwise stop
Given a certain number 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.

  1. 5 is not even so we multiply it by 3 and add 1 and we obtain 16
    16 is not 1 so we need to keep going

  2. 16 is even so we divide it by 2 and obtain 8
    8 is not 1 so we need to keep going

  3. 8 is even so we divide by 2 and obtain 4
    4 is not 1 so we need to go on

  4. 4 is even so we divide by 2 and obtain 2
    2 is not 1 so we need to go on

  5. 2 is even so we divide by 2 and obtain 1
    we have reached 1 so we can stop.

It turns out that for 5 it takes exactly 5 steps to reach 1.

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:

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%
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).


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

How does the solution above compares to the one you found?

Notice a few things about the solution above:

Now the homework asks you to accomplish two more things:
  1. accept two values, representing the range of values for which you want to run the program
  2. report the number with the max number of iterations in the given range (and the max value too)
It is expected of the user to type values that make sense, that is: The program should be working like this:
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%
Just think about computing the max value in a sequence of numbers?

How would you do it, if you were to do it by hand?

I would use a method such as this:

At the end, if I compute iterations correctly, and if I don't skip numbers, 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:

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%
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.

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

Write a program that behaves like this:
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();

    } 
} 

Note that a diamond is composed of four 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.