Skip to main content

Problem spec

ProblemSpec must inherit tcframe::BaseProblemSpec:

class ProblemSpec : public BaseProblemSpec {};

Except for private helper functions, every member of ProblemSpec listed below must be protected.


Input/output variables

Defined as instance member variables of ProblemSpec, which will be referenced in other methods of ProblemSpec and TestSpec.

There are three supported types of variables:

Scalar

Variables of built-in integral types (int, long long, char, etc.), built-in floating-point types (float, double), and std::string.

Vector

std::vector<T>, where T is a scalar type as defined above. Arrays (T[]) are not supported.

Matrix

std::vector<std::vector<T>>, where T is a scalar type as defined above. 2D arrays (T[][]) are not supported.

Example

class ProblemSpec : public BaseProblemSpec {
protected:
int A, B;
vector<int> parent;
vector<vector<int>> values;
};

Input/output formats

InputFormat()

virtual void InputFormat() = 0;

Defines the input format. It is mandatory.


OutputFormat(), OutputFormatX()

virtual void OutputFormat() {}

virtual void OutputFormat1() {}
virtual void OutputFormat2() {}
// ...
virtual void OutputFormat5() {}

Defines the possible output format(s). If there is only one output format, only OutputFormat() can be specified, otherwise multiple OutputFormatX() should be specified.


Definitions

The following macros are exposed to define input/output formats:

EMPTY_LINE()

#define EMPTY_LINE()  /* see below */

Defines an empty line.


RAW_LINE()

#define RAW_LINE(var)  /* see below */

Defines a line of raw string (which may contain whitespaces). The variable must be a std::string.

Example

UsageVariableFormat
void InputFormat() {
RAW_LINE(S);
}

S = "Hello, world!"

Hello, world!

RAW_LINES()

#define RAW_LINES(var)  /* see below */

Defines multiple lines, each consisting of raw string.

Usage:

  • RAW_LINES(<var>);
  • RAW_LINES(<var>) % SIZE(<number of elements>);

The variable must be a vector of std::string. If the size is not given, then this must be the last segment in the I/O format.

Example

UsageVariablesFormat
void InputFormat() {
RAW_LINES(X) % SIZE(2);
RAW_LINES(Y);
}
  • X = {
    • "Hello, world!",
    • "Happy new year."}
  • Y = {
    • "lorem",
    • "ipsum",
    • "dolor sit amet"}
Hello, world!
Happy new year.
lorem
ipsum
dolor sit amet

LINE()

#define LINE(arg, ...)  /* see below */

Defines a single line containing space-separated scalar or vector variables. In case of vector variables, the elements are separated by spaces as well.

Usage:

  • LINE(<arg1>, <arg2>, ...);

where each arg is one of:

  • <scalar variable name>.
  • <vector variable name> % SIZE(<number of elements>). The number of elements can be a constant or a scalar variable.
  • <vector variable name>. Here, the number of elements is unspecified. This kind of element must occur last in a line segment, if any. Elements will be considered until new line is found.

Example

UsageVariablesFormat
void InputFormat() {
LINE(N);
LINE(A % SIZE(3), B);
LINE(M, C % SIZE(M));
}
  • N = 2
  • A = {1, 2, 3}
  • B = {100, 200, 300, 400}
  • M = 2
  • C = {7, 8}
2
1 2 3 100 200 300 400
2 7 8

LINES()

#define LINES(var, ...)  /* see below */

Defines multiple lines, each consisting of space-separated elements of given vector/matrix variables.

Usage:

  • LINES(<var1>, <var2>, ...);
  • LINES(<var1>, <var2>, ...) % SIZE(<number of elements>);

where each variable is a vector or matrix.

If the size is not given, this must be the last segment in the I/O format.

If a matrix variable is given, it must occur as the last argument, and the number of rows must match with the number of elements of the other vector variables (if any). It is not required that each row of the matrix consists of the same number of columns.

Examples

