MOJ MOJ Melhor Online Judge BETA

Criando e gerenciando contests no MOJ — o guia do organizador

Um contest é uma sala própria: seus problemas, suas contas, seu placar, seu relógio. Tudo aqui existe no wizard web E na CLI (moj contest …) — mesma API, mesmos cortes no servidor. Este é o roteiro de professor para professor, da criação ao relatório final.

1. O ciclo de vida de um contest

criarproblemascontasno arconduzirrelatório
  • O contest entra no ar na hora da criação — quem controla o que o aluno vê é a janela de INÍCIO/FIM (contagem regressiva antes, problemas durante, encerrado depois). Dá p/ preparar tudo com calma com a sala já de pé.
  • Os problemas podem ser privados (modo prova): o contest usa qualquer problema a que você tem acesso — dono, colaborador ou membro da org. Nada vaza antes da largada.
  • As contas são do contest (separadas do treino livre): cada aluno ganha login/senha daquela sala, e só dela.
  • Quem pode criar: conta com a permissão “pode criar” — a mesma da criação de problemas (peça a um admin se ainda não tem; confira com moj whoami).

2. A CLI em 60 segundos

curl -fsSL https://moj.naquadah.com.br/moj -o ~/.local/bin/moj && chmod +x ~/.local/bin/moj
curl -fsSL https://moj.naquadah.com.br/moj-contest -o ~/.local/bin/moj-contest && chmod +x ~/.local/bin/moj-contest
moj login                       # sessão do TREINO — cria contests, templates, export
moj contest create --empty --name "Prova 1 APC" --start "$(date -d 'tomorrow 10:00' +%s)" --end "$(date -d 'tomorrow 12:00' +%s)"

Requisitos: bash, curl, jq — e mais nada (sem mojtools, sem bubblewrap: gestão de contest é API pura). moj contest … delega ao moj-contest; use a grafia que preferir.

DUAS sessões, e este é o tropeço clássico: criar/templates/export/duplicate/list/remove usam a sua sessão do treino (moj login). Administrar um contest (settings, problems, users, news, extend…) exige sessão naquele contest:
moj contest login prova1apc -u ribas.admin   # conta *.admin DO contest
moj contest -c prova1apc settings get        # agora os comandos de admin funcionam
O token fica por contest (~/.config/moj/token-<cid>) — não atropela a sessão do treino. moj update / moj doctor mantêm a CLI em dia.

3. Criar o contest

Web: o wizard em /treino/criar/ percorre dados, problemas, contas, opções, visual e revisão. CLI: um comando, três jeitos de alimentá-lo:

moj contest create --empty --id prova1apc --name "Prova 1 — APC" --start <epoch> --end <epoch>
moj contest create spec.json                 # spec completa em JSON (veja: moj contest export)
moj contest create --template prova-apc --id prova2apc --start … --end …
  • Ao menos um problema, ou --empty. Criar sem problemas responde 422 (no_problems): o --empty é como a CLI diz “configuro os problemas depois” (na web é o botão “Criar vazio (configuro depois)”). A sala entra no ar do mesmo jeito — os problemas entram na seção 4.
  • O id vira o endereço dos alunos: /contest/?c=prova1apc E https://prova1apc.moj.naquadah.com.br. Tem de ser minúsculo (o subdomínio minúscula tudo — id com maiúscula nunca casaria).
  • Reaproveitar vence redigitar: duplicate copia um contest inteiro (problemas, opções — contas NÃO vão junto) e template save --from-contest transforma um contest numa receita nomeada p/ o próximo semestre.
moj contest duplicate prova1apc --id prova2apc --name "Prova 2" --start … --end …
moj contest template save prova-apc --from-contest prova1apc --with-problems
moj contest template list

4. Problemas (e o sorteio)

