Skip to content

Commit b0cab48

Browse files
committed
add example problems
1 parent d816020 commit b0cab48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1186
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ Running any of them without any command-line options gives
1616
documentation on what parameters they accept.
1717

1818

19+
## Example Problems
20+
21+
A few examples of problem packages can be found in [examples](examples).
22+
23+
1924
## Installing and using problemtools
2025

2126
There are two recommended ways of installing and running problemtools.

examples/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Example problem packages
2+
3+
These are a few examples of complete problems.
4+
5+
## different
6+
7+
This is a simple basic problem that asks for a program that computes
8+
the difference between integers. It should be a good starting point
9+
if you want to learn how the problem format works.
10+
11+
## guess
12+
13+
This is a simple example of an *interactive* problem, where there is
14+
no fixed input to process, but the solution instead communicates back
15+
and forth with a validator program.
16+
17+
## hello
18+
19+
This is a problem that just asks for a program that prints `Hello
20+
World!`. It is a somewhat atypical problem since it does not have any
21+
input. This problem also illustrates having problem statements in
22+
more than one language.

examples/different/data/sample/1.ans

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2
2+
71293781685339
3+
12345677654320

examples/different/data/sample/1.in

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
10 12
2+
71293781758123 72784
3+
1 12345677654321

examples/different/data/secret/01.ans

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
408
2+
1000000000000000
3+
5177
4+
168383
5+
638207819439327
6+
8
7+
112
8+
3483822
9+
18974
10+
123409
11+
4127849162
12+
0
13+
875198495378459
14+
1100
15+
175817
16+
189414
17+
40000000
18+
10901826
19+
3
20+
121
21+
12
22+
1
23+
789571852
24+
173
25+
57891268
26+
4999999993
27+
561304
28+
110
29+
1246644096697
30+
13
31+
18795471810
32+
1587156
33+
5621
34+
590218309894
35+
8
36+
4
37+
14
38+
1000000000000000
39+
372036854766496
40+
360
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A bunch of handwritten cases.

