창작마당에서는 문제를 자유롭게 만들 수 있고, 관리자의 확인 후 실제 문제로 AOJ에 출판할 수 있습니다.
간단한 문제를 하나 만들어봅시다.
https://aoj.anacnu.kr/workshop 에 접속합니다.

새 문제 만들기를 클릭합니다.

이번에 만들 문제는 두 정수 , 가 주어졌을 때 두 수를 뺀 값을 계산하는 문제입니다.
각 칸에 들어가야 하는 내용은 다음과 같습니다.
제목: 문제의 제목입니다.문제 타입: 채점 방법을 결정합니다. 보통의 경우 ICPC를 선택합니다.
생성을 누르면 창작마당 내부로 들어오게 됩니다.
지문: 푸는 사람에게 보일 문제 지문입니다. Markdown 문법으로 작성합니다.테스트/테스트케이스: 제출한 프로그램을 채점할 때 사용할 입력들을 관리합니다. A+B라면 2 3이나 5 9와 같은 입력들을 파일 단위로 저장하게 됩니다.리소스: 후에 설명할 제너레이터, 체커, 벨리데이터를 컴파일하는데 필요한 추가 리소스를 관리합니다. 어지간해선 들어갈 일이 없습니다.제너레이터: 테스트케이스를 생성하는 프로그램들을 관리합니다.체커: 문제 타입이 Special Judge일 경우에만 사용합니다. 입력과 정답 출력, 사용자 출력을 입력으로 받아서 사용자 출력이 맞는지 확인하는 프로그램입니다.밸리데이터: 테스트케이스들이 올바른 형식을 가지는지 확인하는 프로그램입니다. 공백이 잘 들어가 있는지, 입력 설명과 동일한 구조로 구성되어 있는지 등솔루션: 테스트케이스를 입력으로 받아서 답을 출력하는 프로그램들을 관리합니다.인보케이션: 테스트케이스와 솔루션을 선택해서 실제로 채점을 돌려볼 수 있는 페이지입니다.스냅샷: git이나 체크포인트라 생각하면 됩니다. 문제를 만드는 진행 상황을 저장하거나 롤백할 수 있습니다.멤버: 공동 작업자를 추가할 수 있습니다.
우선 지문을 먼저 작성해 봅시다.
지문을 잘 작성하는 방법으로는 solved.ac 아레나 개최 매뉴얼이나 UCPC 디스크립션 작성 및 포매팅 컨벤션를 참고하세요.
작성 후에는 우측 하단의 저장을 눌러 저장합니다.

다음에는 솔루션 탭에 와서 문제의 정해(正解)를 업로드합니다. 이때 예상 verdict가 AC인지, 메인 솔루션이 토글 되어있는지 확인해주세요.

솔루션은 많을 수록 좋습니다. 문제를 푸는 사람이 실수할 법한 코드들을 다양한 언어로 올리는 것을 추천합니다. 특히 배열 접근이 필요한 문제의 경우 off-by-one 오류, 수식 계산이 필요한 문제의 경우 오버플로우 오류, 시간 초과나 메모리 초과가 날 수 있는 코드 등등을 고려해서 다양한 솔루션을 업로드합니다. 복잡한 문제라면 나이브 풀이도 꼭 업로드해봐야 합니다. 나이브 풀이란 가장 직관적인 풀이로, 예를 들어 피보나치 수를 구하는 문제고 인데 재귀로 푸는 코드를 의미합니다.
어느정도 복잡한 문제라면 문제를 푸는 사람이 실수할 법한 코드를 짜는 것은 혼자서는 버거울 수도 있으니 공동 작업자를 초대하는 것을 추천합니다.

밸리데이터는 필수는 아니지만 그래도 입력의 무결성을 증명하는데 좋은 수단입니다.
가령 지문의 입력 설명에서는 로 입력 제한을 잡았는데 실제로는 입력이 로 주어진다거나 하는 오류를 잡을 수 있습니다.
밸리데이터는 테스트케이스를 입력으로 받아서 올바른 구조인지 판단하는 프로그램입니다. 우리는 밸리데이터 구현에 언어로는 C++를 사용할 것이고, 라이브러리로는 testlib.h를 사용할 것입니다. (Codeforces나 Atcoder, BOJ 등에서도 표준으로 사용됩니다)
프리셋 -> testlib 보일러플레이트를 눌러 기본 템플릿을 불러옵니다.

그러면 이런 C++ 코드가 보입니다. testlib.h는 리소스 탭에서 확인/다운로드 할 수 있습니다.

