mirror of
https://github.com/danbulant/introductionToProgramming
synced 2026-09-17 13:13:48 +00:00
update
This commit is contained in:
parent
a6c1363453
commit
4bf15294e7
16 changed files with 3256 additions and 48 deletions
801
common/In.java
Normal file
801
common/In.java
Normal file
|
|
@ -0,0 +1,801 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac In.java
|
||||
* Execution: java In (basic test --- see source for required files)
|
||||
* Dependencies: none
|
||||
*
|
||||
* Reads in data of various types from standard input, files, and URLs.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.InputMismatchException;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* The <code>In</code> data type provides methods for reading strings
|
||||
* and numbers from standard input, file input, URLs, and sockets.
|
||||
* <p>
|
||||
* The Locale used is: language = English, country = US. This is consistent
|
||||
* with the formatting conventions with Java floating-point literals,
|
||||
* command-line arguments (via {@link Double#parseDouble(String)})
|
||||
* and standard output.
|
||||
* <p>
|
||||
* For additional documentation, see
|
||||
* <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
|
||||
* <i>Computer Science: An Interdisciplinary Approach</i>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
* <p>
|
||||
* Like {@link Scanner}, reading a token also consumes preceding Java
|
||||
* whitespace, reading a full line consumes
|
||||
* the following end-of-line delimiter, while reading a character consumes
|
||||
* nothing extra.
|
||||
* <p>
|
||||
* Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines
|
||||
* consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;
|
||||
* see <a href="http://www.docjar.com/html/api/java/util/Scanner.java.html">
|
||||
* Scanner.java</a> (NB: Java 6u23 and earlier uses only \r, \r, \r\n).
|
||||
*
|
||||
* @author David Pritchard
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
public final class In {
|
||||
|
||||
///// begin: section (1 of 2) of code duplicated from In to StdIn.
|
||||
|
||||
// assume Unicode UTF-8 encoding
|
||||
private static final String CHARSET_NAME = "UTF-8";
|
||||
|
||||
// assume language = English, country = US for consistency with System.out.
|
||||
private static final Locale LOCALE = Locale.US;
|
||||
|
||||
// the default token separator; we maintain the invariant that this value
|
||||
// is held by the scanner's delimiter between calls
|
||||
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");
|
||||
|
||||
// makes whitespace characters significant
|
||||
private static final Pattern EMPTY_PATTERN = Pattern.compile("");
|
||||
|
||||
// used to read the entire input. source:
|
||||
// http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
|
||||
private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A");
|
||||
|
||||
//// end: section (1 of 2) of code duplicated from In to StdIn.
|
||||
|
||||
private Scanner scanner;
|
||||
|
||||
/**
|
||||
* Initializes an input stream from standard input.
|
||||
*/
|
||||
public In() {
|
||||
scanner = new Scanner(new BufferedInputStream(System.in), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an input stream from a socket.
|
||||
*
|
||||
* @param socket the socket
|
||||
* @throws IllegalArgumentException if cannot open {@code socket}
|
||||
* @throws IllegalArgumentException if {@code socket} is {@code null}
|
||||
*/
|
||||
public In(Socket socket) {
|
||||
if (socket == null) throw new IllegalArgumentException("socket argument is null");
|
||||
try {
|
||||
InputStream is = socket.getInputStream();
|
||||
scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new IllegalArgumentException("could not open socket: " + socket, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an input stream from a URL.
|
||||
*
|
||||
* @param url the URL
|
||||
* @throws IllegalArgumentException if cannot open {@code url}
|
||||
* @throws IllegalArgumentException if {@code url} is {@code null}
|
||||
*/
|
||||
public In(URL url) {
|
||||
if (url == null) throw new IllegalArgumentException("url argument is null");
|
||||
try {
|
||||
URLConnection site = url.openConnection();
|
||||
InputStream is = site.getInputStream();
|
||||
scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new IllegalArgumentException("could not read URL: '" + url + "'", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an input stream from a file.
|
||||
*
|
||||
* @param file the file
|
||||
* @throws IllegalArgumentException if cannot open {@code file}
|
||||
* @throws IllegalArgumentException if {@code file} is {@code null}
|
||||
*/
|
||||
public In(File file) {
|
||||
if (file == null) throw new IllegalArgumentException("file argument is null");
|
||||
try {
|
||||
// for consistency with StdIn, wrap with BufferedInputStream instead of use
|
||||
// file as argument to Scanner
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
}
|
||||
catch (IOException ioe) {;
|
||||
throw new IllegalArgumentException("could not read file: " + file, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes an input stream from a filename or web page name.
|
||||
*
|
||||
* @param name the filename or web page name
|
||||
* @throws IllegalArgumentException if cannot open {@code name} as
|
||||
* a file or URL
|
||||
* @throws IllegalArgumentException if {@code name} is {@code null}
|
||||
*/
|
||||
public In(String name) {
|
||||
if (name == null) throw new IllegalArgumentException("argument is null");
|
||||
if (name.length() == 0) throw new IllegalArgumentException("argument is the empty string");
|
||||
try {
|
||||
// first try to read file from local file system
|
||||
File file = new File(name);
|
||||
if (file.exists()) {
|
||||
// for consistency with StdIn, wrap with BufferedInputStream instead of use
|
||||
// file as argument to Scanner
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
return;
|
||||
}
|
||||
|
||||
// resource relative to .class file
|
||||
URL url = getClass().getResource(name);
|
||||
|
||||
// resource relative to classloader root
|
||||
if (url == null) {
|
||||
url = getClass().getClassLoader().getResource(name);
|
||||
}
|
||||
|
||||
// or URL from web
|
||||
if (url == null) {
|
||||
URI uri = new URI(name);
|
||||
if (uri.isAbsolute()) url = uri.toURL();
|
||||
else throw new IllegalArgumentException("could not read: '" + name + "'");
|
||||
url = new URL(name);
|
||||
}
|
||||
|
||||
URLConnection site = url.openConnection();
|
||||
|
||||
// in order to set User-Agent, replace above line with these two
|
||||
// HttpURLConnection site = (HttpURLConnection) url.openConnection();
|
||||
// site.addRequestProperty("User-Agent", "Mozilla/4.76");
|
||||
|
||||
InputStream is = site.getInputStream();
|
||||
scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
|
||||
scanner.useLocale(LOCALE);
|
||||
}
|
||||
catch (IOException | URISyntaxException e) {
|
||||
throw new IllegalArgumentException("could not read: '" + name + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an input stream from a given {@link Scanner} source; use with
|
||||
* {@code new Scanner(String)} to read from a string.
|
||||
* <p>
|
||||
* Note that this does not create a defensive copy, so the
|
||||
* scanner will be mutated as you read on.
|
||||
*
|
||||
* @param scanner the scanner
|
||||
* @throws IllegalArgumentException if {@code scanner} is {@code null}
|
||||
*/
|
||||
public In(Scanner scanner) {
|
||||
if (scanner == null) throw new IllegalArgumentException("scanner argument is null");
|
||||
this.scanner = scanner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this input stream exists.
|
||||
*
|
||||
* @return {@code true} if this input stream exists; {@code false} otherwise
|
||||
*/
|
||||
public boolean exists() {
|
||||
return scanner != null;
|
||||
}
|
||||
|
||||
//// begin: section (2 of 2) of code duplicated from In to StdIn,
|
||||
//// with all methods changed from "public" to "public static".
|
||||
|
||||
/**
|
||||
* Returns true if input stream is empty (except possibly whitespace).
|
||||
* Use this to know whether the next call to {@link #readString()},
|
||||
* {@link #readDouble()}, etc. will succeed.
|
||||
*
|
||||
* @return {@code true} if this input stream is empty (except possibly whitespace);
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return !scanner.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this input stream has a next line.
|
||||
* Use this method to know whether the
|
||||
* next call to {@link #readLine()} will succeed.
|
||||
* This method is functionally equivalent to {@link #hasNextChar()}.
|
||||
*
|
||||
* @return {@code true} if this input stream has more input (including whitespace);
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean hasNextLine() {
|
||||
return scanner.hasNextLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this input stream has more input (including whitespace).
|
||||
* Use this method to know whether the next call to {@link #readChar()} will succeed.
|
||||
* This method is functionally equivalent to {@link #hasNextLine()}.
|
||||
*
|
||||
* @return {@code true} if this input stream has more input (including whitespace);
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean hasNextChar() {
|
||||
scanner.useDelimiter(EMPTY_PATTERN);
|
||||
boolean result = scanner.hasNext();
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and returns the next line in this input stream.
|
||||
*
|
||||
* @return the next line in this input stream; {@code null} if no such line
|
||||
*/
|
||||
public String readLine() {
|
||||
String line;
|
||||
try {
|
||||
line = scanner.nextLine();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
line = null;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns the next character in this input stream.
|
||||
*
|
||||
* @return the next {@code char} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
*/
|
||||
public char readChar() {
|
||||
scanner.useDelimiter(EMPTY_PATTERN);
|
||||
try {
|
||||
String ch = scanner.next();
|
||||
assert ch.length() == 1 : "Internal (Std)In.readChar() error!"
|
||||
+ " Please contact the authors.";
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN);
|
||||
return ch.charAt(0);
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'char' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and returns the remainder of this input stream, as a string.
|
||||
*
|
||||
* @return the remainder of this input stream, as a string
|
||||
*/
|
||||
public String readAll() {
|
||||
if (!scanner.hasNextLine())
|
||||
return "";
|
||||
|
||||
String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
|
||||
// not that important to reset delimeter, since now scanner is empty
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream and returns it as a {@code String}.
|
||||
*
|
||||
* @return the next {@code String} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
*/
|
||||
public String readString() {
|
||||
try {
|
||||
return scanner.next();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'String' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code int},
|
||||
* and returns the {@code int}.
|
||||
*
|
||||
* @return the next {@code int} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as an {@code int}
|
||||
*/
|
||||
public int readInt() {
|
||||
try {
|
||||
return scanner.nextInt();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read an 'int' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read an 'int' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code double},
|
||||
* and returns the {@code double}.
|
||||
*
|
||||
* @return the next {@code double} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code double}
|
||||
*/
|
||||
public double readDouble() {
|
||||
try {
|
||||
return scanner.nextDouble();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'double' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read a 'double' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code float},
|
||||
* and returns the {@code float}.
|
||||
*
|
||||
* @return the next {@code float} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code float}
|
||||
*/
|
||||
public float readFloat() {
|
||||
try {
|
||||
return scanner.nextFloat();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'float' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read a 'float' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code long},
|
||||
* and returns the {@code long}.
|
||||
*
|
||||
* @return the next {@code long} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code long}
|
||||
*/
|
||||
public long readLong() {
|
||||
try {
|
||||
return scanner.nextLong();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'long' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read a 'long' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code short},
|
||||
* and returns the {@code short}.
|
||||
*
|
||||
* @return the next {@code short} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code short}
|
||||
*/
|
||||
public short readShort() {
|
||||
try {
|
||||
return scanner.nextShort();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'short' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read a 'short' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code byte},
|
||||
* and returns the {@code byte}.
|
||||
* <p>
|
||||
* To read binary data, use {@link BinaryIn}.
|
||||
*
|
||||
* @return the next {@code byte} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code byte}
|
||||
*/
|
||||
public byte readByte() {
|
||||
try {
|
||||
return scanner.nextByte();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'byte' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read a 'byte' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from this input stream, parses it as a {@code boolean}
|
||||
* (interpreting either {@code "true"} or {@code "1"} as {@code true},
|
||||
* and either {@code "false"} or {@code "0"} as {@code false}).
|
||||
*
|
||||
* @return the next {@code boolean} in this input stream
|
||||
* @throws NoSuchElementException if the input stream is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}
|
||||
*/
|
||||
public boolean readBoolean() {
|
||||
try {
|
||||
String token = readString();
|
||||
if ("true".equalsIgnoreCase(token)) return true;
|
||||
if ("false".equalsIgnoreCase(token)) return false;
|
||||
if ("1".equals(token)) return true;
|
||||
if ("0".equals(token)) return false;
|
||||
throw new InputMismatchException("attempts to read a 'boolean' value from the input stream, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'boolean' value from the input stream, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from this input stream and returns them as
|
||||
* an array of strings.
|
||||
*
|
||||
* @return all remaining tokens in this input stream, as an array of strings
|
||||
*/
|
||||
public String[] readAllStrings() {
|
||||
// we could use readAll.trim().split(), but that's not consistent
|
||||
// since trim() uses characters 0x00..0x20 as whitespace
|
||||
String[] tokens = WHITESPACE_PATTERN.split(readAll());
|
||||
if (tokens.length == 0 || tokens[0].length() > 0)
|
||||
return tokens;
|
||||
String[] decapitokens = new String[tokens.length-1];
|
||||
for (int i = 0; i < tokens.length-1; i++)
|
||||
decapitokens[i] = tokens[i+1];
|
||||
return decapitokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining lines from this input stream and returns them as
|
||||
* an array of strings.
|
||||
*
|
||||
* @return all remaining lines in this input stream, as an array of strings
|
||||
*/
|
||||
public String[] readAllLines() {
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
while (hasNextLine()) {
|
||||
lines.add(readLine());
|
||||
}
|
||||
return lines.toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from this input stream, parses them as integers,
|
||||
* and returns them as an array of integers.
|
||||
*
|
||||
* @return all remaining lines in this input stream, as an array of integers
|
||||
*/
|
||||
public int[] readAllInts() {
|
||||
String[] fields = readAllStrings();
|
||||
int[] vals = new int[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Integer.parseInt(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from this input stream, parses them as longs,
|
||||
* and returns them as an array of longs.
|
||||
*
|
||||
* @return all remaining lines in this input stream, as an array of longs
|
||||
*/
|
||||
public long[] readAllLongs() {
|
||||
String[] fields = readAllStrings();
|
||||
long[] vals = new long[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Long.parseLong(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from this input stream, parses them as doubles,
|
||||
* and returns them as an array of doubles.
|
||||
*
|
||||
* @return all remaining lines in this input stream, as an array of doubles
|
||||
*/
|
||||
public double[] readAllDoubles() {
|
||||
String[] fields = readAllStrings();
|
||||
double[] vals = new double[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Double.parseDouble(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
///// end: section (2 of 2) of code duplicated from In to StdIn */
|
||||
|
||||
/**
|
||||
* Closes this input stream.
|
||||
*/
|
||||
public void close() {
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all integers from a file and returns them as
|
||||
* an array of integers.
|
||||
*
|
||||
* @param filename the name of the file
|
||||
* @return the integers in the file
|
||||
* @deprecated Replaced by {@code new In(filename)}.{@link #readAllInts()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int[] readInts(String filename) {
|
||||
return new In(filename).readAllInts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all doubles from a file and returns them as
|
||||
* an array of doubles.
|
||||
*
|
||||
* @param filename the name of the file
|
||||
* @return the doubles in the file
|
||||
* @deprecated Replaced by {@code new In(filename)}.{@link #readAllDoubles()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double[] readDoubles(String filename) {
|
||||
return new In(filename).readAllDoubles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all strings from a file and returns them as
|
||||
* an array of strings.
|
||||
*
|
||||
* @param filename the name of the file
|
||||
* @return the strings in the file
|
||||
* @deprecated Replaced by {@code new In(filename)}.{@link #readAllStrings()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String[] readStrings(String filename) {
|
||||
return new In(filename).readAllStrings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all integers from standard input and returns them
|
||||
* an array of integers.
|
||||
*
|
||||
* @return the integers on standard input
|
||||
* @deprecated Replaced by {@code new In()}.{@link #readAllInts()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int[] readInts() {
|
||||
return new In().readAllInts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all doubles from standard input and returns them as
|
||||
* an array of doubles.
|
||||
*
|
||||
* @return the doubles on standard input
|
||||
* @deprecated Replaced by {@code new In()}.{@link #readAllDoubles()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double[] readDoubles() {
|
||||
return new In().readAllDoubles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all strings from standard input and returns them as
|
||||
* an array of strings.
|
||||
*
|
||||
* @return the strings on standard input
|
||||
* @deprecated Replaced by {@code new In()}.{@link #readAllStrings()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String[] readStrings() {
|
||||
return new In().readAllStrings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests the {@code In} data type.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
In in;
|
||||
String urlName = "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt";
|
||||
|
||||
// read from a URL
|
||||
System.out.println("readAll() from URL " + urlName);
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In(urlName);
|
||||
System.out.println(in.readAll());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
// read one line at a time from URL
|
||||
System.out.println("readLine() from URL " + urlName);
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In(urlName);
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readLine();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
// read one string at a time from URL
|
||||
System.out.println("readString() from URL " + urlName);
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In(urlName);
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readString();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
// read one line at a time from file in current directory
|
||||
System.out.println("readLine() from current directory");
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In("./InTest.txt");
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readLine();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
// read one line at a time from file using relative path
|
||||
System.out.println("readLine() from relative path");
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In("../stdlib/InTest.txt");
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readLine();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
// read one char at a time
|
||||
System.out.println("readChar() from file");
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In("InTest.txt");
|
||||
while (!in.isEmpty()) {
|
||||
char c = in.readChar();
|
||||
System.out.print(c);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
|
||||
// read one line at a time from absolute OS X / Linux path
|
||||
System.out.println("readLine() from absolute OS X / Linux path");
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readLine();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
// read one line at a time from absolute Windows path
|
||||
System.out.println("readLine() from absolute Windows path");
|
||||
System.out.println("---------------------------------------------------------------------------");
|
||||
try {
|
||||
in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
|
||||
while (!in.isEmpty()) {
|
||||
String s = in.readLine();
|
||||
System.out.println(s);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
331
common/Out.java
Normal file
331
common/Out.java
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac Out.java
|
||||
* Execution: java Out
|
||||
* Dependencies: none
|
||||
*
|
||||
* Writes data of various types to: stdout, file, or socket.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The <code>Out</code> data type provides methods for writing strings and
|
||||
* numbers to various output streams, including standard output, file, and sockets.
|
||||
* <p>
|
||||
* For additional documentation, see
|
||||
* <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
|
||||
* <i>Computer Science: An Interdisciplinary Approach</i>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
public class Out {
|
||||
|
||||
// force Unicode UTF-8 encoding; otherwise it's system dependent
|
||||
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
// assume language = English, country = US for consistency with In
|
||||
private static final Locale LOCALE = Locale.US;
|
||||
|
||||
private PrintWriter out;
|
||||
|
||||
/**
|
||||
* Initializes an output stream from a {@link OutputStream}.
|
||||
*
|
||||
* @param os the {@code OutputStream}
|
||||
*/
|
||||
public Out(OutputStream os) {
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
|
||||
out = new PrintWriter(osw, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an output stream from standard output.
|
||||
*/
|
||||
public Out() {
|
||||
this(System.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an output stream from a socket.
|
||||
*
|
||||
* @param socket the socket
|
||||
* @throws IllegalArgumentException if {@code filename} is {@code null}
|
||||
* @throws IllegalArgumentException if cannot create output stream from socket
|
||||
*/
|
||||
public Out(Socket socket) {
|
||||
if (socket == null) {
|
||||
throw new IllegalArgumentException("socket argument is null");
|
||||
}
|
||||
try {
|
||||
OutputStream os = socket.getOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
|
||||
out = new PrintWriter(osw, true);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalArgumentException("could not create output stream from socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an output stream from a file.
|
||||
*
|
||||
* @param filename the name of the file
|
||||
* @throws IllegalArgumentException if {@code filename} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code filename} is the empty string
|
||||
* @throws IllegalArgumentException if cannot write the file {@code filename}
|
||||
*/
|
||||
public Out(String filename) {
|
||||
if (filename == null) {
|
||||
throw new IllegalArgumentException("filename argument is null");
|
||||
}
|
||||
|
||||
if (filename.length() == 0) {
|
||||
throw new IllegalArgumentException("filename argument is the empty string");
|
||||
}
|
||||
|
||||
try {
|
||||
OutputStream os = new FileOutputStream(filename);
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
|
||||
out = new PrintWriter(osw, true);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalArgumentException("could not create file '" + filename + "' for writing", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the output stream.
|
||||
*/
|
||||
public void close() {
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the current line by printing the line-separator string.
|
||||
*/
|
||||
public void println() {
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an object to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the object to print
|
||||
*/
|
||||
public void println(Object x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a boolean to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the boolean to print
|
||||
*/
|
||||
public void println(boolean x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a character to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the character to print
|
||||
*/
|
||||
public void println(char x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a double to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the double to print
|
||||
*/
|
||||
public void println(double x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a float to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the float to print
|
||||
*/
|
||||
public void println(float x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an integer to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the integer to print
|
||||
*/
|
||||
public void println(int x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a long to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the long to print
|
||||
*/
|
||||
public void println(long x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a byte to this output stream and then terminates the line.
|
||||
* <p>
|
||||
* To write binary data, see {@link BinaryOut}.
|
||||
*
|
||||
* @param x the byte to print
|
||||
*/
|
||||
public void println(byte x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Flushes this output stream.
|
||||
*/
|
||||
public void print() {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an object to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the object to print
|
||||
*/
|
||||
public void print(Object x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a boolean to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the boolean to print
|
||||
*/
|
||||
public void print(boolean x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a character to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the character to print
|
||||
*/
|
||||
public void print(char x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a double to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the double to print
|
||||
*/
|
||||
public void print(double x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a float to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the float to print
|
||||
*/
|
||||
public void print(float x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an integer to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the integer to print
|
||||
*/
|
||||
public void print(int x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a long integer to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the long integer to print
|
||||
*/
|
||||
public void print(long x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a byte to this output stream and flushes this output stream.
|
||||
*
|
||||
* @param x the byte to print
|
||||
*/
|
||||
public void print(byte x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a formatted string to this output stream, using the specified format
|
||||
* string and arguments, and then flushes this output stream.
|
||||
*
|
||||
* @param format the format string
|
||||
* @param args the arguments accompanying the format string
|
||||
*/
|
||||
public void printf(String format, Object... args) {
|
||||
out.printf(LOCALE, format, args);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a formatted string to this output stream, using the specified
|
||||
* locale, format string, and arguments, and then flushes this output stream.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param format the format string
|
||||
* @param args the arguments accompanying the format string
|
||||
*/
|
||||
public void printf(Locale locale, String format, Object... args) {
|
||||
out.printf(locale, format, args);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A test client.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Out out;
|
||||
|
||||
// write to stdout
|
||||
out = new Out();
|
||||
out.println("Test 1");
|
||||
out.close();
|
||||
|
||||
// write to a file
|
||||
out = new Out("test.txt");
|
||||
out.println("Test 2");
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
11
common/README.md
Normal file
11
common/README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Common libraries
|
||||
|
||||
## Typst
|
||||
|
||||
Simple utility to render classes
|
||||
|
||||
## Java
|
||||
|
||||
Sourced from https://magnus-madsen.github.io/course-intprog/book.html.
|
||||
|
||||
Files under [GPL](https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
281
common/StdArrayIO.java
Normal file
281
common/StdArrayIO.java
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac StdArrayIO.java
|
||||
* Execution: java StdArrayIO < input.txt
|
||||
* Dependencies: StdOut.java
|
||||
* Data files: https://introcs.cs.princeton.edu/java/22library/tinyDouble1D.txt
|
||||
* https://introcs.cs.princeton.edu/java/22library/tinyDouble2D.txt
|
||||
* https://introcs.cs.princeton.edu/java/22library/tinyBoolean2D.txt
|
||||
*
|
||||
* A library for reading in 1D and 2D arrays of integers, doubles,
|
||||
* and booleans from standard input and printing them out to
|
||||
* standard output.
|
||||
*
|
||||
* % more tinyDouble1D.txt
|
||||
* 4
|
||||
* .000 .246 .222 -.032
|
||||
*
|
||||
* % more tinyDouble2D.txt
|
||||
* 4 3
|
||||
* .000 .270 .000
|
||||
* .246 .224 -.036
|
||||
* .222 .176 .0893
|
||||
* -.032 .739 .270
|
||||
*
|
||||
* % more tinyBoolean2D.txt
|
||||
* 4 3
|
||||
* 1 1 0
|
||||
* 0 0 0
|
||||
* 0 1 1
|
||||
* 1 1 1
|
||||
*
|
||||
* % cat tinyDouble1D.txt tinyDouble2D.txt tinyBoolean2D.txt | java StdArrayIO
|
||||
* 4
|
||||
* 0.00000 0.24600 0.22200 -0.03200
|
||||
*
|
||||
* 4 3
|
||||
* 0.00000 0.27000 0.00000
|
||||
* 0.24600 0.22400 -0.03600
|
||||
* 0.22200 0.17600 0.08930
|
||||
* 0.03200 0.73900 0.27000
|
||||
*
|
||||
* 4 3
|
||||
* 1 1 0
|
||||
* 0 0 0
|
||||
* 0 1 1
|
||||
* 1 1 1
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* The <code>StdArrayIO</code> class provides static methods for reading
|
||||
* in 1D and 2D arrays from standard input and printing out to
|
||||
* standard output.
|
||||
* <p>
|
||||
* For additional documentation, see
|
||||
* <a href="https://introcs.cs.princeton.edu/22libary">Section 2.2</a> of
|
||||
* <i>Computer Science: An Interdisciplinary Approach</i>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
public class StdArrayIO {
|
||||
|
||||
// it doesn't make sense to instantiate this class
|
||||
private StdArrayIO() { }
|
||||
|
||||
/**
|
||||
* Reads a 1D array of doubles from standard input and returns it.
|
||||
*
|
||||
* @return the 1D array of doubles
|
||||
*/
|
||||
public static double[] readDouble1D() {
|
||||
int n = StdIn.readInt();
|
||||
double[] a = new double[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
a[i] = StdIn.readDouble();
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an array of doubles to standard output.
|
||||
*
|
||||
* @param a the 1D array of doubles
|
||||
*/
|
||||
public static void print(double[] a) {
|
||||
int n = a.length;
|
||||
StdOut.println(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
StdOut.printf("%9.5f ", a[i]);
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 2D array of doubles from standard input and returns it.
|
||||
*
|
||||
* @return the 2D array of doubles
|
||||
*/
|
||||
public static double[][] readDouble2D() {
|
||||
int m = StdIn.readInt();
|
||||
int n = StdIn.readInt();
|
||||
double[][] a = new double[m][n];
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
a[i][j] = StdIn.readDouble();
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the 2D array of doubles to standard output.
|
||||
*
|
||||
* @param a the 2D array of doubles
|
||||
*/
|
||||
public static void print(double[][] a) {
|
||||
int m = a.length;
|
||||
int n = a[0].length;
|
||||
StdOut.println(m + " " + n);
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
StdOut.printf("%9.5f ", a[i][j]);
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 1D array of integers from standard input and returns it.
|
||||
*
|
||||
* @return the 1D array of integers
|
||||
*/
|
||||
public static int[] readInt1D() {
|
||||
int n = StdIn.readInt();
|
||||
int[] a = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
a[i] = StdIn.readInt();
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an array of integers to standard output.
|
||||
*
|
||||
* @param a the 1D array of integers
|
||||
*/
|
||||
public static void print(int[] a) {
|
||||
int n = a.length;
|
||||
StdOut.println(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
StdOut.printf("%9d ", a[i]);
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 2D array of integers from standard input and returns it.
|
||||
*
|
||||
* @return the 2D array of integers
|
||||
*/
|
||||
public static int[][] readInt2D() {
|
||||
int m = StdIn.readInt();
|
||||
int n = StdIn.readInt();
|
||||
int[][] a = new int[m][n];
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
a[i][j] = StdIn.readInt();
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a 2D array of integers to standard output.
|
||||
*
|
||||
* @param a the 2D array of integers
|
||||
*/
|
||||
public static void print(int[][] a) {
|
||||
int m = a.length;
|
||||
int n = a[0].length;
|
||||
StdOut.println(m + " " + n);
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
StdOut.printf("%9d ", a[i][j]);
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 1D array of booleans from standard input and returns it.
|
||||
*
|
||||
* @return the 1D array of booleans
|
||||
*/
|
||||
public static boolean[] readBoolean1D() {
|
||||
int n = StdIn.readInt();
|
||||
boolean[] a = new boolean[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
a[i] = StdIn.readBoolean();
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a 1D array of booleans to standard output.
|
||||
*
|
||||
* @param a the 1D array of booleans
|
||||
*/
|
||||
public static void print(boolean[] a) {
|
||||
int n = a.length;
|
||||
StdOut.println(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (a[i]) StdOut.print("1 ");
|
||||
else StdOut.print("0 ");
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 2D array of booleans from standard input and returns it.
|
||||
*
|
||||
* @return the 2D array of booleans
|
||||
*/
|
||||
public static boolean[][] readBoolean2D() {
|
||||
int m = StdIn.readInt();
|
||||
int n = StdIn.readInt();
|
||||
boolean[][] a = new boolean[m][n];
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
a[i][j] = StdIn.readBoolean();
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a 2D array of booleans to standard output.
|
||||
*
|
||||
* @param a the 2D array of booleans
|
||||
*/
|
||||
public static void print(boolean[][] a) {
|
||||
int m = a.length;
|
||||
int n = a[0].length;
|
||||
StdOut.println(m + " " + n);
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (a[i][j]) StdOut.print("1 ");
|
||||
else StdOut.print("0 ");
|
||||
}
|
||||
StdOut.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests {@code StdArrayIO}.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
// read and print an array of doubles
|
||||
double[] a = StdArrayIO.readDouble1D();
|
||||
StdArrayIO.print(a);
|
||||
StdOut.println();
|
||||
|
||||
// read and print a matrix of doubles
|
||||
double[][] b = StdArrayIO.readDouble2D();
|
||||
StdArrayIO.print(b);
|
||||
StdOut.println();
|
||||
|
||||
// read and print a matrix of doubles
|
||||
boolean[][] d = StdArrayIO.readBoolean2D();
|
||||
StdArrayIO.print(d);
|
||||
StdOut.println();
|
||||
}
|
||||
|
||||
}
|
||||
669
common/StdIn.java
Normal file
669
common/StdIn.java
Normal file
|
|
@ -0,0 +1,669 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac StdIn.java
|
||||
* Execution: java StdIn (interactive test of basic functionality)
|
||||
* Dependencies: none
|
||||
*
|
||||
* Reads in data of various types from standard input.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.InputMismatchException;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* The {@code StdIn} class provides static methods for reading strings
|
||||
* and numbers from standard input.
|
||||
* These functions fall into one of four categories:
|
||||
* <ul>
|
||||
* <li>those for reading individual tokens from standard input, one at a time,
|
||||
* and converting each to a number, string, or boolean
|
||||
* <li>those for reading characters from standard input, one at a time
|
||||
* <li>those for reading lines from standard input, one at a time
|
||||
* <li>those for reading a sequence of values of the same type from standard input,
|
||||
* and returning the values in an array
|
||||
* </ul>
|
||||
* <p>
|
||||
* Generally, it is best not to mix functions from the different
|
||||
* categories in the same program.
|
||||
* <p>
|
||||
* <b>Getting started.</b>
|
||||
* To use this class, you must have {@code StdIn.class} in your
|
||||
* Java classpath. If you used our autoinstaller, you should be all set.
|
||||
* Otherwise, either download
|
||||
* <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a>
|
||||
* and add to your Java classpath or download
|
||||
* <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdIn.java">StdIn.java</a>
|
||||
* and put a copy in your working directory.
|
||||
* <p>
|
||||
* <b>Reading tokens from standard input and converting to numbers and strings.</b>
|
||||
* You can use the following methods to read numbers, strings, and booleans
|
||||
* from standard input one at a time:
|
||||
* <ul>
|
||||
* <li> {@link #isEmpty()}
|
||||
* <li> {@link #readInt()}
|
||||
* <li> {@link #readDouble()}
|
||||
* <li> {@link #readString()}
|
||||
* <li> {@link #readShort()}
|
||||
* <li> {@link #readLong()}
|
||||
* <li> {@link #readFloat()}
|
||||
* <li> {@link #readByte()}
|
||||
* <li> {@link #readBoolean()}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The first method returns true if standard input has no more tokens.
|
||||
* Each other method skips over any input that is whitespace. Then, it reads
|
||||
* the next token and attempts to convert it into a value of the specified
|
||||
* type. If it succeeds, it returns that value; otherwise, it
|
||||
* throws an {@link InputMismatchException}.
|
||||
* <p>
|
||||
* <em>Whitespace</em> includes spaces, tabs, and newlines; the full definition
|
||||
* is inherited from {@link Character#isWhitespace(char)}.
|
||||
* A <em>token</em> is a maximal sequence of non-whitespace characters.
|
||||
* The precise rules for describing which tokens can be converted to
|
||||
* integers and floating-point numbers are inherited from
|
||||
* <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#number-syntax">Scanner</a>,
|
||||
* using the locale {@link Locale#US}; the rules
|
||||
* for floating-point numbers are slightly different
|
||||
* from those in {@link Double#valueOf(String)},
|
||||
* but unlikely to be of concern to most programmers.
|
||||
* <p>
|
||||
* As an example, the following code fragment reads integers from standard input,
|
||||
* one at a time, and prints them one per line.
|
||||
* <pre>
|
||||
* while (!StdIn.isEmpty()) {
|
||||
* double value = StdIn.readDouble();
|
||||
* StdOut.println(value);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>Reading characters from standard input.</b>
|
||||
* You can use the following two methods to read characters from standard input one at a time:
|
||||
* <ul>
|
||||
* <li> {@link #hasNextChar()}
|
||||
* <li> {@link #readChar()}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The first method returns true if standard input has more input (including whitespace).
|
||||
* The second method reads and returns the next character of input on standard
|
||||
* input (possibly a whitespace character).
|
||||
* <p>
|
||||
* As an example, the following code fragment reads characters from standard input,
|
||||
* one character at a time, and prints it to standard output.
|
||||
* <pre>
|
||||
* while (StdIn.hasNextChar()) {
|
||||
* char c = StdIn.readChar();
|
||||
* StdOut.print(c);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>Reading lines from standard input.</b>
|
||||
* You can use the following two methods to read lines from standard input:
|
||||
* <ul>
|
||||
* <li> {@link #hasNextLine()}
|
||||
* <li> {@link #readLine()}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The first method returns true if standard input has more input (including whitespace).
|
||||
* The second method reads and returns the remaining portion of
|
||||
* the next line of input on standard input (possibly whitespace),
|
||||
* discarding the trailing line separator.
|
||||
* <p>
|
||||
* A <em>line separator</em> is defined to be one of the following strings:
|
||||
* {@code \n} (Linux), {@code \r} (old Macintosh),
|
||||
* {@code \r\n} (Windows),
|
||||
* {@code \}{@code u2028}, {@code \}{@code u2029}, or {@code \}{@code u0085}.
|
||||
* <p>
|
||||
* As an example, the following code fragment reads text from standard input,
|
||||
* one line at a time, and prints it to standard output.
|
||||
* <pre>
|
||||
* while (StdIn.hasNextLine()) {
|
||||
* String line = StdIn.readLine();
|
||||
* StdOut.println(line);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>Reading a sequence of values of the same type from standard input.</b>
|
||||
* You can use the following methods to read a sequence numbers, strings,
|
||||
* or booleans (all of the same type) from standard input:
|
||||
* <ul>
|
||||
* <li> {@link #readAllDoubles()}
|
||||
* <li> {@link #readAllInts()}
|
||||
* <li> {@link #readAllLongs()}
|
||||
* <li> {@link #readAllStrings()}
|
||||
* <li> {@link #readAllLines()}
|
||||
* <li> {@link #readAll()}
|
||||
* </ul>
|
||||
* <p>
|
||||
* The first three methods read of all of remaining token on standard input
|
||||
* and converts the tokens to values of
|
||||
* the specified type, as in the corresponding
|
||||
* {@code readDouble}, {@code readInt}, and {@code readString()} methods.
|
||||
* The {@code readAllLines()} method reads all remaining lines on standard
|
||||
* input and returns them as an array of strings.
|
||||
* The {@code readAll()} method reads all remaining input on standard
|
||||
* input and returns it as a string.
|
||||
* <p>
|
||||
* As an example, the following code fragment reads all of the remaining
|
||||
* tokens from standard input and returns them as an array of strings.
|
||||
* <pre>
|
||||
* String[] words = StdIn.readAllStrings();
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>Differences with Scanner.</b>
|
||||
* {@code StdIn} and {@link Scanner} are both designed to parse
|
||||
* tokens and convert them to primitive types and strings.
|
||||
* The main differences are summarized below:
|
||||
* <ul>
|
||||
* <li> {@code StdIn} is a set of static methods and reads
|
||||
* reads input from only standard input. It is suitable for use before
|
||||
* a programmer knows about objects.
|
||||
* See {@link In} for an object-oriented version that handles
|
||||
* input from files, URLs,
|
||||
* and sockets.
|
||||
* <li> {@code StdIn} uses whitespace as the delimiter pattern
|
||||
* that separates tokens.
|
||||
* {@link Scanner} supports arbitrary delimiter patterns.
|
||||
* <li> {@code StdIn} coerces the character-set encoding to UTF-8,
|
||||
* which is the most widely used character encoding for Unicode.
|
||||
* <li> {@code StdIn} coerces the locale to {@link Locale#US},
|
||||
* for consistency with {@link StdOut}, {@link Double#parseDouble(String)},
|
||||
* and floating-point literals.
|
||||
* <li> {@code StdIn} has convenient methods for reading a single
|
||||
* character; reading in sequences of integers, doubles, or strings;
|
||||
* and reading in all of the remaining input.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Historical note: {@code StdIn} preceded {@code Scanner}; when
|
||||
* {@code Scanner} was introduced, this class was re-implemented to use {@code Scanner}.
|
||||
* <p>
|
||||
* <b>Using standard input.</b>
|
||||
* Standard input is a fundamental operating system abstraction on Mac OS X,
|
||||
* Windows, and Linux.
|
||||
* The methods in {@code StdIn} are <em>blocking</em>, which means that they
|
||||
* will wait until you enter input on standard input.
|
||||
* If your program has a loop that repeats until standard input is empty,
|
||||
* you must signal that the input is finished.
|
||||
* To do so, depending on your operating system and IDE,
|
||||
* use either {@code <Ctrl-d>} or {@code <Ctrl-z>}, on its own line.
|
||||
* If you are redirecting standard input from a file, you will not need
|
||||
* to do anything to signal that the input is finished.
|
||||
* <p>
|
||||
* <b>Known bugs.</b>
|
||||
* Java's UTF-8 encoding does not recognize the optional
|
||||
* <a href = "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058">byte-order mask</a>.
|
||||
* If the input begins with the optional byte-order mask, {@code StdIn}
|
||||
* will have an extra character {@code \}{@code uFEFF} at the beginning.
|
||||
* <p>
|
||||
* <b>Reference.</b>
|
||||
* For additional documentation,
|
||||
* see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of
|
||||
* <em>Computer Science: An Interdisciplinary Approach</em>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
* @author David Pritchard
|
||||
*/
|
||||
public final class StdIn {
|
||||
|
||||
/*** begin: section (1 of 2) of code duplicated from In to StdIn. */
|
||||
|
||||
// assume Unicode UTF-8 encoding
|
||||
private static final String CHARSET_NAME = "UTF-8";
|
||||
|
||||
// assume language = English, country = US for consistency with System.out.
|
||||
private static final Locale LOCALE = Locale.US;
|
||||
|
||||
// the default token separator; we maintain the invariant that this value
|
||||
// is held by the scanner's delimiter between calls
|
||||
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");
|
||||
|
||||
// makes whitespace significant
|
||||
private static final Pattern EMPTY_PATTERN = Pattern.compile("");
|
||||
|
||||
// used to read the entire input
|
||||
private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A");
|
||||
|
||||
/*** end: section (1 of 2) of code duplicated from In to StdIn. */
|
||||
|
||||
private static Scanner scanner;
|
||||
|
||||
// it doesn't make sense to instantiate this class
|
||||
private StdIn() { }
|
||||
|
||||
//// begin: section (2 of 2) of code duplicated from In to StdIn,
|
||||
//// with all methods changed from "public" to "public static"
|
||||
|
||||
/**
|
||||
* Returns true if standard input is empty (except possibly for whitespace).
|
||||
* Use this method to know whether the next call to {@link #readString()},
|
||||
* {@link #readDouble()}, etc. will succeed.
|
||||
*
|
||||
* @return {@code true} if standard input is empty (except possibly
|
||||
* for whitespace); {@code false} otherwise
|
||||
*/
|
||||
public static boolean isEmpty() {
|
||||
return !scanner.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if standard input has a next line.
|
||||
* Use this method to know whether the
|
||||
* next call to {@link #readLine()} will succeed.
|
||||
* This method is functionally equivalent to {@link #hasNextChar()}.
|
||||
*
|
||||
* @return {@code true} if standard input has more input (including whitespace);
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public static boolean hasNextLine() {
|
||||
return scanner.hasNextLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if standard input has more input (including whitespace).
|
||||
* Use this method to know whether the next call to {@link #readChar()} will succeed.
|
||||
* This method is functionally equivalent to {@link #hasNextLine()}.
|
||||
*
|
||||
* @return {@code true} if standard input has more input (including whitespace);
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public static boolean hasNextChar() {
|
||||
scanner.useDelimiter(EMPTY_PATTERN);
|
||||
boolean result = scanner.hasNext();
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and returns the next line, excluding the line separator if present.
|
||||
*
|
||||
* @return the next line, excluding the line separator if present;
|
||||
* {@code null} if no such line
|
||||
*/
|
||||
public static String readLine() {
|
||||
String line;
|
||||
try {
|
||||
line = scanner.nextLine();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
line = null;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns the next character.
|
||||
*
|
||||
* @return the next {@code char}
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
*/
|
||||
public static char readChar() {
|
||||
try {
|
||||
scanner.useDelimiter(EMPTY_PATTERN);
|
||||
String ch = scanner.next();
|
||||
assert ch.length() == 1 : "Internal (Std)In.readChar() error!"
|
||||
+ " Please contact the authors.";
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN);
|
||||
return ch.charAt(0);
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'char' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns the remainder of the input, as a string.
|
||||
*
|
||||
* @return the remainder of the input, as a string
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
*/
|
||||
public static String readAll() {
|
||||
if (!scanner.hasNextLine())
|
||||
return "";
|
||||
|
||||
String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
|
||||
// not that important to reset delimiter, since now scanner is empty
|
||||
scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input and returns it as a {@code String}.
|
||||
*
|
||||
* @return the next {@code String}
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
*/
|
||||
public static String readString() {
|
||||
try {
|
||||
return scanner.next();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'String' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as an integer, and returns the integer.
|
||||
*
|
||||
* @return the next integer on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as an {@code int}
|
||||
*/
|
||||
public static int readInt() {
|
||||
try {
|
||||
return scanner.nextInt();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read an 'int' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attemps to read an 'int' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a double, and returns the double.
|
||||
*
|
||||
* @return the next double on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code double}
|
||||
*/
|
||||
public static double readDouble() {
|
||||
try {
|
||||
return scanner.nextDouble();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'double' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'double' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a float, and returns the float.
|
||||
*
|
||||
* @return the next float on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code float}
|
||||
*/
|
||||
public static float readFloat() {
|
||||
try {
|
||||
return scanner.nextFloat();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'float' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'float' value from standard input, "
|
||||
+ "but there no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a long integer, and returns the long integer.
|
||||
*
|
||||
* @return the next long integer on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code long}
|
||||
*/
|
||||
public static long readLong() {
|
||||
try {
|
||||
return scanner.nextLong();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'long' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'long' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a short integer, and returns the short integer.
|
||||
*
|
||||
* @return the next short integer on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code short}
|
||||
*/
|
||||
public static short readShort() {
|
||||
try {
|
||||
return scanner.nextShort();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'short' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'short' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a byte, and returns the byte.
|
||||
*
|
||||
* @return the next byte on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code byte}
|
||||
*/
|
||||
public static byte readByte() {
|
||||
try {
|
||||
return scanner.nextByte();
|
||||
}
|
||||
catch (InputMismatchException e) {
|
||||
String token = scanner.next();
|
||||
throw new InputMismatchException("attempts to read a 'byte' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'byte' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next token from standard input, parses it as a boolean,
|
||||
* and returns the boolean.
|
||||
*
|
||||
* @return the next boolean on standard input
|
||||
* @throws NoSuchElementException if standard input is empty
|
||||
* @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}:
|
||||
* {@code true} or {@code 1} for true, and {@code false} or {@code 0} for false,
|
||||
* ignoring case
|
||||
*/
|
||||
public static boolean readBoolean() {
|
||||
try {
|
||||
String token = readString();
|
||||
if ("true".equalsIgnoreCase(token)) return true;
|
||||
if ("false".equalsIgnoreCase(token)) return false;
|
||||
if ("1".equals(token)) return true;
|
||||
if ("0".equals(token)) return false;
|
||||
throw new InputMismatchException("attempts to read a 'boolean' value from standard input, "
|
||||
+ "but the next token is \"" + token + "\"");
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new NoSuchElementException("attempts to read a 'boolean' value from standard input, "
|
||||
+ "but no more tokens are available");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from standard input and returns them as an array of strings.
|
||||
*
|
||||
* @return all remaining tokens on standard input, as an array of strings
|
||||
*/
|
||||
public static String[] readAllStrings() {
|
||||
// we could use readAll.trim().split(), but that's not consistent
|
||||
// because trim() uses characters 0x00..0x20 as whitespace
|
||||
String[] tokens = WHITESPACE_PATTERN.split(readAll());
|
||||
if (tokens.length == 0 || tokens[0].length() > 0)
|
||||
return tokens;
|
||||
|
||||
// don't include first token if it is leading whitespace
|
||||
String[] decapitokens = new String[tokens.length-1];
|
||||
for (int i = 0; i < tokens.length - 1; i++)
|
||||
decapitokens[i] = tokens[i+1];
|
||||
return decapitokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining lines from standard input and returns them as an array of strings.
|
||||
* @return all remaining lines on standard input, as an array of strings
|
||||
*/
|
||||
public static String[] readAllLines() {
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
while (hasNextLine()) {
|
||||
lines.add(readLine());
|
||||
}
|
||||
return lines.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from standard input, parses them as integers, and returns
|
||||
* them as an array of integers.
|
||||
* @return all remaining integers on standard input, as an array
|
||||
* @throws InputMismatchException if any token cannot be parsed as an {@code int}
|
||||
*/
|
||||
public static int[] readAllInts() {
|
||||
String[] fields = readAllStrings();
|
||||
int[] vals = new int[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Integer.parseInt(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from standard input, parses them as longs, and returns
|
||||
* them as an array of longs.
|
||||
* @return all remaining longs on standard input, as an array
|
||||
* @throws InputMismatchException if any token cannot be parsed as a {@code long}
|
||||
*/
|
||||
public static long[] readAllLongs() {
|
||||
String[] fields = readAllStrings();
|
||||
long[] vals = new long[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Long.parseLong(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens from standard input, parses them as doubles, and returns
|
||||
* them as an array of doubles.
|
||||
* @return all remaining doubles on standard input, as an array
|
||||
* @throws InputMismatchException if any token cannot be parsed as a {@code double}
|
||||
*/
|
||||
public static double[] readAllDoubles() {
|
||||
String[] fields = readAllStrings();
|
||||
double[] vals = new double[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
vals[i] = Double.parseDouble(fields[i]);
|
||||
return vals;
|
||||
}
|
||||
|
||||
//// end: section (2 of 2) of code duplicated from In to StdIn
|
||||
|
||||
// do this once when StdIn is initialized
|
||||
static {
|
||||
resync();
|
||||
}
|
||||
|
||||
/**
|
||||
* If StdIn changes, use this to reinitialize the scanner.
|
||||
*/
|
||||
private static void resync() {
|
||||
setScanner(new Scanner(new java.io.BufferedInputStream(System.in), CHARSET_NAME));
|
||||
}
|
||||
|
||||
private static void setScanner(Scanner scanner) {
|
||||
StdIn.scanner = scanner;
|
||||
StdIn.scanner.useLocale(LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens, parses them as integers, and returns
|
||||
* them as an array of integers.
|
||||
* @return all remaining integers, as an array
|
||||
* @throws InputMismatchException if any token cannot be parsed as an {@code int}
|
||||
* @deprecated Replaced by {@link #readAllInts()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int[] readInts() {
|
||||
return readAllInts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens, parses them as doubles, and returns
|
||||
* them as an array of doubles.
|
||||
* @return all remaining doubles, as an array
|
||||
* @throws InputMismatchException if any token cannot be parsed as a {@code double}
|
||||
* @deprecated Replaced by {@link #readAllDoubles()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double[] readDoubles() {
|
||||
return readAllDoubles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all remaining tokens and returns them as an array of strings.
|
||||
* @return all remaining tokens, as an array of strings
|
||||
* @deprecated Replaced by {@link #readAllStrings()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String[] readStrings() {
|
||||
return readAllStrings();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interactive test of basic functionality.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
StdOut.print("Type a string: ");
|
||||
String s = StdIn.readString();
|
||||
StdOut.println("Your string was: " + s);
|
||||
StdOut.println();
|
||||
|
||||
StdOut.print("Type an int: ");
|
||||
int a = StdIn.readInt();
|
||||
StdOut.println("Your int was: " + a);
|
||||
StdOut.println();
|
||||
|
||||
StdOut.print("Type a boolean: ");
|
||||
boolean b = StdIn.readBoolean();
|
||||
StdOut.println("Your boolean was: " + b);
|
||||
StdOut.println();
|
||||
|
||||
StdOut.print("Type a double: ");
|
||||
double c = StdIn.readDouble();
|
||||
StdOut.println("Your double was: " + c);
|
||||
StdOut.println();
|
||||
}
|
||||
|
||||
}
|
||||
312
common/StdOut.java
Normal file
312
common/StdOut.java
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac StdOut.java
|
||||
* Execution: java StdOut
|
||||
* Dependencies: none
|
||||
*
|
||||
* Writes data of various types to standard output.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The {@code StdOut} class provides static methods for printing strings
|
||||
* and numbers to standard output.
|
||||
*
|
||||
* <p><b>Getting started.</b>
|
||||
* To use this class, you must have {@code StdOut.class} in your
|
||||
* Java classpath. If you used our autoinstaller, you should be all set.
|
||||
* Otherwise, either download
|
||||
* <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a>
|
||||
* and add to your Java classpath or download
|
||||
* <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdOut.java">StdOut.java</a>
|
||||
* and put a copy in your working directory.
|
||||
* <p>
|
||||
* Here is an example program that uses {@code StdOut}:
|
||||
* <pre>
|
||||
* public class TestStdOut {
|
||||
* public static void main(String[] args) {
|
||||
* int a = 17;
|
||||
* int b = 23;
|
||||
* int sum = a + b;
|
||||
* StdOut.println("Hello, World");
|
||||
* StdOut.printf("%d + %d = %d\n", a, b, sum);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* <b>Differences with System.out.</b>
|
||||
* The behavior of {@code StdOut} is similar to that of {@link System#out},
|
||||
* but there are a few technical differences:
|
||||
* <ul>
|
||||
* <li> {@code StdOut} coerces the character-set encoding to UTF-8,
|
||||
* which is a standard character encoding for Unicode.
|
||||
* <li> {@code StdOut} coerces the locale to {@link Locale#US},
|
||||
* for consistency with {@link StdIn}, {@link Double#parseDouble(String)},
|
||||
* and floating-point literals.
|
||||
* <li> {@code StdOut} <em>flushes</em> standard output after each call to
|
||||
* {@code print()} so that text will appear immediately in the terminal.
|
||||
* </ul>
|
||||
* <p>
|
||||
* <b>Reference.</b>
|
||||
* For additional documentation,
|
||||
* see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of
|
||||
* <em>Computer Science: An Interdisciplinary Approach</em>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
public final class StdOut {
|
||||
|
||||
// force Unicode UTF-8 encoding; otherwise it's system dependent
|
||||
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
// assume language = English, country = US for consistency with StdIn
|
||||
private static final Locale LOCALE = Locale.US;
|
||||
|
||||
// send output here
|
||||
private static PrintWriter out;
|
||||
|
||||
// this is called before invoking any methods
|
||||
static {
|
||||
out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET), true);
|
||||
}
|
||||
|
||||
// don't instantiate
|
||||
private StdOut() { }
|
||||
|
||||
/**
|
||||
* Terminates the current line by printing the line-separator string.
|
||||
*/
|
||||
public static void println() {
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an object to this output stream and then terminates the line.
|
||||
*
|
||||
* @param x the object to print
|
||||
*/
|
||||
public static void println(Object x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a boolean to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the boolean to print
|
||||
*/
|
||||
public static void println(boolean x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a character to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the character to print
|
||||
*/
|
||||
public static void println(char x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a double to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the double to print
|
||||
*/
|
||||
public static void println(double x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an integer to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the integer to print
|
||||
*/
|
||||
public static void println(float x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an integer to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the integer to print
|
||||
*/
|
||||
public static void println(int x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a long to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the long to print
|
||||
*/
|
||||
public static void println(long x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a short integer to standard output and then terminates the line.
|
||||
*
|
||||
* @param x the short to print
|
||||
*/
|
||||
public static void println(short x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a byte to standard output and then terminates the line.
|
||||
* <p>
|
||||
* To write binary data, see {@link BinaryStdOut}.
|
||||
*
|
||||
* @param x the byte to print
|
||||
*/
|
||||
public static void println(byte x) {
|
||||
out.println(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes standard output.
|
||||
*/
|
||||
public static void print() {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an object to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the object to print
|
||||
*/
|
||||
public static void print(Object x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a boolean to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the boolean to print
|
||||
*/
|
||||
public static void print(boolean x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a character to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the character to print
|
||||
*/
|
||||
public static void print(char x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a double to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the double to print
|
||||
*/
|
||||
public static void print(double x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a float to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the float to print
|
||||
*/
|
||||
public static void print(float x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an integer to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the integer to print
|
||||
*/
|
||||
public static void print(int x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a long integer to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the long integer to print
|
||||
*/
|
||||
public static void print(long x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a short integer to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the short integer to print
|
||||
*/
|
||||
public static void print(short x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a byte to standard output and flushes standard output.
|
||||
*
|
||||
* @param x the byte to print
|
||||
*/
|
||||
public static void print(byte x) {
|
||||
out.print(x);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a formatted string to standard output, using the specified format
|
||||
* string and arguments, and then flushes standard output.
|
||||
*
|
||||
*
|
||||
* @param format the <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">format string</a>
|
||||
* @param args the arguments accompanying the format string
|
||||
*/
|
||||
public static void printf(String format, Object... args) {
|
||||
out.printf(LOCALE, format, args);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a formatted string to standard output, using the locale and
|
||||
* the specified format string and arguments; then flushes standard output.
|
||||
*
|
||||
* @param locale the locale
|
||||
* @param format the <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">format string</a>
|
||||
* @param args the arguments accompanying the format string
|
||||
*/
|
||||
public static void printf(Locale locale, String format, Object... args) {
|
||||
out.printf(locale, format, args);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests some methods in {@code StdOut}.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
// write to stdout
|
||||
StdOut.println("Test");
|
||||
StdOut.println(17);
|
||||
StdOut.println(true);
|
||||
StdOut.printf("%.6f\n", 1.0/7.0);
|
||||
}
|
||||
|
||||
}
|
||||
737
common/StdRandom.java
Normal file
737
common/StdRandom.java
Normal file
|
|
@ -0,0 +1,737 @@
|
|||
package common;
|
||||
/******************************************************************************
|
||||
* Compilation: javac StdRandom.java
|
||||
* Execution: java StdRandom
|
||||
* Dependencies: StdOut.java
|
||||
*
|
||||
* A library of static methods to generate pseudo-random numbers from
|
||||
* different distributions (bernoulli, uniform, gaussian, discrete,
|
||||
* and exponential). Also includes a method for shuffling an array.
|
||||
*
|
||||
*
|
||||
* % java StdRandom 5
|
||||
* seed = 1316600602069
|
||||
* 59 16.81826 true 8.83954 0
|
||||
* 32 91.32098 true 9.11026 0
|
||||
* 35 10.11874 true 8.95396 3
|
||||
* 92 32.88401 true 8.87089 0
|
||||
* 72 92.55791 true 9.46241 0
|
||||
*
|
||||
* % java StdRandom 5
|
||||
* seed = 1316600616575
|
||||
* 96 60.17070 true 8.72821 0
|
||||
* 79 32.01607 true 8.58159 0
|
||||
* 81 59.49065 true 9.10423 1
|
||||
* 96 51.65818 true 9.02102 0
|
||||
* 99 17.55771 true 8.99762 0
|
||||
*
|
||||
* % java StdRandom 5 1316600616575
|
||||
* seed = 1316600616575
|
||||
* 96 60.17070 true 8.72821 0
|
||||
* 79 32.01607 true 8.58159 0
|
||||
* 81 59.49065 true 9.10423 1
|
||||
* 96 51.65818 true 9.02102 0
|
||||
* 99 17.55771 true 8.99762 0
|
||||
*
|
||||
*
|
||||
* Remark
|
||||
* ------
|
||||
* - Relies on randomness of nextDouble() method in java.util.Random
|
||||
* to generate pseudo-random numbers in [0, 1).
|
||||
*
|
||||
* - This library allows you to set and get the pseudo-random number seed.
|
||||
*
|
||||
* - See http://www.honeylocust.com/RngPack/ for an industrial
|
||||
* strength random number generator in Java.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* The {@code StdRandom} class provides static methods for generating
|
||||
* random number from various discrete and continuous distributions,
|
||||
* including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto,
|
||||
* Poisson, and Cauchy. It also provides method for shuffling an
|
||||
* array or subarray and generating random permutations.
|
||||
*
|
||||
* <p><b>Conventions.</b>
|
||||
* By convention, all intervals are half open. For example,
|
||||
* <code>uniformDouble(-1.0, 1.0)</code> returns a random number between
|
||||
* <code>-1.0</code> (inclusive) and <code>1.0</code> (exclusive).
|
||||
* Similarly, <code>shuffle(a, lo, hi)</code> shuffles the <code>hi - lo</code>
|
||||
* elements in the array <code>a[]</code>, starting at index <code>lo</code>
|
||||
* (inclusive) and ending at index <code>hi</code> (exclusive).
|
||||
*
|
||||
* <p><b>Performance.</b>
|
||||
* The methods all take constant expected time, except those that involve arrays.
|
||||
* The <em>shuffle</em> method takes time linear in the subarray to be shuffled;
|
||||
* the <em>discrete</em> methods take time linear in the length of the argument
|
||||
* array.
|
||||
*
|
||||
* <p><b>Additional information.</b>
|
||||
* For additional documentation,
|
||||
* see <a href="https://introcs.cs.princeton.edu/22library">Section 2.2</a> of
|
||||
* <i>Computer Science: An Interdisciplinary Approach</i>
|
||||
* by Robert Sedgewick and Kevin Wayne.
|
||||
*
|
||||
* @author Robert Sedgewick
|
||||
* @author Kevin Wayne
|
||||
*/
|
||||
public final class StdRandom {
|
||||
|
||||
private static Random random; // pseudo-random number generator
|
||||
private static long seed; // pseudo-random number generator seed
|
||||
|
||||
// static initializer
|
||||
static {
|
||||
// this is how the seed was set in Java 1.4
|
||||
seed = System.currentTimeMillis();
|
||||
random = new Random(seed);
|
||||
}
|
||||
|
||||
// don't instantiate
|
||||
private StdRandom() { }
|
||||
|
||||
/**
|
||||
* Sets the seed of the pseudo-random number generator.
|
||||
* This method enables you to produce the same sequence of "random"
|
||||
* number for each execution of the program.
|
||||
* Ordinarily, you should call this method at most once per program.
|
||||
*
|
||||
* @param s the seed
|
||||
*/
|
||||
public static void setSeed(long s) {
|
||||
seed = s;
|
||||
random = new Random(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the seed of the pseudo-random number generator.
|
||||
*
|
||||
* @return the seed
|
||||
*/
|
||||
public static long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number uniformly in [0, 1).
|
||||
*
|
||||
* @return a random real number uniformly in [0, 1)
|
||||
* @deprecated Replaced by {@link #uniformDouble()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double uniform() {
|
||||
return uniformDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number uniformly in [0, 1).
|
||||
*
|
||||
* @return a random real number uniformly in [0, 1)
|
||||
*/
|
||||
public static double uniformDouble() {
|
||||
return random.nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer uniformly in [0, n).
|
||||
*
|
||||
* @param n number of possible integers
|
||||
* @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive)
|
||||
* @throws IllegalArgumentException if {@code n <= 0}
|
||||
* @deprecated Replaced by {@link #uniformInt(int n)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int uniform(int n) {
|
||||
return uniformInt(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer uniformly in [0, n).
|
||||
*
|
||||
* @param n number of possible integers
|
||||
* @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive)
|
||||
* @throws IllegalArgumentException if {@code n <= 0}
|
||||
*/
|
||||
public static int uniformInt(int n) {
|
||||
if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n);
|
||||
return random.nextInt(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random long integer uniformly in [0, n).
|
||||
*
|
||||
* @param n number of possible {@code long} integers
|
||||
* @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive)
|
||||
* @throws IllegalArgumentException if {@code n <= 0}
|
||||
* @deprecated Replaced by {@link #uniformLong(long n)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static long uniform(long n) {
|
||||
return uniformLong(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random long integer uniformly in [0, n).
|
||||
*
|
||||
* @param n number of possible {@code long} integers
|
||||
* @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive)
|
||||
* @throws IllegalArgumentException if {@code n <= 0}
|
||||
*/
|
||||
public static long uniformLong(long n) {
|
||||
if (n <= 0L) throw new IllegalArgumentException("argument must be positive: " + n);
|
||||
|
||||
// https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-
|
||||
long r = random.nextLong();
|
||||
long m = n - 1;
|
||||
|
||||
// power of two
|
||||
if ((n & m) == 0L) {
|
||||
return r & m;
|
||||
}
|
||||
|
||||
// reject over-represented candidates
|
||||
long u = r >>> 1;
|
||||
while (u + m - (r = u % n) < 0L) {
|
||||
u = random.nextLong() >>> 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA
|
||||
// THE STATIC METHODS ABOVE.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns a random real number uniformly in [0, 1).
|
||||
*
|
||||
* @return a random real number uniformly in [0, 1)
|
||||
* @deprecated Replaced by {@link #uniformDouble()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double random() {
|
||||
return uniformDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer uniformly in [a, b).
|
||||
*
|
||||
* @param a the left endpoint
|
||||
* @param b the right endpoint
|
||||
* @return a random integer uniformly in [a, b)
|
||||
* @throws IllegalArgumentException if {@code b <= a}
|
||||
* @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE}
|
||||
* @deprecated Replaced by {@link #uniformInt(int a, int b)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int uniform(int a, int b) {
|
||||
return uniformInt(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer uniformly in [a, b).
|
||||
*
|
||||
* @param a the left endpoint
|
||||
* @param b the right endpoint
|
||||
* @return a random integer uniformly in [a, b)
|
||||
* @throws IllegalArgumentException if {@code b <= a}
|
||||
* @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE}
|
||||
*/
|
||||
public static int uniformInt(int a, int b) {
|
||||
if ((b <= a) || ((long) b - a >= Integer.MAX_VALUE)) {
|
||||
throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
|
||||
}
|
||||
return a + uniform(b - a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number uniformly in [a, b).
|
||||
*
|
||||
* @param a the left endpoint
|
||||
* @param b the right endpoint
|
||||
* @return a random real number uniformly in [a, b)
|
||||
* @throws IllegalArgumentException unless {@code a < b}
|
||||
* @deprecated Replaced by {@link #uniformDouble(double a, double b)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double uniform(double a, double b) {
|
||||
return uniformDouble(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number uniformly in [a, b).
|
||||
*
|
||||
* @param a the left endpoint
|
||||
* @param b the right endpoint
|
||||
* @return a random real number uniformly in [a, b)
|
||||
* @throws IllegalArgumentException unless {@code a < b}
|
||||
*/
|
||||
public static double uniformDouble(double a, double b) {
|
||||
if (!(a < b)) {
|
||||
throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
|
||||
}
|
||||
return a + uniform() * (b-a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random boolean from a Bernoulli distribution with success
|
||||
* probability <em>p</em>.
|
||||
*
|
||||
* @param p the probability of returning {@code true}
|
||||
* @return {@code true} with probability {@code p} and
|
||||
* {@code false} with probability {@code 1 - p}
|
||||
* @throws IllegalArgumentException unless {@code 0} ≤ {@code p} ≤ {@code 1.0}
|
||||
*/
|
||||
public static boolean bernoulli(double p) {
|
||||
if (!(p >= 0.0 && p <= 1.0))
|
||||
throw new IllegalArgumentException("probability p must be between 0.0 and 1.0: " + p);
|
||||
return uniformDouble() < p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random boolean from a Bernoulli distribution with success
|
||||
* probability 1/2.
|
||||
*
|
||||
* @return {@code true} with probability 1/2 and
|
||||
* {@code false} with probability 1/2
|
||||
*/
|
||||
public static boolean bernoulli() {
|
||||
return bernoulli(0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from a standard Gaussian distribution.
|
||||
*
|
||||
* @return a random real number from a standard Gaussian distribution
|
||||
* (mean 0 and standard deviation 1).
|
||||
*/
|
||||
public static double gaussian() {
|
||||
// use the polar form of the Box-Muller transform
|
||||
double r, x, y;
|
||||
do {
|
||||
x = uniformDouble(-1.0, 1.0);
|
||||
y = uniformDouble(-1.0, 1.0);
|
||||
r = x*x + y*y;
|
||||
} while (r >= 1 || r == 0);
|
||||
return x * Math.sqrt(-2 * Math.log(r) / r);
|
||||
|
||||
// Remark: y * Math.sqrt(-2 * Math.log(r) / r)
|
||||
// is an independent random gaussian
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from a Gaussian distribution with mean μ
|
||||
* and standard deviation σ.
|
||||
*
|
||||
* @param mu the mean
|
||||
* @param sigma the standard deviation
|
||||
* @return a real number distributed according to the Gaussian distribution
|
||||
* with mean {@code mu} and standard deviation {@code sigma}
|
||||
*/
|
||||
public static double gaussian(double mu, double sigma) {
|
||||
return mu + sigma * gaussian();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer from a geometric distribution with success
|
||||
* probability <em>p</em>.
|
||||
* The integer represents the number of independent trials
|
||||
* before the first success.
|
||||
*
|
||||
* @param p the parameter of the geometric distribution
|
||||
* @return a random integer from a geometric distribution with success
|
||||
* probability {@code p}; or {@code Integer.MAX_VALUE} if
|
||||
* {@code p} is (nearly) equal to {@code 1.0}.
|
||||
* @throws IllegalArgumentException unless {@code p >= 0.0} and {@code p <= 1.0}
|
||||
*/
|
||||
public static int geometric(double p) {
|
||||
if (!(p >= 0)) {
|
||||
throw new IllegalArgumentException("probability p must be greater than 0: " + p);
|
||||
}
|
||||
if (!(p <= 1.0)) {
|
||||
throw new IllegalArgumentException("probability p must not be larger than 1: " + p);
|
||||
}
|
||||
// using algorithm given by Knuth
|
||||
return (int) Math.ceil(Math.log(uniformDouble()) / Math.log(1.0 - p));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer from a Poisson distribution with mean λ.
|
||||
*
|
||||
* @param lambda the mean of the Poisson distribution
|
||||
* @return a random integer from a Poisson distribution with mean {@code lambda}
|
||||
* @throws IllegalArgumentException unless {@code lambda > 0.0} and not infinite
|
||||
*/
|
||||
public static int poisson(double lambda) {
|
||||
if (!(lambda > 0.0))
|
||||
throw new IllegalArgumentException("lambda must be positive: " + lambda);
|
||||
if (Double.isInfinite(lambda))
|
||||
throw new IllegalArgumentException("lambda must not be infinite: " + lambda);
|
||||
// using algorithm given by Knuth
|
||||
// see http://en.wikipedia.org/wiki/Poisson_distribution
|
||||
int k = 0;
|
||||
double p = 1.0;
|
||||
double expLambda = Math.exp(-lambda);
|
||||
do {
|
||||
k++;
|
||||
p *= uniformDouble();
|
||||
} while (p >= expLambda);
|
||||
return k-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from the standard Pareto distribution.
|
||||
*
|
||||
* @return a random real number from the standard Pareto distribution
|
||||
*/
|
||||
public static double pareto() {
|
||||
return pareto(1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from a Pareto distribution with
|
||||
* shape parameter α.
|
||||
*
|
||||
* @param alpha shape parameter
|
||||
* @return a random real number from a Pareto distribution with shape
|
||||
* parameter {@code alpha}
|
||||
* @throws IllegalArgumentException unless {@code alpha > 0.0}
|
||||
*/
|
||||
public static double pareto(double alpha) {
|
||||
if (!(alpha > 0.0))
|
||||
throw new IllegalArgumentException("alpha must be positive: " + alpha);
|
||||
return Math.pow(1 - uniformDouble(), -1.0 / alpha) - 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from the Cauchy distribution.
|
||||
*
|
||||
* @return a random real number from the Cauchy distribution.
|
||||
*/
|
||||
public static double cauchy() {
|
||||
return Math.tan(Math.PI * (uniformDouble() - 0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer from the specified discrete distribution.
|
||||
*
|
||||
* @param probabilities the probability of occurrence of each integer
|
||||
* @return a random integer from a discrete distribution:
|
||||
* {@code i} with probability {@code probabilities[i]}
|
||||
* @throws IllegalArgumentException if {@code probabilities} is {@code null}
|
||||
* @throws IllegalArgumentException if sum of array entries is not (very nearly) equal to {@code 1.0}
|
||||
* @throws IllegalArgumentException unless {@code probabilities[i] >= 0.0} for each index {@code i}
|
||||
*/
|
||||
public static int discrete(double[] probabilities) {
|
||||
if (probabilities == null) throw new IllegalArgumentException("argument array must not be null");
|
||||
double EPSILON = 1.0E-14;
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < probabilities.length; i++) {
|
||||
if (!(probabilities[i] >= 0.0))
|
||||
throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + probabilities[i]);
|
||||
sum += probabilities[i];
|
||||
}
|
||||
if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON)
|
||||
throw new IllegalArgumentException("sum of array entries does not approximately equal 1.0: " + sum);
|
||||
|
||||
// the for loop may not return a value when both r is (nearly) 1.0 and when the
|
||||
// cumulative sum is less than 1.0 (as a result of floating-point roundoff error)
|
||||
while (true) {
|
||||
double r = uniformDouble();
|
||||
sum = 0.0;
|
||||
for (int i = 0; i < probabilities.length; i++) {
|
||||
sum = sum + probabilities[i];
|
||||
if (sum > r) return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer from the specified discrete distribution.
|
||||
*
|
||||
* @param frequencies the frequency of occurrence of each integer
|
||||
* @return a random integer from a discrete distribution:
|
||||
* {@code i} with probability proportional to {@code frequencies[i]}
|
||||
* @throws IllegalArgumentException if {@code frequencies} is {@code null}
|
||||
* @throws IllegalArgumentException if all array entries are {@code 0}
|
||||
* @throws IllegalArgumentException if {@code frequencies[i]} is negative for any index {@code i}
|
||||
* @throws IllegalArgumentException if sum of frequencies exceeds {@code Integer.MAX_VALUE} (2<sup>31</sup> - 1)
|
||||
*/
|
||||
public static int discrete(int[] frequencies) {
|
||||
if (frequencies == null) throw new IllegalArgumentException("argument array must not be null");
|
||||
long sum = 0;
|
||||
for (int i = 0; i < frequencies.length; i++) {
|
||||
if (frequencies[i] < 0)
|
||||
throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + frequencies[i]);
|
||||
sum += frequencies[i];
|
||||
}
|
||||
if (sum == 0)
|
||||
throw new IllegalArgumentException("at least one array entry must be positive");
|
||||
if (sum >= Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("sum of frequencies overflows an int");
|
||||
|
||||
// pick index i with probability proportional to frequency
|
||||
double r = uniformInt((int) sum);
|
||||
sum = 0;
|
||||
for (int i = 0; i < frequencies.length; i++) {
|
||||
sum += frequencies[i];
|
||||
if (sum > r) return i;
|
||||
}
|
||||
|
||||
// can't reach here
|
||||
assert false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from an exponential distribution
|
||||
* with rate λ.
|
||||
*
|
||||
* @param lambda the rate of the exponential distribution
|
||||
* @return a random real number from an exponential distribution with
|
||||
* rate {@code lambda}
|
||||
* @throws IllegalArgumentException unless {@code lambda > 0.0}
|
||||
*/
|
||||
public static double exponential(double lambda) {
|
||||
if (!(lambda > 0.0))
|
||||
throw new IllegalArgumentException("lambda must be positive: " + lambda);
|
||||
return -Math.log(1 - uniformDouble()) / lambda;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random real number from an exponential distribution
|
||||
* with rate λ.
|
||||
*
|
||||
* @param lambda the rate of the exponential distribution
|
||||
* @return a random real number from an exponential distribution with
|
||||
* rate {@code lambda}
|
||||
* @throws IllegalArgumentException unless {@code lambda > 0.0}
|
||||
* @deprecated Replaced by {@link #exponential(double)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static double exp(double lambda) {
|
||||
return exponential(lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified array in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
*/
|
||||
public static void shuffle(Object[] a) {
|
||||
validateNotNull(a);
|
||||
int n = a.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int r = i + uniformInt(n-i); // between i and n-1
|
||||
Object temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified array in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
*/
|
||||
public static void shuffle(double[] a) {
|
||||
validateNotNull(a);
|
||||
int n = a.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int r = i + uniformInt(n-i); // between i and n-1
|
||||
double temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified array in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
*/
|
||||
public static void shuffle(int[] a) {
|
||||
validateNotNull(a);
|
||||
int n = a.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int r = i + uniformInt(n-i); // between i and n-1
|
||||
int temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified array in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
*/
|
||||
public static void shuffle(char[] a) {
|
||||
validateNotNull(a);
|
||||
int n = a.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int r = i + uniformInt(n-i); // between i and n-1
|
||||
char temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified subarray in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @param lo the left endpoint (inclusive)
|
||||
* @param hi the right endpoint (exclusive)
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
|
||||
*
|
||||
*/
|
||||
public static void shuffle(Object[] a, int lo, int hi) {
|
||||
validateNotNull(a);
|
||||
validateSubarrayIndices(lo, hi, a.length);
|
||||
|
||||
for (int i = lo; i < hi; i++) {
|
||||
int r = i + uniformInt(hi-i); // between i and hi-1
|
||||
Object temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified subarray in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @param lo the left endpoint (inclusive)
|
||||
* @param hi the right endpoint (exclusive)
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
|
||||
*/
|
||||
public static void shuffle(double[] a, int lo, int hi) {
|
||||
validateNotNull(a);
|
||||
validateSubarrayIndices(lo, hi, a.length);
|
||||
|
||||
for (int i = lo; i < hi; i++) {
|
||||
int r = i + uniformInt(hi-i); // between i and hi-1
|
||||
double temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rearranges the elements of the specified subarray in uniformly random order.
|
||||
*
|
||||
* @param a the array to shuffle
|
||||
* @param lo the left endpoint (inclusive)
|
||||
* @param hi the right endpoint (exclusive)
|
||||
* @throws IllegalArgumentException if {@code a} is {@code null}
|
||||
* @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)}
|
||||
*/
|
||||
public static void shuffle(int[] a, int lo, int hi) {
|
||||
validateNotNull(a);
|
||||
validateSubarrayIndices(lo, hi, a.length);
|
||||
|
||||
for (int i = lo; i < hi; i++) {
|
||||
int r = i + uniformInt(hi-i); // between i and hi-1
|
||||
int temp = a[i];
|
||||
a[i] = a[r];
|
||||
a[r] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a uniformly random permutation of <em>n</em> elements.
|
||||
*
|
||||
* @param n number of elements
|
||||
* @throws IllegalArgumentException if {@code n} is negative
|
||||
* @return an array of length {@code n} that is a uniformly random permutation
|
||||
* of {@code 0}, {@code 1}, ..., {@code n-1}
|
||||
*/
|
||||
public static int[] permutation(int n) {
|
||||
if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n);
|
||||
int[] perm = new int[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
perm[i] = i;
|
||||
shuffle(perm);
|
||||
return perm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a uniformly random permutation of <em>k</em> of <em>n</em> elements.
|
||||
*
|
||||
* @param n number of elements
|
||||
* @param k number of elements to select
|
||||
* @throws IllegalArgumentException if {@code n} is negative
|
||||
* @throws IllegalArgumentException unless {@code 0 <= k <= n}
|
||||
* @return an array of length {@code k} that is a uniformly random permutation
|
||||
* of {@code k} of the elements from {@code 0}, {@code 1}, ..., {@code n-1}
|
||||
*/
|
||||
public static int[] permutation(int n, int k) {
|
||||
if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n);
|
||||
if (k < 0 || k > n) throw new IllegalArgumentException("k must be between 0 and n: " + k);
|
||||
int[] perm = new int[k];
|
||||
for (int i = 0; i < k; i++) {
|
||||
int r = uniformInt(i+1); // between 0 and i
|
||||
perm[i] = perm[r];
|
||||
perm[r] = i;
|
||||
}
|
||||
for (int i = k; i < n; i++) {
|
||||
int r = uniformInt(i+1); // between 0 and i
|
||||
if (r < k) perm[r] = i;
|
||||
}
|
||||
return perm;
|
||||
}
|
||||
|
||||
// throw an IllegalArgumentException if x is null
|
||||
// (x can be of type Object[], double[], int[], ...)
|
||||
private static void validateNotNull(Object x) {
|
||||
if (x == null) {
|
||||
throw new IllegalArgumentException("argument must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
// throw an exception unless 0 <= lo <= hi <= length
|
||||
private static void validateSubarrayIndices(int lo, int hi, int length) {
|
||||
if (lo < 0 || hi > length || lo > hi) {
|
||||
throw new IllegalArgumentException("subarray indices out of bounds: [" + lo + ", " + hi + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests the methods in this class.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
int n = Integer.parseInt(args[0]);
|
||||
if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1]));
|
||||
double[] probabilities = { 0.5, 0.3, 0.1, 0.1 };
|
||||
int[] frequencies = { 5, 3, 1, 1 };
|
||||
String[] a = "A B C D E F G".split(" ");
|
||||
|
||||
StdOut.println("seed = " + StdRandom.getSeed());
|
||||
for (int i = 0; i < n; i++) {
|
||||
StdOut.printf("%2d ", uniformInt(100));
|
||||
StdOut.printf("%8.5f ", uniformDouble(10.0, 99.0));
|
||||
StdOut.printf("%5b ", bernoulli(0.5));
|
||||
StdOut.printf("%7.5f ", gaussian(9.0, 0.2));
|
||||
StdOut.printf("%1d ", discrete(probabilities));
|
||||
StdOut.printf("%1d ", discrete(frequencies));
|
||||
StdOut.printf("%11d ", uniformLong(100000000000L));
|
||||
StdRandom.shuffle(a);
|
||||
for (String s : a)
|
||||
StdOut.print(s);
|
||||
StdOut.println();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ public class GamblerPlot {
|
|||
else
|
||||
cash--;
|
||||
|
||||
GamblerPlot.printCash(cash);
|
||||
printCash(cash);
|
||||
}
|
||||
|
||||
boolean won = cash == goal;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ public class RollLoadedDie {
|
|||
public static void main(String[] args) {
|
||||
double rand8 = Math.random() * 8.;
|
||||
// floor returns double. Round gives long for double input, so conversion needed
|
||||
int random = (int)(Math.round(Math.floor(rand8)) + 1);
|
||||
int random = (int)(Math.floor(rand8) + 1);
|
||||
// 1 - 8 to 1 - 6, with 6 receiving the probabilities of 7 - 8
|
||||
// 1 - 5 have their original probabilities, meaning each have 1/8 chance of being selected, while 6 is 3/8
|
||||
random = Math.min(random, 6);
|
||||
System.out.println(random);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,8 @@ the (fixed) probability that the gambler wins each bet. Use your program
|
|||
to try to learn how this probability affects the chance of winning and the
|
||||
expected number of bets. Try a value of $p$ close to $0.5$ (say, $0.48$).
|
||||
|
||||
Small changes of probability affect win % a lot, for example the chance of
|
||||
doubling money from $100$ to $200$ is roughly 50% for $p=0.5$, but falls to
|
||||
less than 5% for $p=0.49$ and 0% below that.
|
||||
|
||||
#embedClass(name: "Gambler")
|
||||
104
week4/Card.java
104
week4/Card.java
|
|
@ -1,21 +1,22 @@
|
|||
public class Card {
|
||||
public static final String CLUBS = "♣";
|
||||
public static final String DIAMONDS = "♦";
|
||||
public static final String HEARTS = "♥";
|
||||
public static final String SPADES = "♠";
|
||||
|
||||
|
||||
public enum Suit {
|
||||
Clubs,
|
||||
Diamonds,
|
||||
Hearts,
|
||||
Spades;
|
||||
|
||||
public static final String CLUBS = "♣";
|
||||
public static final String DIAMONDS = "♦";
|
||||
public static final String HEARTS = "♥";
|
||||
public static final String SPADES = "♠";
|
||||
|
||||
public String sprint() {
|
||||
switch(this) {
|
||||
case Clubs: return Card.CLUBS;
|
||||
case Diamonds: return Card.DIAMONDS;
|
||||
case Hearts: return Card.HEARTS;
|
||||
case Spades: return Card.SPADES;
|
||||
case Clubs: return CLUBS;
|
||||
case Diamonds: return DIAMONDS;
|
||||
case Hearts: return HEARTS;
|
||||
case Spades: return SPADES;
|
||||
}
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
|
@ -29,81 +30,95 @@ public class Card {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
public static Card fromNumbers(int suit, int value) {
|
||||
return new Card(Suit.values()[suit], value);
|
||||
}
|
||||
|
||||
public String sprintValue() {
|
||||
// Print a single character for the value
|
||||
// Only a single character is returned so that we can format
|
||||
// the card output correctly and easily
|
||||
public char sprintValue() {
|
||||
assert this.value > 0 && this.value < 14;
|
||||
if(this.value == 1) {
|
||||
return "A";
|
||||
return 'A';
|
||||
} else if(this.value == 11) {
|
||||
return "J";
|
||||
return 'J';
|
||||
} else if(this.value == 12) {
|
||||
return "Q";
|
||||
return 'Q';
|
||||
} else if(this.value == 13) {
|
||||
return "K";
|
||||
return 'K';
|
||||
} else if(this.value == 10) {
|
||||
return "⒑";
|
||||
// UTF-8 character that looks like a 10
|
||||
// but uses only one character width
|
||||
return '⒑';
|
||||
}
|
||||
return Integer.toString(this.value);
|
||||
// asserted 0 < x < 14, we handled 1, 10-13
|
||||
// the only valid values here are 2-9
|
||||
return Integer.toString(this.value).charAt(0);
|
||||
}
|
||||
|
||||
// Print the card to a string to be later processed (or printed).
|
||||
// Approximates 'normal' card deck look
|
||||
// Numbered cards have their suit symbol repeated based on their value.
|
||||
// Face cards are empty.
|
||||
public String sprintCard() {
|
||||
var output = "";
|
||||
var value = this.sprintValue();
|
||||
var suit = this.suit.sprint();
|
||||
|
||||
output += value;
|
||||
|
||||
// Generate the top (and bottom) of a card
|
||||
// this will show the value of the card on each edge
|
||||
var top = "";
|
||||
top += value;
|
||||
if(this.value > 10) {
|
||||
output += " ";
|
||||
top += " ";
|
||||
} else {
|
||||
output += this.value >= 4 ? suit : " ";
|
||||
output += this.value < 4 && this.value > 1 ? suit : " ";
|
||||
output += this.value >= 4 ? suit : " ";
|
||||
// and for numbered cards, show the suit characters
|
||||
top += this.value >= 4 ? suit : " ";
|
||||
top += this.value < 4 && this.value > 1 ? suit : " ";
|
||||
top += this.value >= 4 ? suit : " ";
|
||||
}
|
||||
output += value;
|
||||
output += "\n";
|
||||
top += value;
|
||||
top += "\n";
|
||||
|
||||
output += top;
|
||||
|
||||
if(this.value > 10) {
|
||||
// face cards get suits on the side, right above and under their values
|
||||
// numbered cards are empty on their sides
|
||||
output += suit + " " + suit + "\n";
|
||||
output += suit + " " + suit + "\n";
|
||||
} else {
|
||||
// normal cards have either 3 or 4 rows of suits in 1-3 columns,
|
||||
// with the middle one sometimes floating.
|
||||
// we have to have a set size and can't have floating characters,
|
||||
// so this is a best effort approximation
|
||||
// instead of using 3 rows we have a gap in the 3rd row
|
||||
output += " ";
|
||||
output += this.value >= 6 ? suit : " ";
|
||||
output += this.value % 2 == 1 || this.value >= 8 ? suit : " ";
|
||||
// odd or 10
|
||||
output += this.value % 2 == 1 || this.value == 10 ? suit : " ";
|
||||
output += this.value >= 6 ? suit : " ";
|
||||
output += " ";
|
||||
output += "\n";
|
||||
|
||||
|
||||
output += " ";
|
||||
output += this.value >= 9 ? suit : " ";
|
||||
output += this.value == 8 || this.value == 10 ? suit : " ";
|
||||
output += this.value >= 9 ? suit : " ";
|
||||
output += this.value >= 8 ? suit : " ";
|
||||
output += this.value == 10 ? suit : " ";
|
||||
output += this.value >= 8 ? suit : " ";
|
||||
output += " ";
|
||||
output += "\n";
|
||||
}
|
||||
|
||||
|
||||
output += value;
|
||||
|
||||
if(this.value > 10) {
|
||||
output += " ";
|
||||
} else {
|
||||
output += this.value >= 4 ? suit : " ";
|
||||
output += this.value < 4 && this.value > 1 ? suit : " ";
|
||||
output += this.value >= 4 ? suit : " ";
|
||||
}
|
||||
output += value;
|
||||
output += "\n";
|
||||
output += top;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Shows cards next to each other (left to right)
|
||||
// assumes that sprintCard returns the same width for each card (and each row of a card)
|
||||
public static String sprintCards(Card[] cards) {
|
||||
String[] output = { "", "", "", "" };
|
||||
|
||||
// split each card into it's 4 rows
|
||||
// save the row into relevant output
|
||||
for(var i = 0; i < cards.length; i++) {
|
||||
var cardstr = cards[i].sprintCard().split("\n");
|
||||
for(var x = 0; x < cardstr.length; x++) {
|
||||
|
|
@ -111,6 +126,7 @@ public class Card {
|
|||
}
|
||||
}
|
||||
|
||||
// and join the rows together with a newline
|
||||
var outputstr = "";
|
||||
for(var i = 0; i < output.length; i++) {
|
||||
outputstr += output[i] + "\n";
|
||||
|
|
|
|||
|
|
@ -3,19 +3,25 @@ import java.util.Random;
|
|||
public class Deal {
|
||||
public static void main(String[] args) {
|
||||
int handCount = Integer.parseInt(args[0]);
|
||||
// We have 52 cards, each hand is 5 cards
|
||||
if(handCount > 10) {
|
||||
System.err.println("Too many hands! Maximum is 10.\njava Deal [hands]");
|
||||
}
|
||||
|
||||
// Generate the deck
|
||||
Card[] deck = new Card[52];
|
||||
for(var i = 0; i < 52; i++) {
|
||||
// 13 cards for each suit, take advantage of int division
|
||||
var value = (i % 13) + 1;
|
||||
var suit = i / 13;
|
||||
deck[i] = Card.fromNumbers(suit, value);
|
||||
deck[i] = new Card(Card.Suit.values()[suit], value);
|
||||
}
|
||||
|
||||
// Randomly shuffle the deck
|
||||
Random random = new Random();
|
||||
for(var i = 0; i < deck.length; i++) {
|
||||
// swap each item with a random item in the array
|
||||
// isn't truly random, but we're not using crypto random anyway
|
||||
var second = random.nextInt(deck.length);
|
||||
var a = deck[i];
|
||||
deck[i] = deck[second];
|
||||
|
|
@ -24,7 +30,15 @@ public class Deal {
|
|||
|
||||
for(var handNumber = 0; handNumber < handCount; handNumber++) {
|
||||
var offset = handNumber * 5;
|
||||
Card[] hand = { deck[offset], deck[offset+1], deck[offset+2], deck[offset+3], deck[offset+4] };
|
||||
// since the deck is shuffled, we just take the next 5 cards from the array
|
||||
// java could use an array slice so that we didn't need to copy all the objects..
|
||||
Card[] hand = {
|
||||
deck[offset],
|
||||
deck[offset+1],
|
||||
deck[offset+2],
|
||||
deck[offset+3],
|
||||
deck[offset+4]
|
||||
};
|
||||
System.out.println(Card.sprintCards(hand));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
week4/Transpose.java
Normal file
3
week4/Transpose.java
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
public class Transpose {
|
||||
|
||||
}
|
||||
|
|
@ -23,3 +23,18 @@ For the example spreadsheet array in the text, you code would print the followin
|
|||
85 57 77 32 34 46 59 66 71 29
|
||||
98 78 76 11 22 54 88 89 24 38
|
||||
```
|
||||
|
||||
Input:
|
||||
|
||||
```
|
||||
99 85 98
|
||||
98 57 78
|
||||
92 77 76
|
||||
94 32 11
|
||||
99 34 22
|
||||
90 46 54
|
||||
76 59 88
|
||||
92 66 89
|
||||
97 71 24
|
||||
89 29 38
|
||||
```
|
||||
|
|
|
|||
10
week4/tests/Transpose/input1.txt
Normal file
10
week4/tests/Transpose/input1.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
99 85 98
|
||||
98 57 78
|
||||
92 77 76
|
||||
94 32 11
|
||||
99 34 22
|
||||
90 46 54
|
||||
76 59 88
|
||||
92 66 89
|
||||
97 71 24
|
||||
89 29 38
|
||||
3
week4/tests/Transpose/output1.txt
Normal file
3
week4/tests/Transpose/output1.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
99 98 92 94 99 90 76 92 97 89
|
||||
85 57 77 32 34 46 59 66 71 29
|
||||
98 78 76 11 22 54 88 89 24 38
|
||||
Loading…
Reference in a new issue