CSCI A201/A597 and I210

Lecture Notes Thirteen

Second semester 2000-2001


Nested loops, other loops, loops and a half, Monte Carlo problems.
Let's practice a bit with for loops. Can you print the numbers from 0 to 9?

Easy: What if you want to print the numbers on the same line?
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	for (int i = 0; i < 10; i++) {
	    System.out.println(i); 
	} 
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
0
1
2
3
4
5
6
7
8
9
frilled.cs.indiana.edu%

Just use print in the loop, ... and one (empty) println outside of it:
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	for (int i = 0; i < 10; i++) {
	    System.out.print(i); 
	} 
	System.out.println(); 
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
0123456789
frilled.cs.indiana.edu%

Very good. But don't you want to spaced them out a bit?

OK, I will print each number in parentheses. Looks good. Can you write 10 such lines?
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	for (int i = 0; i < 10; i++) {
	    System.out.print(" (" + i + ")"); 
	} 
	System.out.println(); 
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
frilled.cs.indiana.edu%

Let me first highlight the code that prints a line. The part that you have in blue.
class One {
    public static void main(String[] args) {
	for (int i = 0; i < 10; i++) {
	    System.out.print(" (" + i + ")"); 
	} 
	System.out.println(); 
    } 
}

Exactly. Now let's do that 10 times. Use a for loop, with a different index, j.