moj contest -c prova1apc problems add apc#fibonacci           # vira a próxima letra (A, B, …)
moj contest -c prova1apc problems add apc#vetor1 --letter C --name "Vetores I"
moj contest -c prova1apc problems ls
moj contest -c prova1apc problems reorder C A B               # nova ordem das letras
moj contest -c prova1apc problems rm B

Buscar e sortear do banco público — o sorteio filtra por coleção, tag e dificuldade; --seed o torna reprodutível (auditável: mesma seed, mesmo sorteio); --add já coloca o resultado no contest:

moj contest -c prova1apc problems search fibonacci --collection "Olimpíada Brasileira de Informática"
moj contest -c prova1apc problems draw --collections "problemas-apc" --tags vetores,strings \
    --count 5 --difficulty facil --seed 42 --add
  • Restrição de linguagem por problema: problems langs C c,cpp (só C/C++ no problema C); - volta a herdar a lista do contest.
  • Problema privado entra normalmente SE você tem acesso (dono/colaborador/membro da org) — é o fluxo de prova: o problema nunca vira público.
Enunciado, testes e time-limits vêm do PACOTE do problema — o contest só referencia problemas. A autoria é o outro guia: Criando problemas no MOJ (botão na Gestão de Problemas).

5. As contas dos alunos

No wizard: cole a lista da turma (um aluno por linha), clique “processar”, gere as senhas faltantes e baixe o CSV — esse arquivo é o que você distribui (login, senha, nome). Na CLI:

moj contest -c prova1apc users add 231026714 --name "Ada Lovelace" --email ada@aluno.unb.br
moj contest -c prova1apc users ls
moj contest -c prova1apc users reset 231026714        # nova senha p/ um aluno
moj contest -c prova1apc users set-password-all "senha-da-sala"   # lab presencial: uma senha só
moj contest -c prova1apc users disable 231026714      # bloqueia (suspeita de fraude etc.)
moj contest -c prova1apc users logout 231026714       # derruba a sessão ativa
Conta de contest NÃO é a conta do treino livre: ela vive dentro do contest, com senha própria. O aluno logado no treino ainda precisa do login/senha do contest que você distribuiu.

6. Placar: icpc × obi

  • icpcranking por problemas resolvidos; desempates: penalidade, depois último AC. A penalidade é configurável:
    moj contest -c prova1apc settings set penalty_minutes=20 penalty_verdicts=wa,tle,mle,rte,ce
    moj contest -c prova1apc settings set penalty_verdicts=      # vazio = NENHUM veredicto penaliza
  • obiplacar por pontos por grupo (subtarefas): o tests/score do problema define os grupos e o placar soma pontos em vez de contar resolvidos. Como fazer problema com grupos: o guia de problemas, seção “tests/score passo a passo”.

O modo se escolhe na criação (wizard: “Modo / placar”; CLI: na spec/template). Cores de balão e filtros de região do placar ficam no passo “Visual” do wizard.

7. Documentos impressos (info sheet, caderno, time limits)

Toda prova imprime três documentos: as informações do ambiente (versões de compilador, limites de memória/pilha, linguagens aceitas), o caderno da prova (capa + enunciados) e a folha de time limits — e, depois dela, o editorial (a solução de cada problema, tirada do docs/solucao.md dos pacotes; o servidor só deixa publicar depois do fim da prova). O MOJ gera tudo em PDF e HTML, em português e inglês, a partir do que o contest já tem — sem copiar e colar nada. Times só veem caderno e time limits publicados a partir do início da prova; a sede vê antes, para imprimir.

