Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add concept randomness and concept exercise captains-log #2582

Merged
merged 5 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions concepts/randomness/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "Java includes utilities to generate random numbers.",
"authors": ["sanderploegsma"],
"contributors": []
}
58 changes: 58 additions & 0 deletions concepts/randomness/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# About

## Generating random values

There are multiple ways to generate random values in Java.

### Using `Random`

The [`java.util.Random`][java-util-random-docs] class provides several methods to generate pseudo-random values.

```java
Random random = new Random();

random.next(8); // Generates a random int with the given number of bits, in this case 8

random.nextInt(); // Generates a random int in the range Integer.MIN_VALUE through Integer.MAX_VALUE
random.nextInt(10); // Generates a random int in the range 0 to 10

random.nextFloat(); // Generates a random float in the range 0.0 to 1.0
random.nextDouble(); // Generates a random double in the range 0.0 to 1.0

random.nextBoolean(); // Generates a random boolean value
random.nextLong(); // Generates a random long value
```

Next to its default constructor, the `Random` class also has another constructor where a custom seed can be provided.
If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers.

### Using `Math.random()`

The [`Math.random()`][math-random-docs] method is a utility method to generate a random `Double` in the range from `0.0` to `1.0`.

### Using `ThreadLocalRandom`

The [`java.util.concurrent.ThreadLocalRandom`][thread-local-random-docs] class is an alternative for `java.util.Random` and is designed to be thread-safe.
This class has some extra utility methods to generate values that take both a lower and upper bound, making it a bit easier to work with.

```java
ThreadLocalRandom random = ThreadLocalRandom.current();

random.nextInt(10, 20); // Generates a random int in the range 10 to 20
random.nextLong(10, 20); // Generates a random long in the range 10 to 20

random.nextFloat(10.0, 20.0); // Generates a random float in the range 10 to 20
random.nextDouble(10.0, 20.0); // Generates a random double in the range 10 to 20
```

## Security

Random values are often used to generate sensitive values like passwords.
However, all of the methods to generate random values as described above are _not_ considered cryptographically secure.

In order to generate cryptographically strong random numbers, use the [`java.security.SecureRandom`][secure-random-docs] class.

[java-util-random-docs]: https://docs.oracle.com/javase/8/docs/api/java/util/Random.html
[math-random-docs]: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--
[thread-local-random-docs]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadLocalRandom.html
[secure-random-docs]: https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html
57 changes: 57 additions & 0 deletions concepts/randomness/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Introduction

An instance of the `java.util.Random` class can be used to generate random numbers in Java.

## Random integers

A random integer can be generated using the `nextInt()` method.
This will generate a value in the range from `Integer.MIN_VALUE` to `Integer.MAX_VALUE`.

```java
Random random = new Random();

random.nextInt();
// => -1169335537
```

To limit the range of generated values, use `nextInt(int)`.
This will generate a value in the range from `0` (inclusive) to the given upper bound (exclusive).

For example, this will generate a random number from `0` through `9`.

```java
Random random = new Random();

random.nextInt(10);
// => 6
```

And this will generate a random number from `10` through `19`.

```java
Random random = new Random();

10 + random.nextInt(10);
// => 11
```

## Random doubles

A random double can be generated using the `nextDouble()` method.
This will generate a value in the range from `0.0` to `1.0`.

```java
Random random = new Random();

random.nextDouble();
// => 0.19250004204021398
```

And this will generate a random number from `100.0` to `200.0`.

