1.5 Input and Output
In this section we extend the set of simple abstractions
(command-line input and standard output) that we have been
using as the interface between our Java programs and the
outside world to include standard input, standard draw,
and standard audio.
Standard input makes it convenient for us to write programs that process
arbitrary amounts of input and to interact with our programs; standard
draw makes it possible for us to work with graphics;
and standard audio adds sound.
Bird's-eye view.
A Java program takes input values from the command line and prints a string of characters as output. By default, both command-line input and standard output are associated with the application that takes commands (the one in which you have been typing the java and javac commands). We use the generic term terminal window to refer to this application. Here are some instructions for using the command line on your system. [ Windows · Mac · Linux ]- Command-line input. All classes have a main() method that takes a String array as argument. That array is the sequence of command-line arguments that we type, provided to Java by the operating system. By convention, both Java and the operating system process the arguments as strings, so if we intend for an argument to be a number, we use a method such as Integer.parseInt() to convert it from String to the appropriate type.
- Standard output. To print output values in our programs, we have been using System.out.println(). Java sends the results to an abstract stream of characters known as standard output. By default, the operating system connects standard output to the terminal window - all of the output in our programs so far has been appearing in the terminal window.
RandomSeq.java uses this model: It takes a command-line argument N and produces an output sequence of random numbers between 0 and 1.
To complete our programming model, we add the following libraries:
- Standard input. Read numbers and strings from the user.
- Standard draw. Plot graphics.
- Standard audio. Create sound.
Standard output.
Java's print() and println() methods, invoked with System.out, implement the standard output abstraction that we need, but to treat standard input and standard output in a uniform manner, we use the methods defined in the following API:
The print() and println() methods are the ones that you have been using. The printf() method gives us more control over the appearance of the output.![]()
Since the first time that we printed double values we have been distracted by excessive precision in the printed output. For example, when we use System.out.print(Math.PI) we get the output 3.141592653589793 even though we might prefer to see 3.14 or 3.14159. With printf(), we can write StdOut.printf("%7.5f", Math.PI) to get 3.14159.
- Basics.
In its simplest form, printf() takes two arguments.
The first argument, a string, contains a format
that describes how the second argument is to be converted to
a string for output. Formats begin with %
and end with a one-letter conversion code. The conversion
codes that we use most frequently are d
(for decimal values from Java's integer types),
f (for floating-point values) and s
(for String values).
Between the % and the conversion code is an
integer value that specifies the field width
of the converted value (the number of characters in the
converted output string). By default, blanks are added on
the left to make the length of the converted
output equal to the field width; if we want the blanks
on the right, we can insert a minus sign before the field width.
(If the converted output string is bigger than the field width,
the field width is ignored.) Following the
width we have the option of including a period followed by number of
digits to put after the decimal point (the precision) for a
double value or the number of characters to take from
the beginning for a String value.
The following table summarizes these conventions:
- Format string.
The first argument of printf() is called the format string.
Any part of the format string that is not part of a format is passed through
to the output, with the format replaced by the argument value (converted
to a string as specified). For example, the statement
prints the lineStdOut.printf("PI is approximately %.2f\n", Math.PI);
To print a new line, we need to explicitly include \n in the format string.PI is approximately 3.14
- Multiple arguments.
The printf() function can take more than two
arguments. In this case, the format string will have a format
specifier for each argument, perhaps separated by other characters
to pass through to the output. For example, if you were making
payments on a loan, you might use code whose inner loop
contains the statements
to print a table like this one (see exercise 1.5.12):String formats = "%3s $%6.2f $%7.2f $%5.2f\n"; StdOut.printf(formats, month[i], pay, bal, interest);
payment balance interest Jan $299.00 $9742.67 $41.67 Feb $299.00 $9484.26 $40.59 Mar $299.00 $9224.78 $39.52 ...
Standard input.
Our StdIn library supports an abstract data stream that may be empty or can contain a sequence of values separated by whitespace. Each value is a String or a value from one of Java's primitive types. One of the key features of the standard input stream is that your program consumes values when it reads them. Once your program has read a value, it cannot back up and read it again. The library is defined by the following API:
We now consider several examples in detail.![]()
- Typing input.
When you use the java command to invoke a Java program
from the command line, you actually are doing three things: (i)
issuing a command to start executing your program, (ii)
specifying the
values of the command-line arguments, and (iii) beginning to define the
standard input stream. The string of characters that you type
in the terminal window after the command line is the standard
input stream. When you type characters, you are interacting with
your program. The program waits for you to create the standard
input stream. For example, AddInts.java
takes an argument N from the command line, then reads N numbers
from standard input and adds them:
When you type java AddInts 4, after taking the command-line arguments, the program calls the method StdIn.readInt() and waits for you to type an integer. Suppose that you want 144 to be the first input: as you type 1, then 4, and then 4, nothing happens, because StdIn does not know that you are done typing the integer, but when you then type <return> to signify the end of your integer, StdIn.readInt() immediately returns the value 144. After you have typed four numbers in this way, AddInts expects no more input and prints out the sum, as desired.public class AddInts { public static void main(String[] args) { int N = Integer.parseInt(args[0]); int sum = 0; for (int i = 0; i < N; i++) sum += StdIn.readInt(); StdOut.println("Sum is " + sum); } }
- Input format. If you type abc or 12.2 or true when StdIn.readInt() is expecting an int, then it will respond with a NumberFormatException. The format for each type is the same as you have been using for literal values within Java programs. For convenience, StdIn treats strings of consecutive whitespace characters as identical to one space and allows you to delimit your numbers with such strings. It does not matter how many spaces you put between numbers, whether you enter numbers on one line or separate them with tab characters or spread them out over several lines, (except that your terminal application processes standard input one line at a time, so it will wait until you type <return> before sending all of the numbers on that line to standard input). You can mix values of different types in an input stream, but each time that the program expects a value of a particular type, there needs to be a value of that type in the input stream.
- Interactive user input. Program TwentyQuestions.java plays a simple guessing game. You type numbers, each of which is an implicit question (Is this the number?) and the program tells you whether your guess is too high or too low.
- Processing an infinite stream. Typically, input streams are finite: your program marches through the input stream, consuming values until the stream is empty. But there is no restriction of the size of the input stream. Average.java reads in a sequence of real numbers from standard input and prints their average. It illustrates a key property of using an input stream: the length of the stream is not known to the program. We type all the numbers that we have, then the program averages them. Before reading each number, the program uses the method StdIn.isEmpty() to check whether there are any more numbers in the input stream. How do we signal that we have no more data to type? By convention, we type a special sequence of characters known as the end-of-file sequence. It is <ctrl-d> on OS X and Linux, and it is <ctrl-z> on Windows; on some systems the end-of-file sequence must appear on its own line.
Redirection and piping.
For many applications, typing input data as a standard input stream from the terminal window is untenable because doing so limits our program's processing power by the amount of data that we can type. Similarly, we often want to save the information printed on the standard output stream for later use. We can use operating system mechanisms to address both issues.- Redirecting standard output to a file.
By adding a simple directive to the
command that invokes a program, we can redirect its standard output to
a file, for permanent storage or for input to some other program at a later
time. For example, the command
specifies that the standard output stream is not to be printed in the terminal window, but instead is to be written to a text file named data.txt. Each call to StdOut.print() or StdOut.println() appends text at the end of that file. In this example, the end result is a file that contains 1,000 random values. No output appears in the terminal window: it goes directly into the file named after the > symbol. Thus, we can save away information for later retrieval.
- Redirecting standard output from a file.
Similarly, we can redirect standard input so
that StdIn reads data from a file instead of the terminal
application. For example, the command
reads a sequence of numbers from the file data.txt and computes their average value. Specifically, the < symbol is a directive to implement the standard input stream by reading from the file data.txt instead of by waiting for the user to type something into the terminal window. When the program calls StdIn.readDouble(), the operating system reads the value from the file. This facility to redirect standard input from a file enables us to process huge amounts of data from any source with our programs, limited only by the size of the files that we can store.
- Connecting two programs.
The most flexible way to implement the
standard input and standard output abstractions is to specify that they are
implemented by our own programs!
This mechanism is called piping. For
example, the following command
specifies that the standard output for RandomSeq and the standard input stream for Average are the same stream. That is, the result has the same effect as the following sequence of commands
but the file data.txt is not needed.% java RandomSeq 1000 > data.txt % java Average < data.txt
- Filters.
For many common tasks, it is convenient
to think of each program as a filter that converts a standard input stream
to a standard output stream in some way, with piping as the command
mechanism to connect programs together. For example,
MovingAverage.java
takes a command-line argument N and prints on standard
output a stream of numbers where each number in the output stream is
the average of the N numbers starting at the corresponding position in the
standard input stream.
Your operating system also provides a number of filters. For example, the sort filter puts the lines on standard input in sorted order:
Another useful filter is more, which reads data from standard input and displays it in your terminal window one screenful at a time. For example, if you type% java RandomSeq 5 | sort 0.035813305516568916 0.14306638757584322 0.348292877655532103 0.5761644592016527 0.9795908813988247
you will see as many numbers as fit in your terminal window, but more will wait for you to hit the space bar before displaying each succeeding screenful.% java RandomSeq 1000 | more
Standard drawing.
Now we introduce a simple abstraction for producing drawings as output. We imagine an abstract drawing device capable of drawing lines and points on a two-dimensional canvas. The device is capable of responding to the commands that our programs issue in the form of calls to static methods in StdDraw. The primary interface consists of two kinds of methods: drawing commands that cause the device to take an action (such as drawing a line or drawing a point) and control commands that set parameters such as the pen size or the coordinate scales.Here is the Javadoc.
- Basic drawing commands.
We first consider the drawing commands:
These methods are nearly self-documenting: StdDraw.line() draws a straight line segment connecting the point (x0, y0) with the point (x1 , y1) whose coordinates are given as arguments, StdDraw.point() draws a spot centered on the point (x, y) whose coordinates are given as arguments. The default coordinate scale is the unit square (all coordinates between 0 and 1). The standard implementation displays the canvas in a window on your computer's sceen, with black lines and points on a white background. The window includes a menu option to save your drawing to a file, in a format suitable for publishing on the Web.
Your first drawing. The HelloWorld for graphics programming with StdDraw is to draw a triangle with a point inside. To draw the triangle, we draw three lines: one from the point (0, 0) at the lower left corner to the point (1, 0), one from that point to the third vertex at (1/2, sqrt(3)/2) and one from that point back to back to (0, 0). As a final flourish, we draw a spot in the middle of the triangle. Program Triangle.java contains the full program.
double t = Math.sqrt(3.0)/2.0; StdDraw.line(0.0, 0.0, 1.0, 0.0); StdDraw.line(1.0, 0.0, 0.5, t); StdDraw.line(0.5, t, 0.0, 0.0); StdDraw.point(0.5, t/3.0);
- Control commands.
The coordinate system that we use to communicate
with the drawing device is the unit square, but we often want to draw plots
at different scales.
Also, we often want to draw lines of different thickness and points
of different size than the standard. To accommodate these needs,
StdDraw has the following methods:
For example, when we issue the command StdDraw.setXscale(0, N), we are telling the drawing device that we will be using x-coordinates between 0 and N. Note that the two-call sequence
sets the drawing coordinates to be within a bounding box whose lower left corner is at (x0, y0) and whose upper right corner is at (x1, y1).StdDraw.setXscale(x0, x1); StdDraw.setYscale(y0, y1);
- Filtering data to a standard drawing.
PlotFilter.java reads a sequence
of points defined by (x, y) coordinates from standard input
and draws a spot at each point.
It adopts the convention that the first four
numbers on standard input specify the bounding box, so that
it can scale the plot.
% java PlotFilter < USA.txt
- Plotting a function graph.
FunctionGraph.java
plots the function y = sin(4x) + sin(20x) in the interval (0, π).
There are an infinite number of points in the interval, so we have
to make do with evaluating the function at a finite number of
points within the interval. We sample the function by
choosing a set of x values, then computing y values by evaluating
the function at each x value. Plotting the function
by connecting successive points with lines produces what is known
as a piece-wise linear approximation.
- Filtering data to a standard drawing.
PlotFilter.java reads a sequence
of points defined by (x, y) coordinates from standard input
and draws a spot at each point.
It adopts the convention that the first four
numbers on standard input specify the bounding box, so that
it can scale the plot.
- Outline and filled shapes.
StdDraw also includes
methods to draw circles, rectangles, and arbitrary polygons.
Each shape defines an outline. When the method name
is just the shape name, that outline is traced by the drawing pen.
When the method name begins with filled, the named shape is instead filled
solid, not traced. As usual, we summarize the available methods in
an API:
The arguments for circle() and define a circle of radius r; the arguments for square() define a square of side length 2r centered on the given point; and the arguments for polygon() define a sequence of points that we connect by lines, including one from the last point to the first point.
- Text and color.
To annotate or highlight various elements in your drawings,
StdDraw includes methods for
drawing text, setting the font, and setting the the
ink in the pen.
In this code, Font and Color are abstractions that are implemented with non-primitive types that you will learn about in Section 3.1. Until then, we leave the details to StdDraw. The available pen colors are BLACK, BLUE, CYAN, DARK_GRAY, GRAY, GREEN, LIGHT_GRAY, MAGENTA, ORANGE, PINK, RED, WHITE, and YELLOW, defined as constants within StdDraw. For example, the call
changes to gray ink. The default ink color is BLACK. The default font is a 16-point plain Serif font.StdDraw.setPenColor(StdDraw.GRAY);
- Animation.
The StdDraw library has two additional methods that we
can use to produce the effect of motion on the screen.
The HelloWorld of animation is to produce a black ball that appears to move around on the canvas. Suppose that the ball is at position (x, y) and we want to create the impression of having it move to a new position, say (x + .01, y + .02). We do so in two steps:
- Calculate the position of the ball.
- Clear the screen.
- Draw the ball at its new position.
- Pause for a short while.
To create the illusion of movement, we would like to iterate these steps for a whole sequence of positions (that would form a straight line, in this case). Accordingly, StdDraw has a show() method that allows us to control when the result of drawing actions are actually shown on the display. You can think of it collecting all of the lines, points, shapes, and text that we tell it to draw and then immediately drawing them all when we issue the show() command. To control the apparent speed, show() takes an argument telling StdDraw to wait the given number of milliseconds after doing the drawing. By default, StdDraw issues a show() after each line(), point(), or other drawing command; we turn that option off when we call StdDraw.show(t) and turn it back on when we call StdDraw.show() with no arguments.
BouncingBall.java implements these steps to create the illusion of a ball moving in the box of side length 2, centered on the origin. The current position of the ball is given by (rx, ry) and it the new position at each step is computed by adding vx to rx and vy to ry. Since (vx, vy) is the fixed distance that the ball moves in each time unit, it represents the velocity. To keep the ball in the drawing, we simulate the effect of the ball bouncing off the walls according to the laws of elastic collision. This effect is easy to implement: when the ball hits a vertical wall, we just change the velocity in the x-direction from vx to -vx and when the ball hits a horizontal wall, we change the velocity in the y-direction from vy to -vy. The images below, which show the track of the ball, are produced by a modified version of this code (see Exercise 1.5.34).
- Images. Our standard draw library supports drawing pictures as well as geometric shapes. The command StdDraw.picture(x, y, filename) plots the image in the given filename (either JPEG, GIF, or PNG format) on the canvas, centered on (x, y). DeluxeBouncingBall.java illustrates an example where the bouncing ball is replaced by an image of the earth.
- User interaction.
Our standard draw library also includes methods so that the user
can interact with the window using the mouse.
double mouseX() return x coordinate of mouse double mouseY() return y coordinate of mouse boolean mousePressed() is the mouse currently being pressed?
- A first example. MouseFollower.java is the HelloWorld of mouse interaction. It draws a blue ball, centered on the location of the mouse. When the user holds down the mouse button, the ball changes color from blue to cyan.
- A simple attractor. OneSimpleAttractor.java simulates the motion of a blue ball that is attracted to the mouse. It also accounts for a drag force.
- Many simple attractors. SimpleAttractors.java simulates the motion of 20 blue balls that are attracted to the mouse. It also accounts for a drag force. When the user clicks, the balls disperse randomly.
- Springs. Springs.java implements a spring system.
Standard audio.
StdAudio is a library that you can use to play and manipulate sound files. It allows you to play .wav files, to write programs to create and manipulate arrays of double values, and to read and write them as .wav files:
We first introduce some some basic concepts behind one of the oldest and most important areas of computer science and scientific computing, which is known as digital signal processing.![]()
- Concert A.
Sound is the vibration of matter that we perceive, in particular,
by the vibration of our eardrums, so oscillation is the key to
understanding sound. Perhaps the simplest place to start is to consider the musical
note A above middle C, which is known as concert A. This note is nothing
more than a sine wave, scaled to oscillate at a frequency of 440 times per
second. The function sin(t) repeats itself once every 2π
units on the x axis, so if we measure t in seconds and plot the function
sin(2πt × 440) we get
a curve that oscillates 440 times per second.
We measure frequency in hertz
(cycles per second). When you double or
halve the frequency, you move up or down an octave on the scale.
For example 880 hertz is one
octave above concert A and 110 hertz is two octaves below concert A. For
reference, the frequency range of human hearing is about 20 to 20,000
hertz.The amplitude (y value) corresponds to the volume. We assume
it is scaled to be between -1 and +1. The following code fragment
plays concert A for 1 second.
int SAMPLE_RATE = 44100; double[] a = new double[SAMPLE_RATE + 1]; for (int i = 0; i <= SAMPLE_RATE; i++) { a[i] = Math.sin(2 * Math.PI * i * 440 / SAMPLE_RATE); } StdAudio.play(a); - Other notes. A simple mathematical formula characterizes
the other notes on the chromatic scale. They are divided equally on a logarithmic
(base 2) scale: there are twelve notes on the chromatic scale, and we get the
i th note above a given note by multiplying its frequency by the (i/12)th
power of 2. In other words, the frequency of each note in the chromatic
scale is precisely the frequency of the previous note in the scale multiplied
by the twelfth root of two. This information suffices to create music! For
example, to play the tune Frere Jacques, we just need to play each of the
notes A B C A by producing sine waves of the appropriate frequency for
about half a second each and then repeat the pattern.
- Chords and harmonics.
Notes like concert A have a pure sound that is a
not very musical, because the sounds that you are accustomed to hearing
have many other components. The sound from the guitar string echos off
the wooden part of the instrument, the walls of the room that you are in,
and so forth. You may think of such effects as modifying the basic sine wave.
For example, most musical instruments produce harmonics (the same note in
different octaves and not as loud), or you might play chords (multiple notes
at the same time). To combine multiple sounds, we can simply add their
waves together (and rescale to make sure they stay between -1 and +1).
When we add sine waves of different frequency, we can get arbitrarily complicated waves. Indeed, one of the triumphs of 19th century mathematics was the development of the ideas that any periodic function can be expressed as a sum of sine and cosine waves, known as a Fourier series. This mathematical idea corresponds to the idea that we can create a large range of sounds with musical instruments or our vocal chords and that all sound consists of a composition of various oscillating curves. Any sound corresponds to a curve and any curve corresponds to a sound.
- Sampling.
For digital sound, we represent a curve by sampling it at regular
intervals, in precisely the same manner as when we plot function graphs.
We sample sufficiently often that we have an accurate representation
of the curve - a widely used sampling rate for digital sound
is 44,100 samples per second. For concert A, that rate corresponds to
plotting each cycle of the sine wave by sampling
it at about 100 points. Since we sample at
regular intervals, we only need to compute
the y coordinates of the sample points.
It is that simple: we represent sound as an array of numbers
(double values that are between -1 and +1).
- Play that tune. PlayThatTune.java is an example that shows how easily we can create music with StdAudio. It takes notes from standard input, indexed on the chromatic scale from concert A, and plays them on standard audio.
Graphical user interfaces.
A graphical user interface (GUI) is.... Swing is Java's built-in library of GUI widgets. It includes primitives for creating buttons, menus, scrollbars, and many other common graphical components that everyday applications (browser, email client, word processor) use. The text editor JEdit that you have been using to write your programs is written in Java. We will defer interactive graphics until later, but just to give you an idea of what is possible, GUI.java is a bare-bones Java program that contains a clickable button. Each operating system displays the program using its own look-and-feel to blend in with native applications. Below is the same program under Windows XP and Mac OS X.
Standard draw 3D.
Under development. See this directory for StdDraw3D and examples.Q + A
Q. Can I re-read data from standard input.
A. No. You only get one shot.
Q. How do I enter the end-of-file sequence if I am redirecting standard input from a file?
A. It is automatically included by your operating system.
Q. What other conversion codes are there for printf()?
A. For integer values, there are o for octal, x for hexadecimal; for floating point, you can use e or g to get scientific notation. There also are numerous formats for dates and times. Here is a wealth of information about printf format string syntax.
Q. How do I print the % symbol within printf()?
A. Use %%.
Q. What happens if my program attempts to read data from standard input after it is exhausted?
A. You will get the following error
Use StdIn.isEmpty() to check whether there is more input available.
java.lang.RuntimeException: Tried to read from empty stdin
Q. What is the symbol for the end of a line?
A. Different operating systems use different symbols. On Unix systems, the newline character is '\n', on Windows each line is terminated by a string of two characters "\r\n", on Macs each line is terminated by the string "\n\r". When writing a program, you should avoid using operating system specific features or else it might not work as expected on other systems. Use System.out.println() to print a new line, or the following to determine the sequence of characters that represents a new line.
String NEWLINE = System.getProperty("line.separator");
Q. Which of the following is more efficient?
String s; while (!StdIn.isEmpty()) { while (!StdIn.isEmpty()) { s = StdIn.readString(); String s = StdIn.readString(); ... ... } }
A. No difference in terms of efficiency. The second is better style because it limits the scope of the variable s.
Q. How is the Java coordinate system different from the one in StdDraw?
A. StdDraw arranges the axes in Cartesian form - (0, 0) is lower left, whereas Java uses (0, 0) for upper left. StdDraw uses real-valued coordinates, whereas Java uses integer coordinates.
Q. How do I create colors for use with the graphics library?
A. Here's a primer on using colors in Java.
Q. What are the main differences of the PNG, JPEG, and PostScript graphics formats?
A. The graphics on most web pages are in PNG, GIF, or JPEG format. All three formats are raster-based - they store the set of pixels and color gradations needed to represent a picture. PNG and GIF are ideal for displaying figures with straight lines and geometric figures, while JPEG is best suited for photographs. PostScript is a vector-based format. For example, it represents a circle as a geometric object instead of a collection of thousands of pixels. The quality does not degrade if you enlarge or shrink it. For this reason, most printers use PostScript to print documents and graphics.
Q. What does the error message Exception in thread "main" java.lang.NoClassDefFoundError: StdIn mean?
A. You probably forgot to put StdIn.java in your current working directory and compile it.
Q. How can I create an animated GIF?
A. Currently our graphics library does not support saving animated file formats like MPEG, animated GIF, or AVI. However, with an external utility (e.g., ImageMagick) the process is not difficult, and we have used it to create some of the animations on this booksite. The idea is to use StdDraw.save() to save a sequence of PNG files named frame100.png, frame101.png, frame102.png, and so on. Assuming ImageMagick is installed (Unix, Linux, OS X, and Windows are all supported) you can use the command
convert -delay 10 -loop 5 T*.png duke.gif
The convert program stitches together the frames (in lexicographic order), displays them every 10 milliseconds (ten per second), and repeats the loop 5 times.
Exercises
- Write a program Sum5.java that reads in five integers from standard input and prints out their sum.
- Write a program MaxMin.java that reads in integers (as many as the user enters) from standard input and prints out the maximum and minimum values read in.
-
Write a program DeleteX.java that reads in text from
standard input and deletes all occurrences of the letter X.
To filter a file and remove all X's, run your program with the
following command:
% java DeleteX < input.txt > output.txt
- Write a program ThreeLargest.java that reads integers from standard input and prints out the three largest inputs.
- Write a program GeometricMean.java that reads in positive real numbers from standard input and prints out their geometric mean. The geometric mean of N positive numbers x1, x2, ..., xN is (x1 * x2 * ... * xN)1/N. Hint: consider taking logs to avoid overflow.
- Write a program HarmonicMean.java that reads in positive real numbers from standard input and prints out their harmonic mean. The harmonic mean of N positive numbers x1, x2, ..., xN is (1/x1 + 1/x2 + ... + 1/xN) / (1 / N).
- Write a program Pnorm.java that takes a command-line argument p, reads in real numbers from standard input, and prints out their p-norm. The p-norm norm of a vector (x1, ..., xN) is defined to be the pth root of (|x1|p + |x2|p + ... + |xN|p).
-
Consider the following Java program.
public class Mystery { public static void main(String[] args) { int i = StdIn.readInt(); int j = StdIn.readInt(); System.out.println((i-1)); System.out.println((j*i)); } }Suppose that the file input.txt contains
What does the following command do?5 1
java Mystery < input.txt
-
Repeat the previous exercise but use the following command instead
java Mystery < input.txt | java Mystery | java Mystery | java Mystery
-
Consider the following Java program.
public class Mystery { public static void main(String[] args) { int i = StdIn.readInt(); int j = StdIn.readInt(); int k = i + j; System.out.println(j); System.out.println(k); } }Suppose that the file input.txt contains the integers 1 and 1. What does the following command do?
java Mystery < input.txt | java Mystery | java Mystery | java Mystery
-
Consider the Java program Ruler.java.
public class Ruler { public static void main(String[] args) { int n = StdIn.readInt(); String s = StdIn.readString(); System.out.println((n+1) + " " + s + (n+1) + s); } }Suppose that the file input.txt contains the integers 1 and 1. What does the following command do?
java Ruler < input.txt | java Ruler | java Ruler | java Ruler
-
Consider the Java program Dragon.java.
public class Dragon { public static void main(String[] args) { String dragon = StdIn.readString(); String nogard = StdIn.readString(); System.out.print(dragon + "L" + nogard); System.out.print(" "); System.out.print(dragon + "R" + nogard); System.out.println(); } }Suppose that the file input.txt contains the strings F and F. What does the following command do?
java Dragon < input.txt | java Dragon | java Dragon
- Write a program TenPerLine.java that takes a sequence of integers between 0 and 99 and prints them nicely 10 per line. Pipe the output of java RandomIntSeq N through java TenPerLine to get N integers between 0 and 99, printed 10 per line.
- Modify Add.java so that it re-asks the user to enter two positive integers if the user types in a non-positive integer.
- Modify TwentyQuestions.java so that it re-asks the user to enter a response if the user types in something other than true or false. Hint: add a do-while loop within the main loop.
- Nonagram. Write a program to plot a nonagram.
- Star polygons. Write a program StarPolygon.java that takes two command line inputs p and q, and plots the {p/q}-star polygon.
- Complete graph. Write a program to plot that takes an integer N, plots an N-gon, where each vertex lies on a circle of radius 256. Then draw a gray line connecting each pair of vertices.
- Necker cube. Write a program NeckerCube.java to plot a Necker cube.
- What happens if you move the StdDraw.clear(Color.BLACK) command to before the beginning of the while loop in BouncingBall.java? Answer: try it and observe a nice woven 3d pattern with the given starting velocity and position.
- What happens if you change the parameter of StdDraw.pause() to 0 or 1000 in BouncingBall.java?
- Write a program to plot a circular ring of width 10 like the one below using two calls to StdDraw.filledCircle().
- Write a program to plot a circular ring of width 10 like the one below using a nested for loop and many calls to StdDraw.point().
-
Write a program to plot the Olympic rings.
- Write a program DeluxeBouncingBall.java that embellishes BouncingBall.java by playing a sound effect upon collision with the wall using StdAudio and the sound files laser.wav and pop.wav.
Creative Exercises
- Word count. Write a program WordCount.java that reads in text from standard input and prints out the number of words in the text. For our purposes, a word is a sequence of non-whitespace characters, surrounded by whitespace. Use the library StdIn.
- Word and line count. Modify WordCount.java so that reads in text from standard input and prints out the number of characters, words, and lines in the text.
- Longest consecutive streak. Write a program Repeats.java that reads in a sequence of integers and prints out the integer that appears the most times in-a-row. For example, if the input is 1 2 2 1 5 1 1 7 7 7 7 1 1 then your program should print out the integer 7.
- Centroid.
Given the positions and masses of N object, compute their center-of-mass
or centroid. The centroid is defined to be the average
position of the N objects, weighted by mass. That is
if the positions and masses are given by
(xi, yi, mi),
then the center of mass (x, y, m) is given by:
m = m1 + m2 + ... + mN x = (m1x1 + ... + mnxN) / m y = (m1y1 + ... + mnyN) / m
Write a program CenterOfMass.java that reads in a sequence of positions and masses (xi, yi, mi) from standard input and prints out their center of mass (x, y, m). Hint: model your program after Average.java.
- Signal analysis. Write a program SignalAnalyzer.java that reads in a sequence of real numbers between -1 and 1 and prints out their average magnitude, average power, and the number of zero crossings. The average magnitude is the average of the absolute values of the data values. The average power is the value of the squares of the data values. The number of zero crossings is the number of times a data value transitions from a strictly negative number to a strictly positive number, or vice versa. These three statistics are widely used to analyze digital signals.
- Rainfall problem. Write a program Rainfall.java that reads in nonnegative integers (representing rainfall) one at a time until 999999 is entered, and then prints out the average of value (not including 999999).
- Missing integer. Write a program that reads in N-1 distinct integers between 1 and N and determines the missing value.
- Closest points.
Write a program to read in three command line arguments x, y, z,
and a sequence of points (xi, yi, zi)
from standard input, and print out the point closest to
(x, y, z). Recall that the square of the distance between
(x, y, z) and (xi, yi, zi)
is
(x - xi)2 + (y - yi)2 +
(z - zi)2.
Optimization: it is possible to do without using Math.sqrt.
- Remove duplicates. Write a program Duplicates.java that reads in a sequence of integers and prints back out the integers, except that it removes repeated values if they appear consecutively. For example, if the input is 1 2 2 1 5 1 1 7 7 7 7 1 1, your program should print out 1 2 1 5 1 7 1.
- Run length encoding. Write a program RunLengthEncoder.java that encodes a binary input using run length encoding. Write a program RunLengthDecoder.java that decodes a run length encoded message.
- Head and tail. Write programs Head.java and Tail.java that take an integer command line input N and print out the first or last N lines of the given file. (Print the whole file if it consists of <= N lines of text.)
- Print a random word. Read a list of N words from standard input, where N is unknown ahead of time, and print out one of the N words uniformly at random. Do not store the word list. Instead, use Knuth's method: when reading in the ith word, select it with probability 1/i to be the selected word, replacing the previous champion. Print out the word that survives after reading in all of the data.
- Caesar cipher.
Julius Caesar sent secret messages to Cicero using a scheme that
is now known as a Caesar cipher. Each letter is replaced
by the letter k positions ahead of it in the alphabet (and you
wrap around if needed). The table below gives the Caesar cipher
when k = 3.
Original: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Caesar: D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
For example the message "VENI, VIDI, VICI" is converted to "YHQL, YLGL, YLFL". Write a program Caesar.java that takes a command-line argument k and applies a Caesar cipher with shift = k to a sequence of letters read from standard input. If a letter is not an uppercase letter, simply print it back out.
- Caesar cipher decoding. How would you decode a message encrypted using a Caesar cipher? Hint: you should not need to write any more code.
-
Parity check.
A Boolean matrix has the parity property
when each row and each column has an even sum. This is a simple type of
error-correcting code because if one bit is corrupted in transmission
(bit is flipped from 0 to 1 or from 1 to 0) it can be detected and
repaired. Here's a 4 x 4 input file which has the parity property:
1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 1
Write a program ParityCheck.java that takes an integer N as a command line input and reads in an N-by-N Boolean matrix from standard input, and outputs if (i) the matrix has the parity property, or (ii) indicates which single corrupted bit (i, j) can be flipped to restore the parity property, or (iii) indicates that the matrix was corrupted (more than two bits would need to be changed to restore the parity property). Use as little internal storage as possible. Hint: you do not even have to store the matrix!
- Takagi's function. Plot Takagi's function: everywhere continuous, nowhere differentiable.
- Hitchhiker problem.
You are interviewing N candidates for the sole position
of American Idol.
Every minute you get to see a new candidate, and you have
one minute to decide whether or not to declare that person
the American Idol. You may not change your mind once you
finish interviewing the candidate.
Suppose that you can immediately rate each candidate with a single real
number between 0 and 1,
but of course, you don't know the rating of the candidates not yet seen.
Devise a strategy and write a program AmericanIdol that has
at least a 25% chance of picking the best candidate
(assuming the candidates arrive in random order),
reading the 500 data values from standard input.
Solution: interview for N/2 minutes and record the rating of the best candidate seen so far. In the next N/2 minutes, pick the first candidate that has a higher rating than the recorded one. This yields at least a 25% chance since you will get the best candidate if the second best candidate arrives in the first N/2 minutes, and the best candidate arrives in the final N/2 minutes. This can be improved slightly to 1/e = 0.36788 by using essentially the same strategy, but switching over at time N/e.
- Checkerboard.
Write a program CheckerBoard.java
that takes a command-line argument N and plots an N-by-N checkerboard.
Always color the lower left square red.
Draw the squares in red and black. Below is the desired
output for N = 5, 10, and 25.
-
Nested diamonds.
Write a program Diamonds.java
that takes a command line input N and plots N nested squares
and diamonds.
Below is the desired output for N = 3, 4, and 5.
-
Regular polygons.
Create a function to plot an N-gon, centered on (x, y) of size
length s.
Use the function to draws nested polygons like the picture below.
- Bulging squares.
Write a program BulgingSquares.java that draws the
following optical illusion from
Akiyoshi Kitaoka
The center appears to bulge outwards even though all squares
are the same size.
- Spiraling mice. Suppose that N mice that start on the vertices of a regular polygon with N sides, and they each head toward the nearest other mouse (in counterclockwise direction) until they all meet. Write a program to draw the logarithmic spiral paths that they trace out by drawing nested N-gons, rotated and shrunk as in this animation.
-
Spiral.
Write a program to draw a spiral like the one below.
-
Rose.
Write a program Rose.java
that takes a command line input N
and plots an order rose with N petals (if N is odd) or 2N petals
(if N is even). Plot the polar coordinates (r, θ) of the
function f(θ) = sin(N × θ) for
θ ranging from 0 to 360 degrees.
Below is the desired output for N = 4, 7, and 8.
-
Globe.
Write a program Globe.java
that takes a real command-line argument α
and plots a globe-like pattern with parameter α.
Plot the polar coordinates (r, θ) of the function
f(θ) = cos(α × θ) for θ
ranging from 0 to 7200 degrees. Below is the desired output
for α = 0.8, 0.9, and 0.95.
- Drawing strings.
Write a program RandomText.java
that takes a string s and an integer N as command line
inputs, and writes the string N times at a random location,
and in a random color.
- Banner. Write a program Banner.java that takes a string s, and displays it on the screen, moving from left-to-right, and wrapping around as necessary.
- 2D random walk.
Write a program RandomWalk.java
to simulate a 2D random walk and animate the results.
Start at the center of a 2N-by-2N grid. The current location
is displayed in blue; the trail in white.
- Spirographs. Write a program Spirograph.java
to read in three command-line arguments
R, r, and a, and animates the resulting spirograph.
A spirograph
or epicycloid
is a curve formed by rolling a circle of radius r
around a larger fixed circle or radius R. If the pen offset of the pen point
from the center of the rolling circle is (r+a), then the equation of
the resulting curve at time t is given by
x(t) = (R+r)*cos(t) - (r+a)*cos(((R+r)/r)*t) y(t) = (R+r)*sin(t) - (r+a)*sin(((R+r)/r)*t)
(Such curves were popularized by Hasbro's game Spirograph which contains discs with gear teeth on the edges. The disks contains small holes so that you could put a pen in it and trace the path.) For a dramatic 3d effect, draw a circular image, e.g., earth.gif instead of a dot, and show it rotating over time. Here's a picture of the resulting spirograph when R = 180, r = 40, and a = 15.
- Rotating table. You are seated at a rotating square table (like a lazy Susan), and there are four coins placed in the four corners of the table. Your goal is to flip the coins so that they are either all heads or all tails, at which point a bell rings to notify you that you are done. You may select any two of them, determine their orientation, and (optionally) flip either or both of them over. To make things challenging, you are blindfolded, and the table is spun after each time you select two coins. Write a program RotatingTable.java that initializes the coins to random orientations. Then, it prompts the user to select two positions (1-4), and identifies the orientation of each coin. Next, the user can specify which, if any of the two coins to flip. The process repeats until the user solves the puzzle.
- Rotating table solver.
Write another program RotatingTableSolver.java
to solve the rotating table puzzle.
One effective strategy is to choose two coins at random and flip them to
heads. However, if you get really unlucky, this could take an arbitrary
number of steps. Goal: devise a strategy that always solves the puzzle
in at most 5 steps.
- Hex. Hex is a two-player board game popularized by John Nash while a graduate student at Princeton University, and later commercialized by Parker Brothers. It is played on a hexagonal grid in the shape of an 11-by-11 diamond. Write a program Hex.java that draws the board.
- Clock. Write a program Clock.java that displays an animation of the second, minute, and hour hands of an analog clock. Use the method StdDraw.pause(1000) to update the display roughly once per second. Hint: this may be one of the rare times when you want to use the % operator with a double - it works the way you would probably expect.
-
Projectile motion with drag.
Write a program BallisticMotion.java
that plots the trajectory of a ball that is shot with velocity v
at an angle theta. Account for gravitational and drag forces.
Assume that the drag force is proportional to the square of the velocity.
Using Newton's equations of motions and the Euler-Cromer method,
update the position, velocity, and acceleration according to the
following equations:
v = sqrt(vx*vx + vy*vy) ax = - C * v * vx ay = -G - C * v * vy vx = vx + ax * dt vy = vy + ay * dt x = x + vx * dt y = y + vy * dt
Use G = 9.8, C = 0.002, and set the initial velocity to 180 and the angle to 60 degrees.
- Heart.
Write a program Heart.java to draw
a pink heart: Draw a diamond, then draw two circles to the upper left
and upper right sides.
- Changing square. Write a program that draws a square and changes its color each second.
- Oscilloscope.
Write a program Oscilloscope.java
to simulate the output of an oscilloscope and produce Lissajous patterns.
They are named after the French physicist, Jules A. Lissajous, who
studied the patterns that arise when two mutually perpendicular periodic
disturbances occur simultaneously.
Assume that the vertical and horizontal inputs are sinusoidal:
x = A sin (wxt + φx) y = B sin (wyt + φy) A, B = amplitudes wx, wy = angular velocity φx, φY = phase factors
For example, the first image below has A = B = 1, wx = 2, wy = 3, φx = 30 degrees, φy = 45 degrees. The other two have parameters (1, 1, 2, 3, 20, 45) and (1, 1, 5, 3, 30, 45)
- Simple harmonic motion. Repeat the previous exercise, but animate the Lissajous patterns as in this applet. Ex: A = B = wx = wy = 1, but at each time t draw 100 (or so) points with φx ranging from 0 to 720 degrees, and φx ranging from 0 to 1080 degrees.
- Bouncing ball with gravity. Modify BouncingBall.java to incorporate gravity in the vertical direction.
- Bresenham's line drawing algorithm.
To plot a line segment from (x1, y1) to (x2, y2) on a monitor, say 1024-by-1024,
you need to make a discrete approximation to the continuous line and determine
exactly which pixels to turn on.
Bresenham's line drawing algorithm is a
clever solution that works when the slope is between 0 and 1 and x1 < x2.
int dx = x2 - x1; int dy = y2 - y1; int y = y1; int eps = 0; for (int x = x1; x <= x2; x++) { StdDraw.point(x, y); eps += dy; if (2*eps >= dx) { y++; eps -= dx; } } - Modify Bresenham's algorithm to handle arbitrary line segments.
- Miller's madness.
Write a program Madness.java
to plot the parametric equation:
where the parameter t is in radians. You should get the following complex picture. Experiment by changing the parameters and produce original pictures.x = sin(0.99 t) - 0.7 cos( 3.01 t) y = cos(1.01 t) + 0.1 sin(15.03 t)
- Fay's butterfly.
Write a program Butterfly.java
to plot the polar equation:
where the parameter t is in radians. You should get an image like the following butterfly-like figure. Experiment by changing the parameters and produce original pictures.r = e^(cos t) - 2 cos(4t) + (sin(t/12)^5)
- Student database. The file students.txt contains a list of students enrolled in an introductory computer science class at Princeton. The first line contains an integer N that specifies the number of students in the database. Each of the next N lines consists of four pieces of information, separated by whitespace: first name, last name, email address, and section number. The program Students.java reads in the integer N and then N lines of data of standard input, stores the data in four parallel arrays (an integer array for the section number and string arrays for the other fields). Then, the program prints out a list of students in section 4 and 5.
- Shuffling. In the October 7, 2003 California state runoff election for governor, there were 135 official candidates. To avoid the natural prejudice against candidates whose names appear at the end of the alphabet (Jon W. Zellhoefer), California election officials sought to order the candidates in random order. Write a program program Shuffle.java that takes a command-line argument N, reads in N strings from standard input, and prints them back out in shuffled order. (California decided to randomize the alphabet instead of shuffling the candidates. Using this strategy, not all N! possible outcomes are equally likely or even possible! For example, two candidates with very similar last names will always end up next to each other.)
- Reverse.
Write a program Reverse.java that
reads in an arbitrary number of real values from standard input
and prints them in reverse order.
Sometimes we need to store a large quantity of values in an array,
but we don't know how many ahead of time. The problem is that once
we allocate memory for an array, its size is fixed as long as the
array continues to exist.
It is not possible to grow or shrink the size of an array. Instead, initialize to array to have size = 1. If the array is not big enough to hold the next element, allocate a new array of double the size and copy the old elements into the new array. This repeated doubling strategy as a tradeoff between the work involved in copying the old elements and the space wasted from leaving the array half empty.
- Tile patterns. Draw some tile patterns like the following from San Giovanni in Laterno (Basilica of St. John Latern) in Rome [ 1 2 3 4 5 6 ] or from the Tile Museum in Lisbon [ 1 2 3 4 5 6 7 8 9 10 ]
Web Exercises
- Time series analysis. This problem investigates two methods for forecasting in time series analysis. Moving average or exponential smoothing.
- Polar plots. Create any of these polar plots.
- Java games. Use StdDraw.java to implement one of the games at javaunlimited.net.
-
Consider the following program.
public class Mystery { public static void main(String[] args) { int N = Integer.parseInt(args[0]); int[] a = new int[M]; while(!StdIn.isEmpty()) { int num = StdIn.readInt(); a[num]++; } for (int i = 0; i < M; i++) for (int j = 0; j < a[i]; j++) System.out.print(i + " "); System.out.println(); } }Suppose the file input.txt contains the following integers:
8 8 3 5 1 7 0 9 2 6 9 7 4 0 5 3 9 3 7 6
What is the contents of the array a after running the following command
java Mystery 10 < input.txt
- High-low. Shuffle a deck of cards, and deal one to the player. Prompt the player to guess whether the next card is higher or lower than the current card. Repeat until player guesses it wrong. Game show: ???? used this.
- Elastic collisions. Write a program CollidingBalls.java that takes a command line input N and plots the trajectories of N bouncing balls that bounce of the walls and each other according to the laws of elastic collisions. Assume all the balls have the same mass.
- Elastic collisions with obstacles. Each ball should have its own mass. Put a large ball in the center with zero initial velocity. Brownian motion.
- Statistical outliers. Modify Average.java to print out all the values that are larger than 1.5 standard deviations from the mean. You will need an array to store the values.
- Optical illusions. Create a Kofka ring or one of the other optical illusions collected by Edward Adelson.
- Computer animation.
In 1995 James Gosling presented a demonstration of Java
to Sun executives, illustrating
its potential to deliver dynamic and interactive
Web content. At the time, web pages were fixed and non-interactive.
To demonstrate what the Web could be, Gosling presented applets
to rotate 3D molecules, visualize sorting routines, and
Duke cart-wheeling across the screen.
Java was officially introduced in May 1995 and widely
adopted in the technology sector.
The Internet would never be the same.
Program Duke.java reads in the 17 images T1.gif through T17.gif and produces the animation. To execute on your computer, download the 17 GIF files and put in the same directory as Duke.java. (Alternatively, download and unzip the file duke.zip or duke.jar to extract all 17 GIFs.)
- Cart-wheeling Duke. Modify Duke.java so that it cartwheels 5 times across the screen, from right to left, wrapping around when it hits the window boundary. Repeat this cart-wheeling cycle 100 times. Hint: after displaying a sequence of 17 frames, move 57 pixels to the left and repeat. Name your program MoreDuke.java.
- Tac (cat backwards). Write a program Duke.java that reads lines of text from standard input and prints the lines out in reverse order.
- Game. Implement the game dodge using StdDraw: move a blue disc within the unit square to touch a randomly placed green disc, while avoiding the moving red discs. After each touch, add a new moving red disc.
- Simple harmonic motion.
Create an animation like the one below from
Wikipedia of simple harmonic motion.
- Yin yang. Draw a yin yang using StdDraw.arc().
- Twenty questions. Write a program QuestionsTwenty.java that plays 20 questions from the opposite point of view: the user thinks of a number between 1 and a million and the computer makes the guesses. Use binary search to ensure that the computer needs at most 20 guesses.
