Published on
· 11분 읽기

ICPC Sinchon 26S 공동 캠프장 & 운영 후기 (1)

Authors
  • avatar
    Name
    GreenScreen410
    Twitter
D+1로 바뀌었습니다.

1부: 알고리즘 캠프 운영

두 번째 블로그 글입니다. 2026년 상반기동안 진행된 ICPC Sinchon 26 Summer의 공동 캠프장으로 활동하며 있었던 일들을 적어보고자 합니다.
정말 수많은 일들이 있었지만 그 속에서 끝까지 함께 운영해 준 운영진 분들, 그리고 무엇보다 같은 공동 캠프장이었던 Annyeong1에게 큰 감사 인사를 드립니다. :blobcheer:

솔직히 저는 PS도 잘 못하고, Annyeong1처럼 인맥도 넓지 않습니다. Annyeong1은 이번 이야기를 블로그 10부작으로 해도 모자를 것 같다고 합니다.

SUAPC를 주최하는 ICPC Sinchon은 1년에 두 번, 알고리즘 캠프와 오프라인 대회를 운영하고 있는 단체입니다.
이러한 PS 단체는 전세계적으로 봐도 흔치 않다고 생각하며, 이 어려운 분위기 속에서 이번에도 이것들을 잘 해내야 했습니다. 적어도 제가 있을 때는 망하면 안되기 때문에..

저는 개발, 후원, 장소, 서류, 그리고 Dify 해커톤과 같은 대외 업무 쪽을 주로 맡게 되었습니다. 굳이 역사와 전통의 PS 대회인 SUAPC에 무슨 LLM 블록코딩을, 그것도 1시간이라는 애매한 시간을 넣었냐 하실 수 있는데, 이것에 대해서는 아마 3부? 4부 쯤 작성할 것 같습니다.

아무튼! 3월부터 8월 25일까지 진행된 그 속의 일들을 하나하나 풀어 나가보도록 하겠습니다.
뭔가 많은 얘기를 공개적으로 할 것 같은데 신촌 연합은 여러분을 환영합니다. PS 행사나 대회를 주최하고 싶으신 분들에게도 도움이 될진 모르겠지만, 도움이 되었으면 좋겠습니다.

이야기의 첫 시작은 알고리즘 캠프 운영입니다.

시즌의 시작과 강사 섭외

3월 28일, 각 학교 학회장 회의를 진행하게 되며 공식적인 26S 일정이 시작되었습니다.
회칙 제정, 올해 새로 연합에 합류하게 된 한양대 이야기, 각 학회의 26년 일정, 인원 보고 등, 현황을 서로 공유하는 자리입니다.
두 캠프장이 모두 바빠 예년보다 늦게, 그것도 중간고사 시즌에 부르게 되어 조금 죄송한 마음도 있었습니다.

초급/중급 강의 강사를 구해야 하는데, 일단 같은 선린 동기였던 gubshig에게 DM을 보냈습니다. 절대 납치가 아닙니다.
다행히 수락을 하였으며, 초급 강사는 gubshig, 중급 강사는 qvixnh22 이렇게 모시게 되었습니다.

아니 ICPC World Finalist의 강의를 들을 수 있는 순간인데 이거 안 들을 수가 없겠죠?
하지만 이때까지만 해도 4월 15일에 무슨 일이 일어날지 몰랐으니...

사라져버린 플랫폼

네, 백준이 완전히 사라져 버렸습니다.
저는 이 소식을 낮잠 자려고 누우려는 그 순간에 들었습니다. 그냥 몇 주동안 아무 일에도 집중이 안되고 정말 슬펐습니다. 스트릭도 1184일 쌓았었는데..

아니 이게 미래를 보여줄 줄은..

역사적으로 알고리즘 캠프는 백준의 그룹 기능을 사용하여 거기에 해당 주차 문제를 업로드하는 방식으로 진행되었습니다.
초급 강의의 경우 알고리즘에 처음 입문하는 분들이 수강하시는 경우가 많아 친숙한 플랫폼에서 하는 것도 중요하다 생각했는데, 정말 앞이 막막했습니다.