UsageVariablesFormat
void InputFormat() {
LINES(V) % SIZE(2);
LINES(X, Y) % SIZE(N);
LINES(Z);
}
  • V = {1, 2}
  • X = {100, 110, 120}
  • Y = {200, 210, 220}
  • N = 3
  • Z = {1, 2, 3, 4}
1
2
100 200
110 210
120 220
1
2
3
4
void InputFormat() {
LINES(op, data) % SIZE(2);
}
  • op = {"UPDATE", "QUERY"}
  • data = { {3, 5}, {7} }
UPDATE 3 5
QUERY 7

GRID()

#define GRID(var)  /* see below */

Defines a grid consisting elements of a given matrix variable. If the given matrix variable is of type char, the elements in each row is not space-separated, otherwise they are space-separated.

Usage:

  • GRID(<var>) % SIZE(<number of rows>, <number of columns>);

Example

UsageVariablesFormat
void InputFormat() {
GRID(G) % SIZE(2, 2);
GRID(H) % SIZE(R, C);
}
  • R = 2
  • C = 3
  • G = { {'a', 'b'}, {'c', 'd'} }
  • H = { {1, 2, 3}, {4, 5, 6} }
ab
cd
1 2 3
4 5 6

BeforeOutputFormat()

virtual void BeforeOutputFormat() {}

Executed right before the produced output is validated against the output format(s). See BeforeOutputFormat() for more details.


Constraints and subtasks

MultipleTestCasesConstraints()

virtual void MultipleTestCasesConstraints() {}

Defines the constraints to be imposed to the multiple test cases counter.


Constraints()

virtual void Constraints() {}

Defines the constraints to be imposed to the input/output variables.


SubtaskX()

virtual void Subtask1() {}
virtual void Subtask2() {}
// ...
virtual void Subtask25() {}

Defines the constraints to be imposed to the input/output variables for each subtask (up to 25).


Definitions

CONS()

#define CONS(predicate)  /* see below */

Defines a constraint. predicate is a boolean expression, whose value must be completely determined by the values of the input variables (only).

Points()

void Points(double points);

Sets the points assigned to a subtask. If not specified, the default is 0. Only available in SubtaskX()s.

Examples

void MultipleTestCasesConstraints() {
CONS(1 <= T && T <= 20);
}
void Constraints() {
CONS(A <= B && B <= 1000);
CONS(graphDoesNotHaveCycles());
}
void Subtask1() {
Points(70);

CONS(A <= B && B <= 1000);
CONS(graphDoesNotHaveCycles());
}

Multiple test cases config

MultipleTestCasesConfig()

virtual void MultipleTestCasesConfig() {}

Defines the config for multiple test cases per file problems. The following methods are exposed:

Counter()

void Counter(int& var);

Sets the input variable that will hold the number of test cases in a file.

OutputPrefix()

void OutputPrefix(std::string prefix);

Sets the prefix to be prepended to the output of each test case. It can include %d, which will be replaced by the actual test case number (1-based).

Example

void MultipleTestCasesConfig() {
Counter(T);
OutputPrefix("Case #%d: ");
}

Problem style config

StyleConfig()

virtual void StyleConfig() {}

Defines the options to enable for problem styles. The following methods are exposed:


NoOutput()

void NoOutput();

Declares that the problem does not need test case output files.

CustomScorer()

void CustomScorer();

Declares that the problem needs a custom scorer.

InteractiveEvaluator()

void InteractiveEvaluator();

Declares that the problem uses interactive evaluator.

Example

void StyleConfig() {
CustomScorer();
NoOutput();
}

Grading config

GradingConfig()

virtual void GradingConfig() {}

Defines the config for local grading. The following methods are exposed:


TimeLimit()

void TimeLimit(int timeLimitInSeconds);

Sets the time limit in seconds. If not specified, the default value is 2 seconds.

MemoryLimit()

void MemoryLimit(int memoryLimitInMegabytes);

Sets the memory limit in MB. If not specified, the default value is 64 MB.