examples/different/data/secret/01.in

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
412 4
2+
1000000000000000 0
3+
5178 1
4+
7598 175981
5+
929292929291300 291085109851973
6+
4 12
7+
12 124
8+
3489512 5690
9+
18975 1
10+
123412 3
11+
4127849174 12
12+
4 4
13+
875198547177030 51798571
14+
184 1284
15+
75 175892
16+
157 189571
17+
372036854766584 372036814766584
18+
19283109 8381283
19+
4 1
20+
135 14
21+
13 1
22+
4 5
23+
5 789571857
24+
174 1
25+
7 57891275
26+
372031854766584 372036854766577
27+
1274198 712894
28+
14 124
29+
1247178194 1247891274891
30+
15 2
31+
85 18795471895
32+
1587157 1
33+
5626 5
34+
590218309895 1
35+
12 4
36+
372036854766579 372036854766583
37+
41 27
38+
0 1000000000000000
39+
88 372036854766584
40+
547 187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1000000000000000
2+
1000000000000000
3+
0
4+
0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The four possible combinations of minimum/maximum values.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1000000000000000 0
2+
0 1000000000000000
3+
1000000000000000 1000000000000000
4+
0 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
SET(cases = 0)
2+
WHILE(!ISEOF)
3+
INT(0, 10^15) SPACE INT(0, 10^15) NEWLINE
4+
SET(cases = cases + 1)
5+
END
6+
ASSERT(1 <= cases && cases <= 40)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/python
2+
from sys import stdin
3+
import sys
4+
import re
5+
6+
integer = "(0|-?[1-9]\d*)"
7+
8+
MAX = 10**15
9+
10+
cases = 0
11+
12+
while True:
13+
line = stdin.readline()
14+
if len(line) == 0:
15+
break
16+
assert re.match(integer + " " + integer + "\n", line), "'%s' is not a pair of integers" % line
17+
(n, m) = map(int, line.split())
18+
assert 0 <= n <= MAX, "%s not in [0, %s]" % (n, MAX)
19+
assert 0 <= m <= MAX, "%s not in [0, %s]" % (m, MAX)
20+
cases += 1
21+
22+
assert 1 <= cases <= 40, "invalid number of cases %d not in [1,40]" % cases
23+
24+
# Nothing to report
25+
sys.exit(42)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Output validator for "A Different Problem". This validator is only
2+
* provided as an example: the problem is so simple that it does not
3+
* need a custom output validator and it would be more appropriate to
4+
* use the default token-based diff validator.
5+
*
6+
* Note: if you start writing error messages in, say, Swedish, make
7+
* sure your file is UTF-8 coded.
8+
*/
9+
#include "validate.h"
10+
11+
using namespace std;
12+
typedef long long int64;
13+
14+
15+
bool read_input(istream &in) {
16+
// we don't need the input to check the output for this problem,
17+
// so we just discard it.
18+
int64 a, b;
19+
if (!(in >> a >> b))
20+
return false;
21+
return true;
22+
}
23+
24+
25+
int read_solution(istream &sol, feedback_function feedback) {
26+
// read a solution from "sol" (can be either judge answer or
27+
// submission output), check its feasibility etc and return some
28+
// representation of it
29+
30+
int64 outval;
31+
if (!(sol >> outval)) {
32+
feedback("EOF or next token is not an integer");
33+
}
34+
return outval;
35+
}
36+
37+
bool check_case() {
38+
if (!read_input(judge_in))
39+
return false;
40+
41+
int64 ans = read_solution(judge_ans, judge_error);
42+
int64 out = read_solution(author_out, wrong_answer);
43+
44+
if (ans != out) {
45+
wrong_answer("judge answer = %d but submission output = %d\n",
46+
ans, out);
47+
}
48+
49+
return true;
50+
}
51+
52+
53+
int main(int argc, char **argv) {
54+
init_io(argc, argv);
55+
56+
while (check_case());
57+
58+
/* Check for trailing output. */
59+
string trash;
60+
if (author_out >> trash) {
61+
wrong_answer("Trailing output");
62+
}
63+
64+
accept();
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/* Utility functions for writing output validators for the Kattis
2+
* problem format.
3+
*
4+
* The primary functions and variables available are the following.
5+
* In many cases, the only functions needed are "init_io",
6+
* "wrong_answer", and "accept".
7+
*
8+
* - init_io(argc, argv):
9+
* initialization
10+
*
11+
* - judge_in, judge_ans, author_out:
12+
* std::istream objects for judge input file, judge answer
13+
* file, and submission output file.
14+
*
15+
* - accept():
16+
* exit and give Accepted!
17+
*
18+
* - accept_with_score(double score):
19+
* exit with Accepted and give a score (for scoring problems)
20+
*
21+
* - judge_message(std::string msg, ...):
22+
* printf-style function for emitting a judge message (a
23+
* message that gets displayed to a privileged user with access
24+
* to secret data etc).
25+
*
26+
* - wrong_answer(std::string msg, ...):
27+
* printf-style function for exitting and giving Wrong Answer,
28+
* and emitting a judge message (which would typically explain
29+
* the cause of the Wrong Answer)
30+
*
31+
* - judge_error(std::string msg, ...):
32+
* printf-style function for exitting and giving Judge Error,
33+
* and emitting a judge message (which would typically explain
34+
* the cause of the Judge Error)
35+
*
36+
* - author_message(std::string msg, ...):
37+
* printf-style function for emitting an author message (a
38+
* message that gets displayed to the author of the
39+
* submission). (Use with caution, and be careful not to let
40+
* it leak information!)
41+
*
42+
*/
43+
#pragma once
44+
45+
#include <sys/stat.h>
46+
#include <cassert>
47+
#include <cstdarg>
48+
#include <cstdlib>
49+
#include <iostream>
50+
#include <fstream>
51+
#include <sstream>
52+
53+
typedef void (*feedback_function)(const std::string &, ...);
54+
55+
const int EXITCODE_AC = 42;
56+
const int EXITCODE_WA = 43;
57+
const std::string FILENAME_AUTHOR_MESSAGE = "authormessage.txt";
58+
const std::string FILENAME_JUDGE_MESSAGE = "judgemessage.txt";
59+
const std::string FILENAME_JUDGE_ERROR = "judgeerror.txt";
60+
const std::string FILENAME_SCORE = "score.txt";
61+
62+
#define USAGE "%s: judge_in judge_ans feedback_dir < author_out\n"
63+
64+
std::ifstream judge_in, judge_ans;
65+
std::istream author_out(std::cin.rdbuf());
66+
67+
char *feedbackdir = NULL;
68+
69+
void vreport_feedback(const std::string &category,
70+
const std::string &msg,
71+
va_list pvar) {
72+
std::ostringstream fname;
73+
if (feedbackdir)
74+
fname << feedbackdir << '/';
75+
fname << category;
76+
FILE *f = fopen(fname.str().c_str(), "a");
77+
assert(f);
78+
vfprintf(f, msg.c_str(), pvar);
79+
fclose(f);
80+
}
81+
82+
void report_feedback(const std::string &category, const std::string &msg, ...) {
83+
va_list pvar;
84+
va_start(pvar, msg);
85+
vreport_feedback(category, msg, pvar);
86+
}
87+
88+
void author_message(const std::string &msg, ...) {
89+
va_list pvar;
90+
va_start(pvar, msg);
91+
vreport_feedback(FILENAME_AUTHOR_MESSAGE, msg, pvar);
92+
}
93+
94+
void judge_message(const std::string &msg, ...) {
95+
va_list pvar;
96+
va_start(pvar, msg);
97+
vreport_feedback(FILENAME_JUDGE_MESSAGE, msg, pvar);
98+
}
99+
100+
void wrong_answer(const std::string &msg, ...) {
101+
va_list pvar;
102+
va_start(pvar, msg);
103+
vreport_feedback(FILENAME_JUDGE_MESSAGE, msg, pvar);
104+
exit(EXITCODE_WA);
105+
}
106+
107+
void judge_error(const std::string &msg, ...) {
108+
va_list pvar;
109+
va_start(pvar, msg);
110+
vreport_feedback(FILENAME_JUDGE_ERROR, msg, pvar);
111+
assert(0);
112+
}
113+
114+
void accept() {
115+
exit(EXITCODE_AC);
116+
}
117+
118+
void accept_with_score(double scorevalue) {
119+
report_feedback(FILENAME_SCORE, "%.9le", scorevalue);
120+
exit(EXITCODE_AC);
121+
}
122+
123+
124+
bool is_directory(const char *path) {
125+
struct stat entry;
126+
return stat(path, &entry) == 0 && S_ISDIR(entry.st_mode);
127+
}
128+
129+
void init_io(int argc, char **argv) {
130+
if(argc < 4) {
131+
fprintf(stderr, USAGE, argv[0]);
132+
judge_error("Usage: %s judgein judgeans feedbackdir [opts] < userout", argv[0]);
133+
}
134+
135+
// Set up feedbackdir first, as that allows us to produce feedback
136+
// files for errors in the other parameters.
137+
if (!is_directory(argv[3])) {
138+
judge_error("%s: %s is not a directory\n", argv[0], argv[3]);
139+
}
140+
feedbackdir = argv[3];
141+
142+
judge_in.open(argv[1], std::ios_base::in);
143+
if (judge_in.fail()) {
144+
judge_error("%s: failed to open %s\n", argv[0], argv[1]);
145+
}
146+
147+
judge_ans.open(argv[2], std::ios_base::in);
148+
if (judge_ans.fail()) {
149+
judge_error("%s: failed to open %s\n", argv[0], argv[2]);
150+
}
151+
152+
author_out.rdbuf(std::cin.rdbuf());
153+
}

0 commit comments

Comments
 (0)