# 台南一中資訊學科能力競賽舉辦指南
**本頁面內容已搬遷至以下頁面,如要修改,請在這些頁面為之,如果沒有帳號,請在出題群組 @xiplus**
* https://wiki.tfcis.org/競賽舉辦指南
* https://wiki.tfcis.org/CMS
* https://wiki.tfcis.org/TPS
## 出題準備
競賽準備大致上分成幾個階段:
1. 尋找出題者
2. 各自出題 & 開會配題
3. 產測資
4. 測題以及補題敘
5. 寫題解
6. 產參賽者帳號
### 競賽大約舉辦時間
在開始接下來的流程之前,需要先了解當前要準備的是哪一場比賽,時間大約在什麼時候,如此才能估計每個階段大致要在何時完成。
| 競賽名稱 | 大約時間 | 競賽時間長度 | 總題數 |
| -------- | -------- | ------- | ----- |
| 初選 | 9 月中旬 | 3 小時 | 5~6 題 |
| 複選 | 9 月下旬 | 3~4 小時 | 5~6 題 |
### 尋找出題者
- 開始時間 : 競賽前 2~3 個月
- 執行時間 : 大約 2 個禮拜,最遲 1 個月
這個階段要到社團詢問大家出題的意願,當前也有出題者的 messenger 以及 Discord 群組可以直接在群組內招募。
通常如果沒有指定出題者,大家很容易就會不在意出題這件事,因此**建議都先指定**。
### 各自出題 & 開會配題
- 開始時間 : 競賽前 1~2 個月
- 執行時間 : 大約 1~2 個禮拜
這個階段會請大家各自出題目,還不需要急著產測資,可以多出幾題,最後多出來的題目可以存起來之後使用。
出題期間就可以同步開會配題,一邊出題一邊調整題目的內容。
採用的題目依照該次競賽的難度決定,題數可以參考前面的表格。
最後多出來的題目可以放到 Trello 上,連結在 Discord。
另外,「出題」「產測資」「寫題敘」可以不用全部同個人,拆開分配的話時間較不足的也會比較容易參與。
### 產測資
- 開始時間 : 競賽前 3~4 個禮拜
- 執行時間 : 大約 1~2 個禮拜
決定好這次要使用的題目後,就可以針對這些題目產測資、新增幾筆子任務。
在這個階段就可以先在 CMS 上建好 Contest,將每題的測資放上去了,接下來進到測題階段也比較方便。
**保險起見,題敘建議開賽前再上傳到系統上。**
### 測題以及補題敘
- 開始時間 : 競賽前 1~2 個禮拜
- 執行時間 : 大約 1~2 個禮拜
最後就是測題階段,測題的人請確保不是參賽者,並且不會洩漏題目給參賽者。
這個階段要針對題目測試各種想得到的假解,也測試各個子任務的正確性,並且將題敘各種不清楚或是可能造成誤會的部分修正。
### 寫題解
- 開始時間 : 競賽前 1 個禮拜
- 執行時間 : 大約 1 個禮拜
這個階段不一定需要,依照各場競賽不同可以討論要不要寫。
部分競賽結束後會有題解時間,因此需要事先寫好題解簡報。
### 產參賽者帳號
- 開始時間 : 競賽前 1~2 天
- 執行時間 : 大約 1~2 天
最後是產參賽者帳號,可以統一一下帳號的格式,至於密碼可以在網路上找密碼產生器。產出的帳號密碼記得要記錄在非公開的文件上,如果是實體賽,當天記得列印帳號密碼給對應的參賽者。
---
## 競賽當天
競賽當天可以大致上分成幾個部分:
1. 競賽開始前
2. 競賽期間
### 競賽開始前
在競賽開始前,需要先確認每個參賽者都能登入 CMS,為了公平起見,建議 CMS 比賽開始時間先不要設定在準確的開始時間,確認大家都能登入後再修改回來。
除了確認登入以外,開始前也要向參賽者宣讀競賽規則。
### 競賽期間
競賽期間要隨時注意有沒有參賽者提出問題。
問題經過判斷如果在題目裡面已經有提到,就不要額外說明,直接說題目裡面已經有提到即可(有常用的回覆選單可以選到)。
反之,如果這個問題關乎題目的正確性,或是會影響題目的可理解性等等,記得要**發送 Annoucement**。
除了等待參賽者提出問題,比賽現場也需要有人抽樣檢視 submission,確認該 submission 得分是否在預期中。若題敘、測資、題目設定等出現有誤,先發 Annoucement 請大家暫停上傳,儘速修完題目後再開放並 rejudge。
---
## 系統相關
### CMS
> 官方文件: https://cms.readthedocs.io/en/v1.4/
#### 上架題目
每個題目需要設定的內容包含了:
- 題目名稱
- 計分模式
- 時間限制(ms)
- 記憶體大小限制(MiB)
- 上傳間隔(s)
- 測試資料
- 配分
**計分模式** 要設定成 IOI 2017。在 CMS 當中是顯示:
```
Use the sum over each subtask of the best result for that subtask across all submissions (IOI 2017-)
```
**上傳間隔** 則是依照每場比賽不同而調整。
以 IOI 2021 為例,建格式設定 1 分鐘(60 秒),最後的 15 分鐘取消上傳間隔。
**測試資料** 的部分可以依照下面的格式走:
- 輸入檔
副檔名為 `.in` (上傳到 CMS 的時候記得要指定副檔名是 `*.in`)
名稱依照 `{子任務編號}_{子任務測資編號}`
如果該題只有一個子任務可以省略 `{子任務編號}_`
例如第一筆子任務的第三個側資檔名就會是 `1_3.in`
- 輸出檔
副檔名為 `.out` (上傳到 CMS 的時候記得要指定副檔名是 `*.out`)
名稱依照 `{子任務編號}_{子任務測資編號}`
如果該題只有一個子任務可以省略 `{子任務編號}_`
例如第一筆子任務的第三個側資檔名就會是 `1_3.out`
最後把全部的測資包成一個 zip,直接選擇**一次上傳多筆測資(Upload Multiple Subtasks)**
**配分** 的部分我們通常是使用 GroupMin,也就是子任務的每一筆測試資料都要通過才會拿到整筆子任務的分數。
如果是採用編號的方式命名測資名稱,那麼可以選擇使用這種方式:
```
[[子任務1配分, 子任務1測資數], [子任務2配分, 子任務2測資數], ...]
```
或是使用 Regular Expression 來表示對應到的測資名稱:
```
[[子任務1配分, 正則表達式1], [子任務2配分, 正則表達式2], ...]
```
可以參考: https://cms.readthedocs.io/en/v1.4/Score%20types.html#groupmin
### TPS
TPS(Task Preparartion System) 是一套可以方便產生題目測試資料以及題本的工具,關於 TPS 可以參考以下的 Github Repo:
> TFcis TPS Example: https://github.com/TNFSH-Programming-Contest/TPS-example
> IOI 2017 TPS: https://github.com/ioi-2017/tps
接下來整理的內容主要參考 TFcis TPS Example,相關的範例也都在上面了。
### 資料夾結構
每題中包含以下目錄和檔案:
- checker: 檢查輸出與標準答案是否相等的程式
- gen: 所有產測資相關的程式碼
- gen/data: 測資產生指令
- scripts: TPS所使用的腳本
- solution: 標程及其他解法程式碼(包含所有拿部分分的程式碼),不要跟 validator 搞混
- solution/check.txt: 所有標程對於所有測資的執行狀況(包含是否WA、TLE),使用指令 make arithmetic-check
- statement: 題本
- statement/index.md: (TPS格式)markdown 格式的題目敘述,之後會以 pandoc 輸出成 PDF
- statement/index.pdf: (TPS格式)用 tps statement 輸出的 PDF 題目敘述
- tests: 測試資料
- tests/mapping: 各子任務所屬測資檔案對應表(tps gen 自動產生),使用於自動匯入CMS時
- validator: 驗證測資格式是否正確,是否符合範圍限制,各子任務是否符合各自限制,不要跟 solution 搞混
- problem.json: 題目設定,包含時限及CMS設定
- solutions.json: 標程設定,用以產生輸出檔的標程參數為 "verdict": "model_solution"
- subtasks.json: 子任務分數設定
---
接下來針對幾個需要自訂的檔案進行說明
### 題目設定 - problem.json
> 範例檔案: https://github.com/TNFSH-Programming-Contest/TPS-example/blob/master/Arithmetic/problem.json
其中有幾項需要特別注意的欄位:
| 參數 | 範例值 | 設定位置 |
| --- | --- | --- |
| 競賽名稱 | TPS範例題目 | problem.json 的`contest_name`欄位(所有題目皆需設定) |
| 題目編號 | A | problem.json 的`problem_label`欄位 |
| 題目代號 | Arithmetic | problem.json 的`name`和`code`欄位 |
| 題目名稱 | 四則運算 | problem.json 的`title`欄位 |
| 時間限制 | 1 秒 | problem.json 的`time_limit`欄位 |
| 記憶體限制 | 512 MB | problem.json 的`memory_limit`欄位 |
| 上傳間隔 | 120 秒 | problem.json 的`min_submission_interval`欄位 |
### 子任務配分 - subtasks.json
> 範例檔案: https://github.com/TNFSH-Programming-Contest/TPS-example/blob/master/Arithmetic/subtasks.json
子任務配分設定於 subtasks.json 。格式如下範例:
```json
{
"global_validators": ["validator.cpp"],
"subtasks": {
"task1": {
"index": 1,
"score": 40,
"validators": []
},
"task2": {
"index": 2,
"score": 60,
"validators": ["validator-2.cpp"]
}
}
}
```
`subtasks`底下的Key為各測資名稱(如`task1`),`score`為該測資的分數。
## 題本 - statement/
題本使用 Markdown 撰寫並置於 `statement/index.md`。題本內需要使用到的圖片都放在 `statement/` 資料夾下。題本 Markdown 撰寫完成後切到題目目錄底下後使用 `tps statement` 指令可以產生 PDF 檔。
題本的撰寫格式可以參考範例檔案。
> 範例檔案: https://github.com/TNFSH-Programming-Contest/TPS-example/blob/master/Arithmetic/statement/index.md
需要注意的是,題本的題目相關資訊會參照 `problem.json` 產生,子任務會參照 `subtasks.json` 產生,因此需要先設定好這兩個檔案。
## 產測資 - gen/ gen/data
> 範例檔案: https://github.com/TNFSH-Programming-Contest/TPS-example/tree/master/Arithmetic/gen
產生測資的程式應置於 `gen/` 下。
以下說明適用於符合TPS產測方式的作法。
產測程式根據**命令行參數**來產生不同測資,該程式產生測資必須使用**標準輸出(stdout)**,不能是檔案輸出。
在 `gen/data` 設定各子任務所使用的程式名稱及參數。
每一行代表一個測資點,使用 `@subtask 測資名稱` 區分不同子任務,測資名稱不可有空白,並且應跟 `subtasks.json` 內相同。範例如下:
```
@subtask sample
manual sample-01.in
@subtask a0
gen task2 qutxm
@subtask 1e4
gen norm 0 10000 csizh
@subtask all
manual all-01.in
gen norm -1000000000 1000000000 jvnyj
```
如果需要手動產生測資,將測資檔放置於 `gen/manual`,然後在`gen/data`寫入一行`manual 測資檔名稱`。
在 `gen` 後面的內容 `testlib.h` 會將它當作該筆測資的亂數種子,舉例來說 `gen task2 qutxm` 會將 `task2 qutxm` 當作亂數種子。
固定亂數種子就會產出相同的測資內容。可以到 https://www.random.org/strings/ 產亂數種子。
設定完成後切到題目目錄底下後使用 `tps gen` 指令產生測資,結果會存於 `tests/`。
### 驗測程式 - validator/
> 範例檔案: https://github.com/TNFSH-Programming-Contest/TPS-example/tree/master/Arithmetic/validator
驗證測資**數值範圍**、圖論題是否為一棵樹、是否連通等題目所給定的限制(與解題演算法無關)屬於驗測程式範疇,放置於 `validator/` 資料夾下。
並在 `subtasks.json` 設定要使用哪個驗測程式。
所有子任務都使用的設定於`subtasks.json`的`global_validators`。
單一子任務使用的則設定於對應子任務下的`validators`。
測試不同演算法**是否會TLE、得到哪些部分分數**的程式應視為**標程**,請參閱標程說明。
## 標程 - solution/ solutions.json
將標程及其他拿部分分的解法都放在 `solutions/` 底下。
並在 `solutions.json` 設定標程如以下格式:
```json
{
"filename.cpp": {
"verdict": "model_solution"
}
}
```
其他解法是否設定於 `solutions.json` 皆無所謂。
`verdict` 值可參閱[官方說明](https://github.com/ioi-2017/tps/tree/master/docs#solutionsjson)。
## checker/
因為TPS沒有提供CMS所使用的white-diff checker,本範例提供完全相符比較的checker(比CMS嚴格),該檔案不會匯入到CMS中(務必使用[TFcis/cms](https://github.com/TFcis/cms)及在`problem.json`中設定`"ignore_checker": true`)。
###### tags: `指南`