|
CSCI A201/A597 and I210
Lecture Notes Fourteen
Second semester 2000-2001
|
More examples (or practice problems) from chapter six.
|
Here's a program that helps with problem 6.1
|
What does it do?
|
|
Reads lines, one by one.
|
When does it end?
|
|
When you type Control-D.
|
Which is EOF (end of file).
|
Yes, in that case the line is null.
|
What does it do, line by line?
|
|
Looks at the tokens, and prints them in uppercase.
|
Let's see the program.
|
import java.util.*;
import java.io.*;
/* pages 239 - 241 and 246 - 250 */
class One {
public static void main(String[] args) {
ConsoleReader console = new ConsoleReader(System.in);
System.out.print("Hello>");
String line = console.readLine();
while (line != null) { // ^D would do it
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
System.out.println(token.toUpperCase());
}
System.out.print("Hello>");
line = console.readLine(); // what if we take this out?
}
System.out.println("End of program.");
}
}
|
For both problem 6.2 and 6.3 the trick is to interpret (read and promptly evaluate) input.
|
I think I can demo that.
|
|
You're going to read a rate, then numbers, finished by zero...
|
... then numbers again, ending with EOF.
|
|
Which is Control-D (on Unix).
|
I could even end it with a keyword, such as "quit" or "bye",
or some other meaningful word.
|
import java.util.*;
import java.io.*;
class TwoAndThree {
public static void main(String[] args) {
ConsoleReader console = new ConsoleReader(System.in);
System.out.print("Rate>");
String line = console.readLine();
StringTokenizer tokenizer = new StringTokenizer(line);
double rate = Double.parseDouble(tokenizer.nextToken());
double amount;
do {
System.out.print("Dollars>");
line = console.readLine();
tokenizer = new StringTokenizer(line);
amount = Double.parseDouble(tokenizer.nextToken());
} while (amount > 0);
do {
System.out.print("Euros>");
line = console.readLine();
if (line == null || line.equalsIgnoreCase("quit"))
break;
tokenizer = new StringTokenizer(line);
amount = Double.parseDouble(tokenizer.nextToken());
} while (true);
System.out.println("Thank you for using this program.");
}
}
|
I see that you're assuming the user will never type
more than one number on a line.
|
Also, my error checking is minimal: the program ends with
EOF, or when user enters "quit", otherwise we
expect to read only numbers.
|
|
Also, you could get by without a tokenizer.
|
I think so, but I did that only for practice.
|
|
There are many ways of solving problem 6.4.
|
Yes, but empathy would not be one of them.
|
|
Of course. What I meant was that you need to generate random directions.
|
And you have more than one way to produce random numbers.
|
|
Let's use whatever the book uses.
|
It's a good book.
|
|
In addition to that I want to use an object oriented approach.
|
And bring a drunkard into the picture.
|
|
Exactly.
|
A drunkard is like a BankAccount.
|
import java.util.*;
class Drunkard {
int x, y;
Drunkard(int x, int y) {
this.x = x;
this.y = y;
}
void moveNorth() {
this.y -= 1;
}
void moveEast() {
this.x += 1;
}
void report() {
System.out.println("Hiccup: " + x + ", " + y);
}
}
class Four {
public static void main(String[] args) {
Random generator = new Random();
Drunkard drunkard = new Drunkard(100, 100);
int direction;
for (int i = 0; i < 100; i++) {
direction = Math.abs(generator.nextInt()) % 4;
if (direction == 0) { // N
drunkard.moveNorth();
} else if (direction == 1) { // E
drunkard.moveEast();
} else if (direction == 2) { // S
System.out.println("Should move South.");
} else if (direction == 3) { // W
System.out.println("Should move West.");
} else {
System.out.println("Impossible!");
}
drunkard.report();
}
}
}
|
Not bad at all.
|
Now let's look at 6.5 and 6.6.
|
|
Isn't a cannonball like a drunkard?
|
Yes, they're both tiggers.
|
|
They all deal directly with gravitational fields.
|
|
|
|
Cannonballs require more physics, though.
|
class Cannonball {
double x;
double y;
double vx;
double vy;
final double g = 9.81;
Cannonball(double speed, double angle) {
x = 0;
y = 0;
vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;
}
void move() {
double deltaT = 0.01;
x += vx * deltaT;
y += vy * deltaT;
vy -= g * deltaT;
}
void report() {
System.out.println("Located at: (" + x + ", " + y + ")");
}
double height() {
return y;
}
}
class FiveAndSix {
public static void main(String[] args) {
Cannonball c = new Cannonball(10, Math.PI / 4);
for (int i = 0; i < 10 * 100; i++) { // flying 10 seconds
c.move();
c.report();
if (c.height() < 0) {
System.out.println("SPLOOOF! The cannonball landed!");
break;
}
}
}
}
|
Could you also compute the highest point the cannonball gets to?
|
That would almost be problem 16, wouldn't it?
|
|
Yes.
|
We'd have to update our notion of a current maximum every time we
are looking at a height.
|
|
Come to think of it the cannonball could do it.
| Intelligent cannonball.
|
|
Intelligent, but misguided.
|
Well, here it is anyway:
|
class Cannonball {
double x;
double y;
double vx;
double vy;
final double g = 9.81;
double max;
Cannonball(double speed, double angle) {
x = 0;
y = 0;
vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;
max = 0;
}
void move() {
double deltaT = 0.01;
x += vx * deltaT;
y += vy * deltaT;
vy -= g * deltaT;
if (y > max) { max = y; }
}
void report() {
System.out.println("Located at: (" + x + ", " + y + ") ");
System.out.println(" max altitude so far: " + max);
}
double height() {
return y;
}
}
class Max {
public static void main(String[] args) {
Cannonball c = new Cannonball(10, Math.PI / 4);
for (int i = 0; i < 10 * 100; i++) { // flying 10 seconds
c.move();
c.report();
if (c.height() < 0) {
System.out.println("The cannonball landed!");
break;
}
}
}
}
|
You just added three lines?
|
Four, and yes, that was all.
|
|
But how often do those get executed?
|
They're part of the cannonball's movement.
|
|
Let's move on to problem 6.7.
|
This one is easy.
|
|
Yes, from two values we compute a third. And we keep
doing this over and over again.
|
Now only this new value and the most recent of
the two it was computed from should be kept.
|
|
And these two values are then added to compute a new value.
|
And the whole process is repeated, as follows:
|
for (int i = 3; i <= n; i++) {
fNew = fOld + fOlder;
fOlder = fOld;
fOld = fNew;
}
| Yes, that's it. |
This reminds me of another problem: |
| What problem is that? |
See if you can figure it for yourself. |
import java.io.*;
class Mistery {
public static void main(String[] args) {
ConsoleReader console = new ConsoleReader(System.in);
System.out.print("Pass the salt please: ");
double a = console.readDouble();
System.out.print("And the butter: ");
int n = console.readInt();
double xold, xnew;
xold = ... ;
do {
xnew = xold - (Math.pow(xold, n) - a) / (n * Math.pow(xold, n - 1));
xold = xnew;
System.out.println(" " + (Math.pow(xnew, n) - a));
} while (Math.abs(Math.pow(xnew, n) - a) > 0.001);
System.out.println(xnew);
System.out.println(Math.pow(xnew, n) + " " + a);
System.out.println("Thank you!");
}
}
P6.14 perhaps? But what's the ...?
|
It doesn't matter, if it has a value.
|
|
For this problem, at least.
|
Problems 6.9, 6.10, and 6.15 are easy,
although for 10 and 15 we need to wait until
we look at applets to do any graphics.
|
|
Let's do number 10.
|
OK, but I won't draw circles, I'll just create them.
|
|
Drunkards, circles, cannonbals: they're all the same.
|
|
|
|
Especially drunkards.
Here's the code:
|
import java.util.*;
class Ten {
public static void main(String[] args) {
System.out.print("Enter number of circles: ");
ConsoleReader console = new ConsoleReader(System.in);
int n = console.readInt();
System.out.println("Generating " + n + " circles.");
Random generator = new Random();
for (int i = 0; i < n; i++) {
int x = 100 + Math.abs(generator.nextInt()) % 200;
int y = 100 + Math.abs(generator.nextInt()) % 200;
int r = 10 + Math.abs(generator.nextInt()) % 40;
Circle e = new Circle(x, y, r);
System.out.println(e); // looks better when you draw it
}
System.exit(0);
}
}
class Circle {
double xCenter, yCenter, radius;
Circle (double x, double y, double r) {
xCenter = x;
yCenter = y;
radius = r;
}
public String toString() {
return "I am a circle at: (" +
xCenter + ", " + yCenter +
") with a radius of " +
radius;
}
}
|
Why is 6.15 easy?
|
Because it's like 10, and in addition you have complete information
about the position of the squares. You'll see, later.
|
|
Why is 6.15 hard?
|
Because you should come up with a formula for the position of a square
given its row and column (or line and column).
|
This way you can use a for loop for the lines,
|
... and another one for the columns.
|
|
One, inside each other.
|
Like for the patterns we developed last week.
|
|
And why is 6.9 easy?
|
Because you just have to compute two sums, and take
a square root at the end.
|
|
Why is 6.9 hard?
|
6.9 is not hard, but you have to read the problem carefully and use the right formula.
|
|
Which is the last one (second of the two).
|
The last one for today anyway.
|
|
We'll do 6.12, 6.13, and most of the examples from
6.17 through 6.21 next time. |
I can hardly wait.
|
Last updated: Feb 22, 2001 by Adrian German for A201