Why j, when I can call it line? Caling it line would be fine with me.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	for (int line = 0; line < 10; line++) {
	    for (int i = 0; i < 10; i++) {
		System.out.print(" (" + i + ")");
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
 (0) (1) (2) (3) (4) (5) (6) (7) (8) (9)
frilled.cs.indiana.edu%

Looks good, doesn't it? Relax. I marked two of the (4)'s in your output with red and blue. Can you tell me what the difference is between them?

They appear on different lines. Indeed, for the first one line is zero, and for the second one line is 3.

Let me change the output to include information about this second dimension. Good idea.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	for (int line = 0; line < 10; line++) {
	    for (int i = 0; i < 10; i++) {
		System.out.print(" (" + line + ", " + i + ")");
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
 (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9)
 (1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) (1, 9)
 (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (2, 9)
 (3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) (3, 9)
 (4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) (4, 9)
 (5, 0) (5, 1) (5, 2) (5, 3) (5, 4) (5, 5) (5, 6) (5, 7) (5, 8) (5, 9)
 (6, 0) (6, 1) (6, 2) (6, 3) (6, 4) (6, 5) (6, 6) (6, 7) (6, 8) (6, 9)
 (7, 0) (7, 1) (7, 2) (7, 3) (7, 4) (7, 5) (7, 6) (7, 7) (7, 8) (7, 9)
 (8, 0) (8, 1) (8, 2) (8, 3) (8, 4) (8, 5) (8, 6) (8, 7) (8, 8) (8, 9)
 (9, 0) (9, 1) (9, 2) (9, 3) (9, 4) (9, 5) (9, 6) (9, 7) (9, 8) (9, 9)
frilled.cs.indiana.edu%

It was an easy change. I see, the part in blue is new.

Now I have 100 cells in the output, and I have a name for each one of them. Yes, line and i, as a pair of numbers.

Might as well rename i as something more meaningful. Such as column.

And let's ask the user to specify the size of the square (number of lines and columns). Use ConsoleReader for that.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		System.out.print(" (" + line + ", " + column + ")");
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 4
 (0, 0) (0, 1) (0, 2) (0, 3)
 (1, 0) (1, 1) (1, 2) (1, 3)
 (2, 0) (2, 1) (2, 2) (2, 3)
 (3, 0) (3, 1) (3, 2) (3, 3)
frilled.cs.indiana.edu%java One
What size? 6
 (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5)
 (1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5)
 (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5)
 (3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5)
 (4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5)
 (5, 0) (5, 1) (5, 2) (5, 3) (5, 4) (5, 5)
frilled.cs.indiana.edu%

Looks good, doesn't it? Relax. What's new is in red and blue, isn't it?

Yes. It looks really good. I have 6 characters for each cell, and everything looks nice and tidy. Can you highlight the second column?

You mean the set of cells for which column is 1? You got it.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (column == 1) {
		    System.out.print("   **  "); 
		} else { 
		    System.out.print(" (" + line + ", " + column + ")");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 6
 (0, 0)   **   (0, 2) (0, 3) (0, 4) (0, 5)
 (1, 0)   **   (1, 2) (1, 3) (1, 4) (1, 5)
 (2, 0)   **   (2, 2) (2, 3) (2, 4) (2, 5)
 (3, 0)   **   (3, 2) (3, 3) (3, 4) (3, 5)
 (4, 0)   **   (4, 2) (4, 3) (4, 4) (4, 5)
 (5, 0)   **   (5, 2) (5, 3) (5, 4) (5, 5)
frilled.cs.indiana.edu%

I can do the first diagonal now. I know, the change is minor.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (column == line) {
		    System.out.print("   **  "); 
		} else { 
		    System.out.print(" (" + line + ", " + column + ")");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 6
   **   (0, 1) (0, 2) (0, 3) (0, 4) (0, 5)
 (1, 0)   **   (1, 2) (1, 3) (1, 4) (1, 5)
 (2, 0) (2, 1)   **   (2, 3) (2, 4) (2, 5)
 (3, 0) (3, 1) (3, 2)   **   (3, 4) (3, 5)
 (4, 0) (4, 1) (4, 2) (4, 3)   **   (4, 5)
 (5, 0) (5, 1) (5, 2) (5, 3) (5, 4)   **  
frilled.cs.indiana.edu%

What if you want to see both the last column and first diagonal? I don't know, you tell me.

Well, here's what I think: I go through all the cells anyway. Exactly.

I check their names. And if you can tell by their name

... that they belong to either the first diagonal or to the last column, ... you turn them on.

That's it. This would turn on all of the cells that appear on the first diagonal and all of those that appear on the last column. It's just a union of sets.

Easy for you to say that, but here's the program: Looks good.
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (column == line || column == (size - 1)) {
		    System.out.print("   **  "); 
		} else { 
		    System.out.print(" (" + line + ", " + column + ")");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 6
   **   (0, 1) (0, 2) (0, 3) (0, 4)   **  
 (1, 0)   **   (1, 2) (1, 3) (1, 4)   **  
 (2, 0) (2, 1)   **   (2, 3) (2, 4)   **  
 (3, 0) (3, 1) (3, 2)   **   (3, 4)   **  
 (4, 0) (4, 1) (4, 2) (4, 3)   **     **  
 (5, 0) (5, 1) (5, 2) (5, 3) (5, 4)   **  
frilled.cs.indiana.edu%

And I was the first to say that. How can we make this look more like a square?

Maybe change the output a bit. How about this:
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (column == line || column == (size - 1)) {
		    System.out.print("* "); 
		} else { 
		    System.out.print("  ");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 8
*             * 
  *           * 
    *         * 
      *       * 
        *     * 
          *   * 
            * * 
              * 
frilled.cs.indiana.edu%

Now the names are only implicit. Only in our program's mind.

We draw patterns, scalable patterns. Here's code for a Z:
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (column == (size - 1 - line) ||
                    line   == 0                 || 
                    line   == (size - 1))
                {
		    System.out.print("* "); 
		} else { 
		    System.out.print("  ");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 7
* * * * * * * 
          *   
        *     
      *       
    *         
  *           
* * * * * * * 
frilled.cs.indiana.edu%java One
What size? 4
* * * * 
    *   
  *     
* * * * 
frilled.cs.indiana.edu%

Can you draw a circle? A circle?

Sure, why not? Of course:
frilled.cs.indiana.edu%cat One.java
class One {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.print("What size? "); 
	int size = c.readInt(); 
	for (int line = 0; line < size; line++) {
	    for (int column = 0; column < size; column++) {
		if (
 		      Math.abs( (line   - size / 2) * (line   - size / 2) +
 		                (column - size / 2) * (column - size / 2) - 
  		                (size -1) * (size - 1) / 4
			      ) <= (0.15 * size) 

                   ) 
                {
		    System.out.print("* "); 
		} else { 
		    System.out.print("  ");
		}
	    }
	    System.out.println();
	}
    } 
} 
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
What size? 20
                                        
              *           *             
          *                   *         
                                        
                                        
    *                               *   
                                        
  *                                   * 
                                        
                                        
                                        
                                        
                                        
  *                                   * 
                                        
    *                               *   
                                        
                                        
          *                   *         
              *           *             
frilled.cs.indiana.edu%

I hope you understand approximations. And the equation of a circle.

Now we need to move on. First a few simple, basic exercises.

Can you explain this? I sure can.
frilled.cs.indiana.edu%cat Two.java
class Two {
    public static void main(String[] args) {
	for (int i = 0; i < 10; i++) {
	    System.out.print(i); 
	}
	i = 10; 
	System.out.println(i); 
    }
}
frilled.cs.indiana.edu%javac Two.java
Two.java:6: Undefined variable: i
	i = 10; 
	^
Two.java:7: Undefined variable: i
	System.out.println(i); 
	                   ^
2 errors
frilled.cs.indiana.edu%

Can you fix it? I sure can.
frilled.cs.indiana.edu%cat Two.java
class Two {
    public static void main(String[] args) {
	int i; 
	for (i = 0; i < 10; i++) {
	    System.out.print(i); 
	}
	i = 10; 
	System.out.println(i); 
    }
}
frilled.cs.indiana.edu%javac Two.java
frilled.cs.indiana.edu%java Two
012345678910
frilled.cs.indiana.edu%

Let's look at other kind of loops. OK, here's a program that talks to the user.
frilled.cs.indiana.edu%cat Three.java
class Three {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	String line; 
	do {
	    System.out.print("Type something: "); 
	    line = c.readLine(); 
	    System.out.println("You typed: " + line); 
	} while (! line.equals("bye"));  
	System.out.println("Good bye!"); 
    } 
}
frilled.cs.indiana.edu%javac Three.java
frilled.cs.indiana.edu%java Three
Type something: I am here
You typed: I am here
Type something: You are there
You typed: You are there
Type something: Your name is Echo
You typed: Your name is Echo
Type something: Bye
You typed: Bye
Type something: bye
You typed: bye
Good bye!
frilled.cs.indiana.edu%

Using while is a bit longer. Yes, since the test comes first.
frilled.cs.indiana.edu%cat Three.java
class Three {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	String line; 
	System.out.print("Type something: ");
	line = c.readLine();
	System.out.println("You typed: " + line);
        while (! line.equals("bye")) { 
	    System.out.print("Type something: "); 
	    line = c.readLine(); 
	    System.out.println("You typed: " + line); 
	}	
	System.out.println("Good bye!"); 
    } 
}
frilled.cs.indiana.edu%javac Three.java
frilled.cs.indiana.edu%java Three
Type something: Works the same, doesn't it?
You typed: Works the same, doesn't it?
Type something: It does seem so. 
You typed: It does seem so. 
Type something: I am happy. 
You typed: I am happy. 
Type something: BYe
You typed: BYe
Type something: byE
You typed: byE
Type something: bye
You typed: bye
Good bye!
frilled.cs.indiana.edu%

In both cases we work with whole loops. Sometimes you know that you're done in mid-loop.

Yes, here's the loop and a half problem. This program reads lines from a file and reverses them.

When the line is empty there's nothing to be reversed. So the program simply quits the loop.

One can do that with break .. or using a boolean variable, and an if statement.

We choose the second approach, as being more structured. The first one is also often used, it simplifies code sometimes.
frilled.cs.indiana.edu%cat Four.java
class Four {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	boolean done = false; 
	String line; 
	while (! done) {
	    System.out.print("Echo> "); 
	    line = c.readLine(); 
	    if (line == null) { // EOF or ctrl-D for that
		done = true; 
	    } else {
		System.out.println(line); 
	    } 
	} 
    } 
} 
frilled.cs.indiana.edu%javac Four.java
frilled.cs.indiana.edu%java Four
Echo> Hello!
Hello!
Echo> I am here.
I am here.
Echo> How are you?
How are you?
Echo> I am fine, how about you?
I am fine, how about you?
Echo> You don't say...
You don't say...
Echo> I am going to type control-D now
I am going to type control-D now
Echo> Bye!
Bye!
Echo> frilled.cs.indiana.edu%

OK, let's make this more exciting, as if through the looking glass (as you said we would). Yes, s'tel esrever sretcarahc ni sdrow!
frilled.cs.indiana.edu%cat Four.java
class Four {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	boolean done = false; 
	String line; 
	while (! done) {
	    System.out.print("Echo> "); 
	    line = c.readLine(); 
	    if (line == null) { // EOF or ctrl-D for that
		done = true; 
	    } else {
		String rev; 
		int i; 
		for (i = line.length() - 1, rev = ""; i >= 0; i--) {
		    rev += line.charAt(i);
		}
		System.out.println(rev); 
	    } 
	} 
    } 
} 
frilled.cs.indiana.edu%javac Four.java
frilled.cs.indiana.edu%java Four
Echo> Hello!
!olleH
Echo> I say, that's Spanish.
.hsinapS s'taht ,yas I
Echo> Arabic?
?cibarA
Echo> What's going on, can you please tell me. 
 .em llet esaelp uoy nac ,no gniog s'tahW
Echo> Hmmm... 
 ...mmmH
Echo> :-)
)-:
Echo> ...ees I
I see...
Echo> .ahctoG
Gotcha.
Echo> frilled.cs.indiana.edu%

I like this guy, Gotcha. There once was a Polish carpenter, Zbigniew Gotcha, who lived in Kracow. You know the story?

No. I don't either, but I like the way it starts.

Well, OK. Time to wrap up. Let's do random numbers.

Yes, we kept for dessert. Do you like sherbet?

Let's program the following simulation: Oh, this is easy!
Darts are thrown at random points onto the square with corners (1 ,1) and (-1, -1).
If the dart lands inside the unit circle, that is, the circle with center (0, 0) and radius 1
it is a hit.
Otherwise
it is a miss.

Indeed, and here's the solution: Easy as !
frilled.cs.indiana.edu%cat Pi.java
import java.util.Random;

public class Pi {
    public static void main(String[] args) {
	Random r = new Random();
	double x, y, d;
	int i, count = 0;
	for (i=0; i < 100000 ; i++) {
	    x = r.nextDouble() * 2 - 1;
	    y = r.nextDouble() * 2 - 1;
	    d = Math.sqrt(x * x + y * y);
	    if (d < 1) count++;
	}
	System.out.println("Pi is approximately " + 4.0 * count / i);
    }
}

frilled.cs.indiana.edu%javac Pi.java
frilled.cs.indiana.edu%java Pi
Pi is approximately 3.13648
frilled.cs.indiana.edu%java Pi
Pi is approximately 3.15064
frilled.cs.indiana.edu%java Pi
Pi is approximately 3.14424
frilled.cs.indiana.edu%java Pi
Pi is approximately 3.1422
frilled.cs.indiana.edu%java Pi
Pi is approximately 3.1438
frilled.cs.indiana.edu%

Last updated: Feb 20, 2001 by Adrian German for A201