Skip to content

Commit

Permalink
Add concept exercise: captains-log
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderploegsma committed Nov 23, 2023
1 parent 017ac09 commit 41ca0a6
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 0 deletions.
13 changes: 13 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
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);
}
}
23 changes: 23 additions & 0 deletions exercises/concept/captains-log/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
plugins {
id "java"
}

repositories {
mavenCentral()
}

dependencies {
testImplementation platform("org.junit:junit-bom:5.10.0")
testImplementation "org.junit.jupiter:junit-jupiter"
testImplementation "org.assertj:assertj-core:3.15.0"
}

test {
useJUnitPlatform()

testLogging {
exceptionFormat = "full"
showStandardStreams = true
events = ["passed", "failed", "skipped"]
}
}
24 changes: 24 additions & 0 deletions exercises/concept/captains-log/src/main/java/CaptainsLog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
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 Random random;

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

char randomPlanetClass() {
throw new UnsupportedOperationException("Please implement the CaptainsLog.randomPlanetClass() method");
}

String randomShipRegistryNumber() {
throw new UnsupportedOperationException("Please implement the CaptainsLog.randomShipRegistryNumber() method");
}

double randomStardate() {
throw new UnsupportedOperationException("Please implement the CaptainsLog.randomStardate() method");
}
}
Loading

0 comments on commit 41ca0a6

Please sign in to comment.