# Hướng dẫn sử dụng trình sinh test Relax - system Relax - system là hệ thống sinh test đơn giản, nhanh gọn được viết bởi [ntannn](https://www.facebook.com/ntannn.dev) và [iotran](https://www.facebook.com/letranhoanglanvn). ## Setup relax - system ### Cài đặt python Cài đặt python 3.11.9 [tại đây](https://www.python.org/downloads/release/python-3119/). Lưu ý: khi cài đặt sẽ có tùy chọn `add path`. Hãy chọn tùy chọn này để cài đặt môi trường cho python tự động. ### Setup Relax Tải Relax - system tại một trong 2 link sau: - [One drive](https://peaorg-my.sharepoint.com/:u:/g/personal/nhattan2007_peaorg_onmicrosoft_com/EYKsoPTxPxpMlIjOhv2soGIB-g98zplGgUylWj4-pshbtg?e=x9VuaJ) - [Google drive](https://drive.google.com/file/d/16PoaUo49x1-R1vzswyZoWtRJpmmAwRtz/view?usp=sharing) Tiến hành giải nén file, ta sẽ được folder sau. ![image](https://hackmd.io/_uploads/HkElZyVt0.png) ## Sinh inp Mở folder `sinhtest`, chọn file `sinhtest.cpp` hoặc `sinhtest2.cpp`. - `sinhtest.cpp` để sinh các bài có 1 sub - `sinhtest2.cpp` được tối ưu để sinh test với bài có từ $2 - 3$ subtasks. ### Về file `sinhtes2.cpp` ```c++ const int btest = 1; const int etest = 100; // so luong test const int test_for_sub1 = 30; //% so luong test theo tung sub const int test_for_sub2 = 30; const int test_for_sub3 = 40; const int s1 = double(etest) / 100.0 * test_for_sub1 * 1.0; const int s2 = double(etest) / 100.0 * test_for_sub2 * 1.0; ``` Hãy sửa lại số % test tùy sub ở biết `test_for_subx` Sửa biến `btest` và `etest` với mỗi bài tùy vào số lượng test bạn muốn. Sau khi viết xong đoạn code sinh input phù hợp, hãy chạy file sinh test, file inp của bài toán sẽ được sinh ra. #### Lấy ví dụ với bài toán sau --- ![hi](https://imgur.com/6qV15Re.png) --- Đây là đoạn code mà chúng mình sử dụng để sinh test cho bài toán này: [ideone](https://www.ideone.com/RgiFlk). #### Mô tả kĩ hơn ```c++ void sub1(int x) { ofstream os; ofstream inp((to_string(x) + ".inp").c_str()); ll t, n, l, r, m, a, b, q, k; n = Rand(1, N); if(x >= cal(50, s1)) // giới hạn hơn 50% test có n đạt giá trị giới hạn n = N; // của sub tasks if(x <= s1 / 3) k = Rand(1, 100); // 1/3 test đầu của sub1 có k nhỏ (k <= 100) else if(x <= 2 * s1 / 3.0) k = Rand(100, n); // 2/3 test sau có k lớn hơn else k = Rand(1, N); // 1/3 test cuối, k đạt giá trị giới hạn đề bài inp << n << " " << k << '\n'; for(int i = 1; i <= N; i++) vt.pb(i); random_shuffle(all(vt)); //do mỗi giá trị a chỉ xuất hiện một lần for(int i = 1; i <= n; i++) { // các bạn có thể sử dụng map + while a = vt.back(); vt.pop_back(); b = Rand(1, W); inp << a << " " << b << '\n'; } vt.clear(); // do vector mình khai báo là biến toàn cụng nên phải xóa } ``` Một số tip: - Nếu bạn muốn sinh một ít test đặc biệt với số lượng ngẫu nhiên và ít, bạn có thể dùng trick sau: ```c++ int t = Rand(1, 10); if(t == 5) { ...// xử lý sinh test đặc biệt } // đảm bảo 10% tỉ lệ ra test đặc biệt <(")) ``` - đang update vì nhiều tip quá quên r.... #### Lưu ý Hãy viết thuật toán sinh inp thật thông minh và nhớ nghĩ thật kĩ các trường hợp đặc biệt nữa để bộ test đủ mạnh. ## Sinh out Phần này cơ bản là dễ. ### Đưa file code chuẩn Dán code chuẩn vào file `code/origin/code.cpp`. **LƯU Ý, HÃY SỬ DỤNG FREOPEN LÀ "test.inp" VÀ "test.out"** ```c++ #define task "test" if(fopen(task ".inp", "r")) { freopen(task ".inp", "r", stdin); freopen(task ".out", "w", stdout); } ``` Trong foler `Relax-system/sinhtest` của bạn lúc này sẽ có một đống file inp, hãy copy toàn bộ file inp đó (trừ file `sinhtest.cpp`) vào folder `Relax-system/inp` ![image](https://hackmd.io/_uploads/HJr0kxVK0.png) Rồi, giờ hãy chạy file run2.cmd ở folder, mở folder `out` và toàn bộ test sẽ nằm trong đó. --- Trình sinh test này hiện vẫn còn vài chỗ bất tiện, mình sẽ tối ưu thêm sau. Nếu gặp bugs trong quá trình sử dụng, vui lòng liên hệ ntan.