```java
Random random = new Random();

100.0 + 100.0 * random.nextDouble();
// => 111.31849856260328
```
14 changes: 14 additions & 0 deletions concepts/randomness/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"url": "https://docs.oracle.com/javase/8/docs/api/java/util/Random.html",
"description": "java.util.Random API documentation"
},
{
"url": "https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--",
"description": "Math.random() documentation"
},
{
"url": "https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html",
"description": "java.security.SecureRandom API documentation"
}
]
18 changes: 18 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,19 @@
"switch-statement",
"constructors"
]
},
{
"slug": "captains-log",
"name": "Captain's Log",
"uuid": "1ade8233-7a73-4fd9-afe2-f80d7cca14ab",
"concepts": [
"randomness"
],
"prerequisites": [
"arrays",
"numbers",
"strings"
]
}
],
"practice": [
Expand Down Expand Up @@ -2093,6 +2106,11 @@
"slug": "numbers",
"name": "Numbers"
},
{
"uuid": "07674a94-5f10-4b99-8f18-36c841e4aff8",
"slug": "randomness",
"name": "Randomness"
},
{
"uuid": "8a468b14-724a-4036-8edb-d19a02809840",
"slug": "strings",
Expand Down
14 changes: 14 additions & 0 deletions exercises/concept/captains-log/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Hints

## 1. Generate a random planet

- Java does not provide a function to choose an element from a collection at random.
- Remember that you can retrieve an element from an array by its index, which is an integer.

## 2. Generate a random starship registry number

- The `java.util.Random` class provides a method to generate a random `int` between 0 and a given maximum.

## 3. Generate a random stardate

- The `java.util.Random` class method to generate a random `double` always returns a number between `0.0` and `1.0`.
59 changes: 59 additions & 0 deletions exercises/concept/captains-log/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Instructions

Mary is a big fan of the TV series _Star Trek: The Next Generation_.
She often plays pen-and-paper role playing games, where she and her friends pretend to be the crew of the _Starship Enterprise_.
Mary's character is Captain Picard, which means she has to keep the captain's log.
She loves the creative part of the game, but doesn't like to generate random data on the spot.

Help Mary by creating random generators for data commonly appearing in the captain's log.

~~~~exercism/note
The starter implementation of this exercise takes a `java.util.Random` instance as constructor argument.
This allows the exercise's tests to pass an instance with a predefined seed, which makes the test results predictable.

Therefore, you are expected to use provided the `java.util.Random` instance in your implementation.
~~~~

## 1. Generate a random planet

The _Starship Enterprise_ encounters many planets in its travels.
Planets in the Star Trek universe are split into categories based on their properties.
For example, Earth is a class `M` planet.
All possible planetary classes are: `D`, `H`, `J`, `K`, `L`, `M`, `N`, `R`, `T`, and `Y`.

Implement the `randomPlanetClass()` method.
It should return one of the planetary classes at random.

```java
captainsLog.randomPlanetClass();
// => "K"
```

## 2. Generate a random starship registry number

Enterprise (registry number `NCC-1701`) is not the only starship flying around!
When it rendezvous with another starship, Mary needs to log the registry number of that starship.

Registry numbers start with the prefix "NCC-" and then use a number from `1000` to `9999` (inclusive).

Implement the `randomShipRegistryNumber()` method that returns a random starship registry number.

```java
captainsLog.randomShipRegistryNumber();
// => "NCC-1947"
```

## 3. Generate a random stardate

What's the use of a log if it doesn't include dates?

A stardate is a floating point number.
The adventures of the _Starship Enterprise_ from the first season of _The Next Generation_ take place between the stardates `41000.0` and `42000.0`.
The "4" stands for the 24th century, the "1" for the first season.

Implement the `randomStardate()` method that returns a floating point number between `41000.0` (inclusive) and `42000.0` (exclusive).

```java
captainsLog.randomStardate();
// => 41458.15721310934
```
59 changes: 59 additions & 0 deletions exercises/concept/captains-log/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Introduction

## Randomness

An instance of the `java.util.Random` class can be used to generate random numbers in Java.

### Random integers

A random integer can be generated using the `nextInt()` method.
This will generate a value in the range from `Integer.MIN_VALUE` to `Integer.MAX_VALUE`.

```java
Random random = new Random();

random.nextInt();
// => -1169335537
```

To limit the range of generated values, use `nextInt(int)`.
This will generate a value in the range from `0` (inclusive) to the given upper bound (exclusive).

For example, this will generate a random number from `0` through `9`.

```java
Random random = new Random();

random.nextInt(10);
// => 6
```

And this will generate a random number from `10` through `19`.

```java
Random random = new Random();

10 + random.nextInt(10);
// => 11
```

### Random doubles

A random double can be generated using the `nextDouble()` method.
This will generate a value in the range from `0.0` to `1.0`.

```java
Random random = new Random();

random.nextDouble();
// => 0.19250004204021398
```

And this will generate a random number from `100.0` to `200.0`.

```java
Random random = new Random();

100.0 + 100.0 * random.nextDouble();
// => 111.31849856260328
```
5 changes: 5 additions & 0 deletions exercises/concept/captains-log/.docs/introduction.md.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Introduction

## Randomness

%{concept:randomness}
23 changes: 23 additions & 0 deletions exercises/concept/captains-log/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"sanderploegsma"
],
"files": {
"solution": [
"src/main/java/CaptainsLog.java"
],
"test": [
"src/test/java/CaptainsLogTest.java"
],
"exemplar": [
".meta/src/reference/java/CaptainsLog.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"elixir/captains-log"
],
"blurb": "Learn about randomness by helping Mary generate stardates and starship registry numbers for her Star Trek themed pen-and-paper role playing sessions."
}
21 changes: 21 additions & 0 deletions exercises/concept/captains-log/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Design

## Learning objectives

- Know how to generate a random `Integer`.
- Know how to generate a random `Double`.
- Know how to select a random element from a collection.

## Out of scope

- `java.util.SecureRandom`.

## Concepts

- `randomness`

## Prerequisites

- `strings`: know how to use string formatting.
- `numbers`: know how to apply basic mathematical operators.
- `arrays`: know how to retrieve array elements by their index.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import java.util.Random;

class CaptainsLog {

private static final char[] PLANET_CLASSES = new char[]{'D', 'H', 'J', 'K', 'L', 'M', 'N', 'R', 'T', 'Y'};

private final Random random;

CaptainsLog(Random random) {
this.random = random;
}

char randomPlanetClass() {
var index = random.nextInt(PLANET_CLASSES.length);
return PLANET_CLASSES[index];
}

String randomShipRegistryNumber() {
var start = 1000;
var end = 9999;
return String.format("NCC-%d", start + random.nextInt(end - start));
}

double randomStardate() {
var start = 41000.0;
var end = 42000.0;
return start + random.nextDouble() * (end - start);
}
}
Loading