moj contest -c prova1apc docs set caderno_version=v1.0 errata="**C**: onde se lê 10^5, leia-se 10^6."
moj contest -c prova1apc docs gen                      # os 3 tipos, pt+en+es (leva alguns segundos)
moj contest -c prova1apc docs ls                       # o que existe, tamanho, quem gerou
moj contest -c prova1apc docs get all --lang pt        # baixa p/ imprimir
moj contest -c prova1apc docs publish info --lang pt --news   # libera p/ a sede + vira notícia
moj contest -c prova1apc docs upload caderno traduzido.pdf --lang es   # PDF PRONTO: vence o gerado
  • A capa tem três modos, nesta precedência: PDF enviado (docs cover capa.pdf — a arte do evento, entra como está), texto editado (docs text capa --from capa.md, com os marcadores {{CONTEST_NAME}} {{DATE}} {{N_PROBLEMS}} {{N_PAGES}} {{SITES}} {{VERSION}}) ou a capa padrão. O número de páginas impresso na capa é sempre o real.
  • Onde o problema tem PDF próprio de enunciado no contest, é esse PDF que entra no caderno (diagramação preservada); senão o enunciado é renderizado.
  • Publicar faz duas coisas: o documento aparece na seção “Prova” para os times e o chefe de sede (.cstaff) passa a baixá-lo em 📄 Documentos. Antes disso o caderno é conteúdo de prova: a API responde 404 p/ quem não é admin nem juiz-chefe.
  • A sede baixa pela MESMA CLI: moj contest login <cid> com a conta .cstaff, depois docs ls e docs get all — ela só enxerga o que foi publicado. Útil para sede em rede isolada.
  • ⚠️ PT/EN vale p/ capa, títulos e tabelas. O enunciado sai no idioma em que foi escrito — o MOJ guarda um enunciado por problema, não dois.

Tudo isso também está no painel web, em Prova › Documentos (admin e juiz-chefe).

8. Aquecimento e prova oficial (o mesmo contest)

Toda maratona roda um aquecimento (ensaio) antes da prova: dois ou três problemas fáceis para o time ligar a máquina, testar login, editor, impressão e balão — e para os seus juízes e staff ensaiarem. No MOJ isso são rodadas do MESMO contest: mesma URL, mesmo login, mesma configuração. A rodada no ar é a que aparece em Central › Regras e em Prova › Problemas; as outras ficam planejadas até você promover.

Trate o aquecimento como o ensaio geral da operação inteira, não como "dois problemas fáceis". Numa prova no molde do ICPC os times não entram antes do início — o aquecimento é o único momento em que cada papel toca as telas de verdade sem nada em jogo. Entregue antes a cada um o tutorial dele (/contest/ajuda/) e peça que rode a própria lista durante o aquecimento:
PapelO que confere no aquecimento
competidorEntra com a etiqueta que você entregou, abre um problema (enunciado + editor? só enunciado? só PDF?), envia de propósito — inclusive errado —, faz uma clarification, pede uma impressão, guarda um arquivo no backup e acha a própria linha no placar.
.staffImpressora de ponta a ponta, o pop-up liberado para este site (bloqueado = tarefa não marcada), o modo kiosk se for usar impressão automática, e o trajeto do balcão até as mesas.
.cstaffQue todo time da sede entrou pelo menos uma vez — etiqueta que não loga é problema para resolver agora — e que a fila mostra os times dela e só eles.
.judgeAs opções de veredicto são as que esta prova quer, o log e o código abrem na máquina do júri, e a dupla de juízes lê a mesma submissão do mesmo jeito.
.cjudgeNº de juízes por veredicto, a matriz de auto-veredicto e se o alarme de conflito chega mesmo à mesa.
.animeitorO projetor, a chave de webcast rodando no Animeitor para valer, e as fotos e músicas subindo — telão testado com placar vazio é telão não testado.
moj contest -c prova1apc rounds ls                       # rodadas + checklist de promoção
moj contest -c prova1apc rounds set aquecimento --name "Aquecimento" --kind warmup
moj contest -c prova1apc rounds add oficial --name "Prova oficial" \
    --start "2026-09-12 13:00" --end "2026-09-12 18:00" --freeze "2026-09-12 17:00"