이 영향일까, 실제로 작년에는 내부인(신촌 연합 소속) 수강생이 59명이었지만 이번에는 39명, 저번 시즌에 비해 20명 줄어들었습니다.
하지만 알고리즘 캠프를 여는 것을 굳이? 내부인에게만 한정할 필요는 없을 것 같아 이번에 최초로 외부인 신청 폼을 열었는데, 덕분에 64명이 신청하게 되며 저번 시즌 신청자 수를 뛰어넘었습니다.
이런 힘든 상황 속에서도 신청해 주신 분들, 좋은 강의를 진행해 주신 gubshig님, qvixnh22님께 정말 감사드립니다. 🛐🛐

이렇게 생긴 사이트도 있습니다. 하지만 과연 입문자 분들이 이 UI에 잘 적응하실지는 모르겠습니다.

캠프 자동화

원래 개발 분야에 있다가 PS에 입문하게 된 케이스다보니, 단순 반복 업무는 최대한 자동화하면 좋겠다는 생각을 항상 하였습니다.

강의를 못 들었을 경우를 대비하여 수강권을 지급하는데, 이것을 관리하기 위해서는 출석 기능이 필요하였습니다.
여태까지는 운영진 한 명이 강의가 있는 날마다 디스코드 음성 채널에 들어가서 접속 인원을 스크린샷 하고, 그걸 기록하는 방식을 사용했었는데 이거 진짜 너무 번거롭잖아요!

그래서 냉큼 디스코드 봇을 만들었습니다.

초급은 15시 15분, 중급은 17시 15분에 봇이 알아서 각 분반 음성 채널을 들여다보고, 접속해 있는 사람의 디스코드 유저 ID를 전부 긁어옵니다.
그리고 출결 시트에서 오늘 날짜 열을 찾아 출석이면 1, 결석이면 0을 적습니다.

function findTodayColumn(sheet: GoogleSpreadsheetWorksheet): number {
  const kst = new Date().toLocaleDateString('en-CA', { timeZone: 'Asia/Seoul' }); // YYYY-MM-DD
  const [y, m, d] = kst.split('-').map(Number);
  const todaySerial = Math.round((Date.UTC(y, m - 1, d) - Date.UTC(1899, 11, 30)) / 86_400_000);

  for (let c = 0; c < sheet.columnCount; c++) {
    const value = sheet.getCell(0, c).value;
    if (typeof value === 'number' && Math.round(value) === todaySerial) return c;
  }
  return -1;
}

기록이 끝나면 위 사진과 같이 출석과 결석 명단을 보고용 채널에 올려줍니다. 이제 운영진이 스크린샷을 찍을 일이 없어졌습니다!

봇 구현에는 Bun + discord.js를 사용하였으며 이 외의 별도의 프레임워크는 쓰지 않았습니다.
물론 중간에 한 번 통째로 갈아엎기는 했습니다. 로깅 라이브러리도 빼고 그냥 console.log로 돌아갔습니다.

강의 진행

gubshig님은 매 수업시간 전마다 pdf 강의 자료를 디스코드 채널에 업로드 하셨으며, qvixnh22님은 가지고 계신 패드에 자유롭게 판서를 하시며 해당 화면을 공유하는 방식으로 진행하셨습니다.

일단 23112^{31} - 1개의 수강권을 부여하여 자유롭게 테스트 할 수 있도록 합시다.

이렇게 자동화는 어느 정도 되는 듯.. 싶었는데 아직 해결하지 못한 영역이 하나 있었습니다.
수강권을 제공한다? -> 영상 자료가 있다? -> 누군가는 1시간동안 화면을 녹화해야 한다? 네, 바로 녹화입니다.
사실.. 이걸 구현해 보려 했는데, 디스코드 셀프봇, 영상 전송 프로토콜, 패킷 감지, 암호화 및 복호화 등 뭔가 엄청나게 복잡한게 많다는걸 알게 되고는 미해결 과제로 남게 되었습니다.

아마 다음 시즌에 어떤 뛰어나신 분이 만들어 주시겠죠?