Skip to content

Commit

Permalink
Add an example package (#125)
Browse files Browse the repository at this point in the history
* Add an example package

* Clean up
  • Loading branch information
MasloMaslane authored Sep 23, 2023
1 parent c268ea1 commit 0a9d6df
Show file tree
Hide file tree
Showing 11 changed files with 907 additions and 12 deletions.
76 changes: 76 additions & 0 deletions example_package/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# sinol-make
.cache
cache
in/.md5sums

# Tests
in/*.in
out/*.out
!in/???0*.in
!out/???0*.out

# export package file
*.tgz

# LaTeX
*.pdf
*.ps
!doc/logo.*

*.aux
*.lof
*.log
*.lot
*.fls
doc/*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
.*.lb

*.dvi
*.xdv
*-converted-to.*
# these rules might exclude image files for figures etc.
*.eps

## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml

# Encrypted files
*.gpg

# SIO binnary
*.e

# Python Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# pyenv
.python-version

# IPython
profile_default/
ipython_config.py

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so
*.o
24 changes: 13 additions & 11 deletions examples/config.yml → example_package/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ title_pl: Przykładowe zadanie
# (if number of groups doesn't divide 100, then the last groups will have the remaining points).
# Group 0 always has zero points.
scores:
1: 20
2: 30
3: 25
4: 25
1: 40
2: 60

# Time limit for all tests is defined in `time_limit` key.
# More precise time limit for each group or test can be defined in `time_limits` key.
Expand All @@ -43,18 +41,22 @@ override_limits:

# Extra compilation arguments can be defined in `extra_compile_args` key.
# Each language can have different extra arguments.
extra_compilation_args:
cpp: 'abclib.cpp'

# extra_compilation_args:
# cpp: 'abclib.cpp'

# The arguments can also be in an array:
extra_compilation_args:
cpp:
- 'abclib.cpp'
- 'abclib2.cpp'

# extra_compilation_args:
# cpp:
# - 'abclib.cpp'
# - 'abclib2.cpp'

# Additional files used in compilation can be defined in `extra_compilation_files` key.
# They are copied to the directory where the source code is compiled.
# All languages have the same additional files.
extra_compilation_files: ['abclib.cpp', 'abclib.py']

# extra_compilation_files: ['abclib.cpp', 'abclib.py']


### Keys used by sinol-make:
Expand Down
Empty file added example_package/in/.gitkeep
Empty file.
Empty file added example_package/out/.gitkeep
Empty file.
12 changes: 12 additions & 0 deletions example_package/prog/abc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// This is the main model solution.
// It is used for generating output files.

#include <bits/stdc++.h>

using namespace std;

int main() {
int a, b;
cin >> a >> b;
cout << a + b << endl;
}
45 changes: 45 additions & 0 deletions example_package/prog/abcingen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <bits/stdc++.h>
#include "oi.h"
using namespace std;

// Change this function to generate one test for stresstesting.
// The script prog/abcingen.sh in 10 seconds generates
// as much tests as possible and compares the outputs
// of the model solution and brute solution.
// The tests shouldn't be very big, but should be able to cover edge cases.
void generate_one_stresstest(oi::Random &rng) {
cout << rng.randSInt(1, 10) << ' ' << rng.randSInt(1, 10) << endl;
}

// Change this function to create a test with the given name.
// The lists of tests to generate needs to be written in prog/abcingen.sh
void generate_proper_test(string test_name, oi::Random &rng) {
if (test_name == "0a")
cout << "0 1" << endl;
else if (test_name == "1a")
cout << rng.randSInt(5, 1'000) << ' ' << rng.randSInt(5, 1'000) << endl;
else if (test_name == "2a")
cout << "2 2" << endl;
else {
cerr << "Unrecognized test_name = " << test_name << endl;
exit(1);
}
}

int main(int argc, char *argv[]) {
if (argc == 3 && string(argv[1]) == "stresstest") {
unsigned int seed = atoi(argv[2]);
oi::Random rng(seed);
generate_one_stresstest(rng);
return 0;
}
if (argc != 2) {
cerr << "Run prog/abcingen.sh to stresstest and create proper tests." << endl;
exit(1);
}
string test_name = argv[1];
unsigned int seed = (unsigned int) hash<string>{}(test_name);
oi::Random rng(seed);
cerr << "Generating test " << test_name << "..." << endl;
generate_proper_test(test_name, rng);
}
42 changes: 42 additions & 0 deletions example_package/prog/abcingen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

# This script first stresstests the model solution for 10 seconds
# and if it passes, it will generate the proper tests.
# To generate both types of tests, it executes ingen.cpp and passes it some arguments.
# The `test_ids` variable needs to have a manually written list of all proper tests.

prog_dir="$(realpath "$(dirname "$0")")"
cache_dir="$prog_dir/../.cache"
mkdir -p "$cache_dir"
script_name="$(basename "$0")"
task_id=${script_name:0:3}
gen_exe="$cache_dir/${task_id}ingen"
sol_exe="$cache_dir/${task_id}solution"
slo_exe="$cache_dir/${task_id}slow"
stresstest_seconds=10
function compile_cpp {
g++ -std=c++20 -O3 -lm -Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-result -Wfloat-equal "$1" -o "$2" \
|| exit 1
}

# Change the list of tests to generate and (if needed) the paths of solutions.
test_ids="0a 1a 2a"
compile_cpp "$prog_dir/${task_id}ingen.cpp" "$gen_exe"
compile_cpp "$prog_dir/${task_id}.cpp" "$sol_exe"
compile_cpp "$prog_dir/${task_id}s.cpp" "$slo_exe"

for (( i=0, SECONDS=0; SECONDS < stresstest_seconds; i++ )); do
in_test="$cache_dir/input.in"
slo_out="$cache_dir/slo.out"
sol_out="$cache_dir/sol.out"
printf "Running stresstest $i\r"
"$gen_exe" stresstest $i > "$in_test" || { echo "Failed to generate test $i"; exit 1; }
"$slo_exe" < "$in_test" > "$slo_out" || { echo "Brute crashed on test $i"; exit 1; }
"$sol_exe" < "$in_test" > "$sol_out" || { echo "Solution crashed on test $i"; exit 1; }
diff "$slo_out" "$sol_out" -w > /dev/null || { echo "Outputs differ on test $i"; exit 1; }
done
echo "Stresstest passed with $i tests"

for test in $test_ids; do
"$gen_exe" "$test" > "$prog_dir/../in/${task_id}${test}.in" || { echo "Failed to generate test $test"; exit 1; }
done
56 changes: 56 additions & 0 deletions example_package/prog/abcinwer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <bits/stdc++.h>
#include "oi.h"
using namespace std;

int main() {
oi::Scanner in(stdin, oi::PL);

// Change this code to read and validate the input.
int n = in.readInt(0, 1'000);
in.readSpace();
int m = in.readInt(0, 1'000);
in.readEoln();
in.readEof();
assert(n > 0 || m > 0);

// Change this code to have functions which return
// whether the test satisfies a given subtask.
auto is_subtask1 = [&]() -> bool {
return n >= 0 && m >= 0;
};
auto is_subtask2 = [&]() -> bool {
return n >= 5 && m >= 5;
};

// Change this code to have functions which return
// whether the test is exactly the same as
// the sample tests in the statement.
auto is_0a = [&]() -> bool {
return n == 0 && m == 1;
};
auto is_1ocen = [&]() -> bool {
return n == 1000 && m == 1000;
};

map<int, bool> subtasks = {
{1, is_subtask1()},
{2, is_subtask2()},
};
string subtasks_s;
for (auto [subtask_id, is_valid] : subtasks)
subtasks_s += is_valid ? to_string(subtask_id) : string("-");

map<string, bool> sample_tests = {
{"0a", is_0a()},
{"1ocen", is_1ocen()},
};
string sample_test_s = "-";
for (auto [name, is_valid] : sample_tests)
if (is_valid)
sample_test_s = name;

cout << "OK "
<< "n = " << setw(4) << n << ", "
<< "m = " << setw(4) << m << ", "
<< "subtasks = " << subtasks_s << ", sample test = " << sample_test_s << endl;
}
11 changes: 11 additions & 0 deletions example_package/prog/abcs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This is a "brute force" solution for testing model solution.

#include <bits/stdc++.h>

using namespace std;

int main() {
int a, b;
cin >> a >> b;
cout << a + b << endl;
}
Loading

0 comments on commit 0a9d6df

Please sign in to comment.