moj contest -c prova1apc rounds problems oficial set apc#a,apc#b,apc#c   # a prova de verdade
# … roda o aquecimento …
moj contest -c prova1apc rounds promote                  # arquiva o aquecimento, prova no ar
moj contest -c prova1apc machines --round aquecimento    # time × IP × navegador da sala
  • Promover arquiva a rodada no ar — submissões com código-fonte, veredictos, log do juiz, placar, estatísticas, clarifications, notícias, tarefas do staff e logs de acesso ficam em rounds/<rodada>/, mais um relatório navegável —, zera o placar e aplica a janela e os problemas da rodada seguinte.
  • A lista de problemas da rodada oficial fica guardada e só entra no ar na promoção: ninguém vê os problemas da prova durante o aquecimento.
  • Ele recusa promover enquanto houver job na fila do juiz, veredicto pendente ou correção manual aberta — uma submissão julgada depois da troca teria o tempo calculado contra o início novo e reapareceria no histórico da prova. O rounds ls lista os bloqueadores.
  • O que não muda: contas e senhas, times/sedes/bandeiras, escopo do staff, cores de balão, time limits calibrados, linguagens, pool de juízes, matriz de auto-veredicto e os textos dos documentos. O que zera: placar, histórico e submissões dos times (arquivados, não perdidos), balões, numeração de impressão e prorrogações por sede.
  • Os documentos publicados deixam de estar publicados. Os modelos e a capa sobrevivem (são configuração) e os PDFs do aquecimento vão para o arquivo — mas a marca de publicado some. O info sheet, o caderno e a folha de time limits têm de ser publicados de novo na prova oficial, ou os times abrem Arquivos & Recursos e não acham nada.
  • O que times e espetáculo levam consigo na promoção, além da lista acima: as fotos e músicas dos times (são da conta, não da rodada) e as chaves de webcast do telão. Quem recolheu no aquecimento não recolhe de novo.
  • O time vê uma faixa fixa dizendo que é AQUECIMENTO e que aquele placar não é o da prova; depois, a rodada encerrada continua legível (publique-a para os times verem).
  • O aquecimento é quando os times ligam de fato os computadores da sala — então é ali que o MOJ mapeia time × IP × navegador (machines). Na prova, quem loga de outra máquina fica marcado; do mesmo mapa você preenche a sede dos times e arma o gate de navegador.
Se você seguir o modelo do ICPC — login abrindo no minuto do início (settings set login_start=<epoch>, ou login_lead no template) — o time não tem como ver nada disso antes. Aí o aquecimento não é cortesia: é o único ensaio que existe, e pular significa gastar a primeira meia hora da prova descobrindo as telas.

Na web: Prova › Rodadas e Pessoas › Máquinas & gate do painel de administração.

9. Durante a prova

moj contest -c prova1apc dashboard      # visão geral ao vivo (pendências, juízes, alertas)
moj contest -c prova1apc sessions       # quem está logado (IP, navegador)
moj contest -c prova1apc score          # o placar, no terminal
moj contest -c prova1apc news add "Atenção" "O problema C teve o enunciado corrigido."
moj contest -c prova1apc extend +15                       # prorroga p/ TODOS
moj contest -c prova1apc extend +15 --group '^lab2-' --reason "queda de luz na sala 2"
moj contest -c prova1apc audit 50       # trilha de auditoria (quem fez o quê)
moj contest -c prova1apc access         # log de acessos do dia
  • As clarifications (dúvidas dos alunos) são respondidas no admin web do contest — o mesmo lugar onde o staff cuida de impressão e balões (ver o manual do staff).
  • O extend --group prorroga só os logins que casam a regex — prorrogação por sala/sede sem mexer no resto.
  • Pool de juízes: settings set judges=cpu1,cpu2 prende quais juízes atendem o contest (vazio = qualquer juiz online); problems judges D host1 prende por problema.

10. Depois da prova

