| CSCI A201/A597 Lecture Notes Seventeen
Second Summer 2000
|
Problem set six.
|
Here's a program that helps with problem 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.");
}
}
class ConsoleReader {
public ConsoleReader(InputStream inStream) {
reader = new BufferedReader(
new InputStreamReader(
inStream));
}
public String readLine() {
String inputLine = "";
try {
inputLine = reader.readLine();
} catch (IOException e) {
System.out.println(e);
System.exit(1);
}
return inputLine;
}
public int readInt() {
String inputString = readLine();
int n = Integer.parseInt(inputString);
return n;
}
public double readDouble() {
String inputString = readLine();
double x = Double.parseDouble(inputString);
return x;
}
private BufferedReader reader;
}
|
For both problem 2 and 3 the trick is to interpret input.
|
I think I can demo that.
|
|
You're going to read a rate, then numbers, finished by zero...
|
... then numbers again, finishing everything with EOF.
|
|
Which is Control-D.
|
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.");
}
}
class ConsoleReader {
public ConsoleReader(InputStream inStream) {
reader = new BufferedReader(
new InputStreamReader(
inStream));
}
public String readLine() {
String inputLine = "";
try {
inputLine = reader.readLine();
} catch (IOException e) {
System.out.println(e);
System.exit(1);
}
return inputLine;
}
public int readInt() {
String inputString = readLine();
int n = Integer.parseInt(inputString);
return n;
}
public double readDouble() {
String inputString = readLine();
double x = Double.parseDouble(inputString);
return x;
}
private BufferedReader reader;
}
|
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 by typing "quit", but otherwise the user
is expected to type numbers.
|
|
There are many ways of solving problem 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 5 and 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("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?
|
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 7.
|
This one is easy.
|
|
Yes, starting with two values we compute a third.
|
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!");
}
}
I think I know what problem it is, but what's ...?
|
It doesn't matter, if it has a value.
|
|
For this problem, at least...
|
Problems 9, 10, and 15 are easy.
|
|
Yes, let's do number 10.
|
OK, but I won't draw the circles, I will just create them.
|
|
Drunkards, circles, cannonbals: they're all the same.
|
|
|
|
Especially drunkards.
Here's the code:
|
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
class Ten {
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("Enter number: ");
int n = Integer.parseInt(input);
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;
Ellipse2D.Double e = new Ellipse2D.Double(x, y, r, r);
System.out.println(e); // looks better when you draw it
}
System.exit(0);
}
}
|
Why is 15 easy?
|
Because it's like 10, and in addition you have complete information
about the position of the squares.
|
|
Why is 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.
|
|
And why is 9 easy?
|
Because you just have to compute two sums, and take
a square root at the end.
|
|
Why is 9 hard?
|
9 is not hard, but you have to read the problem carefully and use the right formula.
|
|
Which is the last one.
|
The last one for today anyway.
|
|
We'll do 12, 13, and 17-21 tomorrow.
|
I can hardly wait.
|
Last updated: July 18, 2000 by Adrian German for A201