Challenges
A Challenge represents a single programming problem. It corresponds to a source file
containing a function and its test invocations. When loaded, the source code is parsed
to extract the function body, test cases, and correct answers.
Challenge Types
There are three language-specific challenge subclasses:
| Type | Language | Return Type |
|---|---|---|
JavaChallenge |
Java | Inferred from source |
PythonChallenge |
Python | Must be set explicitly |
KotlinChallenge |
Kotlin | Must be set explicitly |
Defining Challenges
Basic Definition
The simplest way to define a challenge:
val individualChallenges =
readingBatContent {
repo = FileSystemSource("./")
java {
group("Warmup-1") {
packageName = "warmup1"
// Add challenges one at a time
challenge("SleepIn")
challenge("MonkeyTrouble")
challenge("SumDouble")
}
}
python {
group("Warmup-1") {
packageName = "warmup1"
// Python challenges need a return type
challenge("sleep_in") { returnType = BooleanType }
challenge("monkey_trouble") { returnType = BooleanType }
challenge("sum_double") { returnType = IntType }
}
}
kotlin {
group("Warmup-1") {
packageName = "warmup1"
// Kotlin challenges also need a return type
challenge("sleepIn") { returnType = BooleanType }
challenge("monkeyTrouble") { returnType = BooleanType }
challenge("sumDouble") { returnType = IntType }
}
}
}
With Descriptions and Metadata
Challenges can include descriptions and CodingBat equivalents:
val challengeWithDescription =
readingBatContent {
repo = FileSystemSource("./")
java {
group("String-1") {
packageName = "string1"
description = "Basic **string** problems using `charAt()` and `substring()`"
challenge("HelloName") {
description = "Return a greeting with the given name"
codingBatEquiv = "p141943"
}
challenge("MakeAbba") {
description = "Combine two strings in *abba* pattern"
codingBatEquiv = "p161056"
}
}
}
}
Custom File Names
By default, the file name is derived from the challenge name plus the language suffix. You can override this:
val customFileNameExample =
readingBatContent {
repo = FileSystemSource("./")
java {
group("Warmup-1") {
packageName = "warmup1"
// Default: fileName is derived from challenge name + language suffix
challenge("SleepIn") // looks for SleepIn.java
// Override the file name explicitly
challenge("MyChallenge") {
fileName = "CustomFileName.java"
}
}
}
kotlin {
group("Warmup-1") {
packageName = "warmup1"
challenge("sleepIn") { returnType = BooleanType } // looks for sleepIn.kt
challenge("customName") {
returnType = StringType
fileName = "MyCustomChallenge.kt"
}
}
}
}
CodingBat Equivalents
Link challenges to their CodingBat counterparts:
val codingBatEquivExample =
readingBatContent {
repo = FileSystemSource("./")
java {
group("Warmup-1") {
packageName = "warmup1"
challenge("SleepIn") {
codingBatEquiv = "p187868"
description = "Return true when you can sleep in"
}
challenge("Diff21") {
codingBatEquiv = "p116624"
description = "Return the absolute difference from 21"
}
}
}
}
Source File Convention
Challenge source files follow a specific convention where the main() method contains
println() (or print() for Python) calls that serve as test invocations:
The framework:
- Extracts the function body (displayed to the user)
- Extracts the
printlncalls as test invocations - Evaluates the code to compute correct answers
- Compares user answers against the computed results
Source-Based Descriptions
Add @desc comments at the top of source files to provide descriptions without
modifying the DSL:
Note
Descriptions set explicitly in the DSL take precedence over @desc comments
in source files.
Challenge Properties
| Property | Type | Default | Description |
|---|---|---|---|
fileName |
String |
"$challengeName.$suffix" |
Source file name |
description |
String |
"" |
Markdown description (or from @desc comments) |
codingBatEquiv |
String |
"" |
CodingBat problem identifier |
returnType |
ReturnType |
Required for Python/Kotlin | Expected return type |
Challenge Identification
Each challenge is uniquely identified by an MD5 hash computed from its language name, group name, and challenge name. This hash is used for tracking user progress and answer history.