moj contest -c prova1apc report prova1.html    # relatório completo (submissões, placar, estatística)
moj contest export prova1apc spec.json --full  # a spec (sem credenciais) p/ versionar/reusar
moj contest template save prova-apc --from-contest prova1apc --with-problems
moj contest remove prova1apc                   # tira do ar (sessão .admin do TREINO; história preservada)

Depois do fim a sala continua visível (encerrada) no arquivo /contests/; os alunos podem rever as próprias submissões. O remove tira do ar quando é isso que você quer.

11. ⚡ Comandos rápidos

ComandoO que faz
moj contest create [spec|--template N] [--id --name --start --end] [--empty]cria (no ar na hora; INÍCIO/FIM controlam a visibilidade; --empty = ainda sem problemas)
moj contest list · show <cid>seus contests · resumo de um
moj contest login <cid> [-u login]sessão de ADMIN naquele contest (necessária p/ tudo abaixo)
… -c <cid> problems add|rm|ls|reorder|langs|judgesos problemas (letras, ordem, linguagens/juízes por problema)
… -c <cid> problems draw --collections … --seed N --addsorteio reprodutível do banco público
… -c <cid> users add|ls|reset|rm|disable|logout|set-password-allas contas (locais do contest)
… -c <cid> settings get|set k=vopções: penalty_minutes, penalty_verdicts, judges, manual_verdict, review_judges (quantos juízes validam, 1–5)…
… -c <cid> extend +min [--group re]prorroga (todos ou uma sala/sede)
… -c <cid> dashboard · sessions · score · audit · accessoperação ao vivo
… -c <cid> news add|ls|rmavisos p/ a sala
… -c <cid> rounds ls|add|set|problems|promote|publish|archiverodadas: aquecimento e prova oficial no mesmo contest (promover arquiva tudo e zera o placar)
… -c <cid> machines [--round R] [--csv]time × IP × navegador de uma rodada; marca quem trocou de máquina
… -c <cid> docs gen|ls|get|publish|cover|upload|set|textdocumentos impressos: info sheet, caderno (capa customizável) e folha de time limits, PDF+HTML, pt/en/es — ou suba o PDF pronto, que vence o gerado
… -c <cid> report [arq]relatório final
moj contest export|duplicate|template …reúso: spec, cópia, receitas nomeadas
moj contest remove <cid>tira do ar (sessão .admin do treino)

12. 💡 Dicas & armadilhas (aprendidas na prática)

  • Id de contest minúsculo, sempre — ele dobra como subdomínio, e subdomínio não tem maiúscula.
  • “admin_required” num comando de admin? Você está na sessão do treino. Rode moj contest login <cid> antes — as duas sessões coexistem.
  • 422 “Inclua ao menos um problema (ou marque criar vazio)” (no_problems) no create? O contest nasceu sem problemas: passe --empty (ou liste problems[] na spec). Acrescentar problemas depois não tem restrição nenhuma — funciona com o contest já no ar.
  • Teste um login de ALUNO antes da prova: abra a URL do contest numa janela anônima com uma linha do CSV. Cinco minutos que salvam a primeira meia hora da prova.
  • Problema de prova: mantenha privado numa org sua; o contest o usa sem nunca publicar. Publicar no treino livre é decisão de DEPOIS da prova.
  • O sorteio com --seed é a sua trilha de auditoria: registre a seed e qualquer um re-executa o mesmo sorteio.
  • `penalty_verdicts=` vazio significa “nada penaliza” — útil em treinos; os contests legados migrados usam wa,tle,mle,rte,ce.
  • langs -/judges - (um traço) devolve o problema à herança das linguagens/pool de juízes do contest.
  • Distribua aos alunos o manual do competidor e o guia da CLI moj-comp — a CLI sobrevive a queda de Internet: a submissão fica empacotada com carimbo assinado e conta no horário certo quando a rede volta.

13. Referências

← o wizard de criação · Criando problemas (o outro guia) · Manual do competidor (distribua aos alunos) · Manual do staff · Tutoriais de papel (entregue um a cada pessoa) · Documentação completa