Skip to content

Challenge Groups

A ChallengeGroup is a named collection of programming challenges within a language. Groups correspond to a package or directory of source files and appear as sections on the language page (e.g., "Warmup-1", "String-2").

Creating Groups

Groups are created inside a language block using the group() function:

val javaIncludeFiles =
  readingBatContent {
    repo = FileSystemSource("./")

    java {
      group("Warmup-1") {
        packageName = "warmup1"
        description = "Simple warmup problems"

        // Include all Java files from the warmup1 package
        includeFiles = "*.java"
      }
    }
  }

Including Files

Java: includeFiles

For Java challenges, use includeFiles with a glob pattern. The return type is inferred from the Java source code:

val javaIncludeFiles =
  readingBatContent {
    repo = FileSystemSource("./")

    java {
      group("Warmup-1") {
        packageName = "warmup1"
        description = "Simple warmup problems"

        // Include all Java files from the warmup1 package
        includeFiles = "*.java"
      }
    }
  }

Python: includeFilesWithType

Python challenges require the includeFilesWithType property with the returns infix function:

val pythonIncludeFiles =
  readingBatContent {
    repo = FileSystemSource("./")

    python {
      group("Warmup-1") {
        packageName = "warmup1"
        description = "Simple Python warmup problems"

        // Python requires an explicit return type
        includeFilesWithType = "*.py" returns BooleanType
      }
    }
  }

Kotlin: includeFilesWithType

Kotlin follows the same pattern as Python:

val kotlinIncludeFiles =
  readingBatContent {
    repo = FileSystemSource("./")

    kotlin {
      group("Warmup-1") {
        packageName = "warmup1"
        description = "Simple Kotlin warmup problems"

        // Kotlin also requires an explicit return type
        includeFilesWithType = "*.kt" returns StringType
      }
    }
  }

Multiple Include Patterns

You can use multiple includeFilesWithType assignments to include files with different return types in the same group:

val multipleIncludePatterns =
  readingBatContent {
    repo = FileSystemSource("./")

    python {
      group("Mixed-1") {
        packageName = "mixed1"
        description = "Problems with different return types"

        // Multiple includeFilesWithType lines for different patterns
        includeFilesWithType = "bool_*.py" returns BooleanType
        includeFilesWithType = "int_*.py" returns IntType
        includeFilesWithType = "str_*.py" returns StringType
      }
    }
  }

Individual Challenges

Instead of (or in addition to) bulk file inclusion, you can add challenges one at a time:

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 }
      }
    }
  }

Descriptions

Both groups and individual challenges support Markdown descriptions:

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"
        }
      }
    }
  }

Source code descriptions

Challenges can also derive descriptions from special @desc comments in their source files. A // @desc Return true when... comment at the top of a Java file will be used as the description unless one is explicitly set in the DSL.

Group Properties

Property Type Default Description
packageName String "" Package path for locating source files
description String "" Markdown description shown at the top of the group page
includeFiles String -- Glob pattern for Java file inclusion
includeFilesWithType PatternReturnType -- Pattern + return type for Python/Kotlin

Multiple Return Types in One Group

A single group can contain challenges with different return types when added individually:

val multipleReturnTypes =
  readingBatContent {
    repo = FileSystemSource("./")

    kotlin {
      group("Mixed-Types") {
        packageName = "mixed"

        challenge("isEven") { returnType = BooleanType }
        challenge("doubleIt") { returnType = IntType }
        challenge("greeting") { returnType = StringType }
        challenge("reverseArray") { returnType = IntArrayType }
        challenge("splitWords") { returnType = StringArrayType }
      }
    }
  }