atcoder-crystal-workspace
Version, currently main branch1 version
- main branchlatestJul 31, 2026
github.com/ReiAkidzuki/atcoder-crystal-workspace
AtCoder Crystal 1.17.0 workspace with testing, bundling, random tests, and AI contest safeguards
Installation
# Add this to your shard.yml
dependencies:
atcoder-crystal-workspace:
github: ReiAkidzuki/atcoder-crystal-workspace
branch: mainmain is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
1.17.0- License
- MIT
Dependencies
Runtime Dependencies
README
AtCoder Crystal workspace
English | 日本語
This workspace targets AtCoder's Crystal 1.17.0 environment.
It is a companion to AtCoder Ruby workspace for problems whose time limits are difficult to meet in Ruby, while keeping the same commands and layout.
Solutions and custom libraries remain separate during development and are bundled into one submission.cr for execution and submission.
Why this is a separate workspace
This is maintained as an independent GitHub template instead of being merged into the Ruby workspace.
Crystal needs its own compiler, Shards dependencies, native libraries, and build cache; keeping those concerns separate makes setup and CI easier to understand.
The contest, tasks, new, test, run, random, bundle, and submit commands deliberately match the Ruby workspace.
You can copy downloaded metadata and tests from a Ruby workspace one task at a time without overwriting a solution:
make import-task FROM=../atcoder-ruby-workspace TARGET=abc468/a
This copies .problem-url, .contest.json when available, test/*.in, test/*.out, and .samples-complete, then creates a fresh main.cr.
It neither converts nor copies Ruby solutions, custom libraries, or random-test programs.
If source and destination data conflict, it stops without overwriting the existing files.
Start from GitHub
Choose “Use this template” and then “Create a new repository” on GitHub. A repository made from the template has independent history, so a fork is unnecessary unless you specifically want the fork relationship.
To share solutions and custom libraries across computers, create one repository from the template and clone that same repository on each computer. Cookies and contest locks are not committed, so configure them separately on every device.
Generative AI during live contests
AtCoder's rules against generative AI apply to ongoing ABCs, ARCs of every division, and AGCs, including Unrated participation. AHCs have separate rules. Rules can change, so check the current official version before every contest.
This repository uses a stricter fail-closed policy for general-purpose coding agents to reduce accidental use. During a covered contest, do not use generative AI for problem summaries, algorithms, code, language conversion, code completion, compiler errors, or debugging.
Device-wide contest lock
Before participating in a covered contest, lock AI assistance and open VS Code without extensions:
make contest-lock CONTEST=abc469
make vscode-safe
contest-lock creates two markers:
.atcoder-contest-lockin this repository${XDG_STATE_HOME:-$HOME/.local/state}/atcoder-workspace/contest-lockfor the device
The device-wide marker lets a lock created from the Crystal workspace also block agents in the Ruby workspace on that computer.
If you override its location with ATCODER_GLOBAL_LOCK_FILE, configure the same absolute path in both workspaces.
As a rule, unlock from the same workspace in which you created the lock.
The existence of either marker is authoritative, even if its contents are invalid. Locks never expire automatically. After verifying on the official site that the contest has ended, the user must unlock the workspace:
make contest-unlock
Check both manual lock scopes without network access:
make contest-status
Target-specific automatic check
Compatible agents are instructed to run status and a target-specific check before contest-related work.
You can also run these checks manually:
make contest-check CONTEST=abc469
bin/contest-guard check --contest abc469 abc469/a
bin/contest-guard check abc469/a
The guard compares the official contest page with AtCoder's server time. For ABC, ARC, and AGC it blocks from five minutes before the listed start through twenty minutes after the listed end. It also fails closed when the contest is live, the network fails, the page format changes, metadata conflicts, or the result is indeterminate. AHC and other contest types are never automatically cleared because their rules differ. The check only knows about its specified target and cannot detect your participation in another live contest, so it does not replace the official page or the manual lock.
Disable AI in VS Code
.vscode/settings.json disables built-in AI, GitHub Copilot, and inline suggestions in this workspace.
make vscode-safe opens a new window with code --new-window --disable-extensions, which disables every extension in that window.
These controls reduce accidental use but cannot disable AI in another editor, browser, CLI, desktop app, or already-open window. Before a contest begins, verify every tool you might use.
Installation
This workspace targets macOS and Debian/Ubuntu-based Linux. On Windows, use Ubuntu under WSL.
Install these prerequisites:
- Git
- Python 3.10 or newer
- uv
- Crystal 1.17.0, or asdf capable of installing it
- Homebrew and Xcode Command Line Tools on macOS when setup should install native dependencies
After cloning the repository, run:
make setup
make doctor
make self-test
make setup verifies Crystal 1.17.0 from .tool-versions and installs it through asdf when necessary.
It then prepares GSL, the pinned Shards dependencies, online-judge-tools (oj) for sample tests, and the aclogin login helper.
It follows Brewfile on macOS and uses libatlas-base-dev, libgsl-dev, and pkg-config on Debian/Ubuntu.
On CI images where native packages are already present, use bin/setup --skip-system-dependencies.
make doctor checks the exact Crystal version, Shards, GSL, oj, aclogin, dependency consistency, and an AtCoder-compatible release build that requires every provided shard.
make self-test runs the workspace's regression tests in temporary directories.
AtCoder Crystal 1.17.0 environment
This repository follows AtCoder's available languages and libraries for Crystal 1.17.0.
The nonstandard libraries provided by AtCoder are pinned through shard.yml and shard.lock.
| AtCoder library | Workspace require | Version |
|---|---|---|
ac-library_cr | require "atcoder" | 0.1.0 / commit c57c18d |
avltree | require "avltree" | 0.1.2 |
graphlb | require "graphlb" | 0.1.0 |
crystal-gsl | require "gsl" | 0.2.0 / commit b1fc1b0 |
immutable | require "immutable" | 0.1.24 |
The default prelude for ABCs, ARCs, and AGCs loads only atcoder and avltree.
This makes AtCoder::DSU, priority queues, Fenwick trees, segment trees, lazy segment trees, ModInt, flows, SCC, 2-SAT, prime and string algorithms, plus AVLTree::SortedSet, SortedMap, and SortedMultiset available without more require statements.
Crystal's own prelude already includes Set, Deque, Random, and basic Math.
graphlb, gsl, and immutable remain opt-in because their use cases are more specialized.
Add an explicit require in the solution or a custom library when needed.
They are already installed by make setup, so enabling one later needs no additional setup.
In particular, gsl is not loaded into solutions that do not need its native linkage.
AtCoder builds a Shards project containing main/src/main.cr.
This workspace instead bundles CONTEST/TASK/main.cr and custom libraries into one temporary source, then compiles it against the pinned Shards at the repository root.
AtCoder receives the resulting submission.cr as ordinary Crystal source.
Submission builds use --release --no-debug --no-color -Donline_judge, matching the relevant AtCoder release settings.
By default, local test and run omit release optimization to reduce compile time.
Add --release for a production-style check:
bin/atcoder test abc468/a --release
bin/atcoder run abc468/a input.txt --release
submit always tests the exact bundled source and executable from a release build.
The official command's --quiet option is deliberately omitted locally so compiler diagnostics remain visible.
Browser login and the optional oj cookie
AtCoder protects source submissions with CAPTCHA, so this workspace does not perform the final submission through a raw HTTP request.
When you run submit while logged in to AtCoder in your regular browser, it copies the validated submission.cr to the clipboard and opens the task's submission page.
Confirm the task and language, complete the human verification, and submit in the browser.
Normal browser submission, public task listing, problem scaffolding, sample download, and local testing do not require make login.
Only when an authenticated, read-only oj operation needs its own session, copy the REVEL_SESSION cookie value from your browser and run:
make login
The cookie is stored in oj's user-data directory, never in this repository.
Do not put cookie values in source files, commits, or chats.
Usage
List every task in a contest:
bin/atcoder tasks abc468
Create main.cr files and download samples for the entire contest:
bin/atcoder contest abc468
To create one task, provide a contest ID and task label or a task URL:
bin/atcoder new abc468 a
bin/atcoder new https://atcoder.jp/contests/abc001/tasks/abc001_1
The resulting layout is:
abc468/
├── .contest.json
├── a/
│ ├── .problem-url
│ ├── main.cr
│ └── test/
│ ├── .samples-complete
│ ├── sample-1.in
│ └── sample-1.out
├── b/
└── ...
.samples-complete is an automatically managed marker for a complete sample download.
After writing a solution, use test for official samples and manual cases, or run with standard input.
Both commands compile the bundled solution only once:
bin/atcoder test abc468/a
bin/atcoder run abc468/a
bin/atcoder run abc468/a input.txt
The equivalent Make targets are:
make test TARGET=abc468/a
make run TARGET=abc468/a INPUT=input.txt
Custom libraries
Place custom .cr files under library/.
Subdirectories are supported.
library/00_core/00_contest_dependencies.cr is bundled first, followed by every other library/**/*.cr file in lexicographic order by its complete path relative to library/.
library/
├── 00_core/
│ ├── 00_contest_dependencies.cr
│ └── input.cr
├── 10_data_structure/
│ └── fenwick_tree.cr
└── 20_graph/
└── dijkstra.cr
Dependencies are not analyzed automatically.
When dependencies cross directory boundaries, add numeric prefixes to the directory names as shown above.
Rename a work-in-progress file to something such as .cr.disabled to exclude it.
Names beginning with a dot are also excluded.
Symbolic links are not allowed anywhere below library/.
New main.cr files load library.cr when compiled directly.
test, run, random, bundle, and submit remove that marked local loader and place the latest libraries before main.cr.
They never rewrite the original main.cr.
During random tests, libraries are bundled only with the solution; the generator and oracle remain independent.
00_core/00_contest_dependencies.cr is bundled first and loads the pinned atcoder and avltree shards.
Later custom libraries can therefore use types from both shards directly.
The random-test generator and oracle do not receive this prelude, keeping all three programs from becoming unnecessarily heavy.
When compiling main.cr without a workspace command, invoke Crystal from the repository root so it can resolve the pinned shards:
crystal build abc468/a/main.cr
The regular bin/atcoder test, run, bundle, and submit commands already use the correct working directory.
Libraries may use normal require statements for the standard library or a pinned shard.
Do not use require "./..." or require "../..." to load another custom file, because that path will not exist after single-file bundling.
See library/README.md for the complete bundling notes in Japanese.
Check only the custom library:
bin/atcoder check-library
Manual test cases
Add existing input and expected-output files to the regular test suite:
bin/atcoder add-case abc468/a custom-1 input.txt expected.txt
# or
make add-case TARGET=abc468/a NAME=custom-1 INPUT=input.txt EXPECTED=expected.txt
This creates abc468/a/test/custom-1.in and custom-1.out.
Existing cases are never overwritten.
Random tests
Create a generator and a small-input reference solution:
bin/atcoder init-random abc468/a
Edit random/generator.cr to accept a seed as its first argument and print one input.
Edit random/oracle.cr to read that input from standard input and print the expected output.
The solution, generator, and oracle are each compiled once at startup:
bin/atcoder random abc468/a 1000 1
# or
make random TARGET=abc468/a COUNT=1000 SEED=1
On a mismatch, timeout, or abnormal exit, reproduction input and metadata are saved below random/failures/.
Seeds must fit Crystal's UInt64 range (0..18446744073709551615).
Each process has a 10-second timeout and a combined 16 MiB output limit by default; ATCODER_RANDOM_TIMEOUT changes only the timeout.
Bundling and submission
Create one manually submittable file at abc468/a/submission.cr:
bin/atcoder bundle abc468/a
# or
make bundle TARGET=abc468/a
submission.cr is excluded from Git.
On repeated runs, the command updates only files carrying its generated marker and refuses to overwrite a hand-written file with the same name.
Edit main.cr or library/, not generated output.
Prepare a submission with:
make submit TARGET=abc468/a
Only after bundling, a release build, and all tests succeed does it save submission.cr and hand it to the clipboard and browser.
The command itself does not submit to AtCoder.
Pulling template updates
Repositories created from a GitHub template do not receive source-template updates automatically. Commit every local change so the worktree is clean, then run:
make update-template
On first use, it adds a template remote for the public source repository.
It uses .atcoder-template-version to cherry-pick newer template commits in order, preserving solution and library commits and never pushing automatically.
A conflicting local customization stops as a normal cherry-pick conflict:
# After resolving conflicts
git add <files>
git cherry-pick --continue
# To cancel the entire update
git cherry-pick --abort
Revalidate after an update:
make setup
make doctor
make self-test
When publishing this source template, advance .atcoder-template-version to a new unique value in the final commit of each release batch.
Do not amend or force-push published release commits.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
main- Seen
- Jul 31, 2026
- Crystal
1.17.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/ReiAkidzuki/atcoder-crystal-workspace
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 15, 2026
- Synced
- Aug 15, 2026
- Versions
- 1