로컬 환경에 testlib.h를 가져와서 작업하는 걸 추천합니다. 대략적인 문법은 다음과 같습니다.
inf: 입력 스트림inf.readInt(MIN, MAX, NAME): [MIN-MAX]인 32비트 정수 NAME을 하나 입력으로 받습니다.inf.readLong(MIN, MAX, NAME): [MIN-MAX]인 64비트 정수 NAME을 하나 입력으로 받습니다.inf.readInts(N, MIN, MAX, NAME): 공백으로 구분되어 주어지는 [MIN-MAX]인 32비트 N개를 입력으로 받습니다.inf.readToken(PATTERN, NAME): 정규식 PATTERN을 만족하는 토큰 NAME을 입력으로 받습니다.inf.readSpace(): 공백을 입력으로 받습니다.inf.readEoln(): \n을 입력으로 받습니다. 모든 테스트케이스들은 \n로 끝나야 하므로 마지막에 꼭 체크해야 합니다. A+B라면 주어지는 입력은 A B가 아니라 A B\n여야 합니다.inf.readEof(): 입력의 종료를 체크합니다. readEof를 호출했는데 아직 입력이 남아있으면 오류가 뜹니다. 이 역시 꼭 체크해야 합니다.
이제 제너레이터 탭으로 이동해서 제너레이터를 생성해 봅시다. 제너레이터는 테스트케이스를 생성하는 프로그램입니다. 우리는 Python을 사용할 것입니다.
추가 -> 직접 입력 -> 템플릿-> Python 템플릿을 불러와주세요.

테스트케이스를 생성할 때는 random을 활용합니다. 이때 생성되는 값이 매 생성마다 달라지면 안되므로 우리는 인자를 받아서 seed로 설정해줄 겁니다.
우리가 만드는 A-B 문제의 입력으로는 1이상 10 이상의 두 정수 A, B가 공백으로 구분되어 주어지므로 random으로 정수 2개를 생성해서 출력해줬습니다.
이 프로그램은 gen --seed=XXX --workshop_seed=YYY처럼 실행하고 주어지는 인자가 같다면 항상 같은 테스트케이스를 출력합니다. 창작마당에서는 --workshop_seed=YYY는 알아서 각 문제마다 고유한 해시값으로 넣어주기 때문에 우리는 gen --seed=XXX 이렇게 실행하면 됩니다.

제너레이터를 추가했다면 테스트로 이동합니다. 여기서는 스크립트를 작성하여 제너레이터를 실행할 수 있습니다.
for i in 1..5:
gen --seed=[i]
gen --seed=1
gen --seed=2
gen --seed=3
gen --seed=4
gen --seed=5
위 두 스크립트는 동일하게 동작합니다. 스크립트 작성이 완료됐다면 스크립트 실행을 눌러주세요.

그러면 아래에 생성된 테스트케이스들을 확인할 수 있습니다. 눈 버튼을 클릭하면 입력 내용을 확인할 수 있습니다.

아까전 우리는 제너레이터의 인자로 seed를 넣어줬기 때문에 스크립트 실행을 여러번 돌려도 테스트케이스는 같은 것을 확인할 수 있습니다.
아직 정답이 생성되지 않았기 때문에 출력은 (없음)이라 뜨는데 일단 무시합니다.
구분선을 추가하면 서브테스크 문제로 전환할 수는 있으나 여기서는 언급만 하고 넘어가겠습니다.

벨리데이터를 만들었다면, 다시 벨리데이터 탭 최하단으로 이동하여 전체 검증을 눌러서 검증해볼 수 있습니다. 제가 일부러 틀리게 넣은 6번 테스트케이스의 A 변수가 0이며 입력 제한인 [1-10]에 맞지 않는다고 오류를 내주는 것을 확인할 수 있습니다.

인보케이션 탭에 들어가서 정답 생성을 눌러주세요. 아까전 생성한 테스트케이스와 솔루션을 이용해서 정답 출력을 생성합니다.

모두 잘 생성된 것을 확인할 수 있습니다.

테스트케이스 탭에 다시 돌아가서 테스트케이스 눈 버튼을 클릭해보면 출력도 저장된 것을 확인할 수 있습니다.

이제 두 솔루션에 1번~5번 테스트케이스를 넣어서 실행해봅시다.

메인 솔루션 (sol)은 (당연하게도) 모두 AC가 나왔고, 틀려야할 솔루션 (wa)는 WA가 나온 것을 확인할 수 있습니다.
복잡한 문제라면 나이브 풀이가 시간초과나 메모리초과가 나오는지, 실수가 있는 풀이가 WA를 받는지, 정답끼리 다른 답을 내놓는지 등을 꼭 확인해야 합니다. 의도된 Verdict가 안나왔을 경우 테스트케이스를 강화할 필요가 있다는 의미입니다.
예를 들어서 피보나치 수 문제를 만들고 있는데, N 최댓값은 100임에도 불구하고, 재귀 풀이 (나이브 풀이)가 AC를 받는다면 테스트케이스 중에 N = 100인 경우가 있는지 확인해야 한다는 것입니다.

작업이 일단락됐다면 스냅샷 -> 커밋을 눌러 진행 상황을 저장합니다. 공동 작업자 멤버들끼리는 스냅샷 단위로 공유되기 때문에 커밋을 안했다면 내가 작업한 내용이 다른 작업자에게 공유되지 않습니다.
아직은 창작마당에서 만든 문제를 바로 AOJ에 업로드할 수 없습니다.
ANA 동아리 임원진이나 저에게 연락 주시면 확인 후 업로드해드립니다!

https://aoj.anacnu.kr/problems/831
정상적으로 문제가 업로드됐습니다!