늦은 회고

2023년 회고

올해 커버 사진은 국외입니다. 일본 삿포로 시 스스키노 거리의 사진입니다.

아마 살면서 가장 자주 출국했던 해였던 것 같습니다(4회). 연간 회고로서는 처음으로 국외 사진을 쓰는 건가 싶었는데, 2021년 회고가 러시아에서의 사진이었던 걸 잊었습니다. 맥도날드가 있던 시절의 러시아도 참 좋았는데요…. 지금은 유감스럽게 되었지만요.

바쁜 연말 중에 글을 작성하다 보니 회고도 늦어버렸습니다. ‘올해’라는 표현과 ‘작년’이라는 표현이 섞여서 등장할 수도 있을 것 같습니다. 적당히 잘 이해해 주시면 감사하겠습니다.

정신없었던 한 해

최고로 정신없는 한 해였던 것도 같습니다. 평소에도 바쁘게 살지만 올해는 특히 정말 너무 바빴습니다. 할 일이 끊이지 않았습니다.

작년에서 올해로 넘어오면서 ‘학생은 시간이 많으니 올 한 해는 솔브드를 키워 보자’는 생각을 했던 것 같은데, 학생도 학생 나름인 것 같습니다. 학점을 어느 정도 챙기려고 하다 보니 다른 걸 못 하게 되고, 다른 걸 하려다 보니 학점이 안 나오는 다소 난감한 상황이 지속되었습니다.

1학기에는 ‘에이 나는 회사도 갔다 왔는데~~ 학교 별 거 없겠지~~’ 하고 22학점을 신청했다가 큰 코 다쳤습니다. 전공 7개 교양 1개를 들었는데요, 학교 과제만 해도 다른 걸 할 수 없을 정도였습니다. 덕분에 최초로 3점대 수호(2.96)에 실패하는 학기가 되었습니다.

회사에서는 제 업무가 많아서 제 시간에 끝낼 수 없어 보이면 그나마 ‘일이 많습니다’ 라고 하고 듀를 조절하거나 할 수 있고, 그 전에 ETA를 제가 정해서 말할 수 있었는데요, 학교는 얄짤없었습니다. 교수님들은 제가 3과목을 듣든 7과목을 듣든 같은 양의 과제를 내 주십니다. 심지어 과제가 언제 나올지도 모릅니다. 그 과정에서 패배하는 건 저 말고는 없습니다. ㅎㅎ.. 교양을 섞던가 해서 조금 더 나은 로드의 시간표를 짰으면 좋았을 것 같다는 아쉬움이 남습니다.

2학기에는 1학기의 여파로 평점이 3.50 아래로 내려가는 바람에 21학점 이상을 신청할 수 없었기 때문에 18학점만 들었습니다. 아직 한 과목이 성적이 고지되지 않기는 했는데요, 그래도 선방해서 3.54입니다. 예전에 18학점을 듣고 번아웃이 왔던 적이 있는데 22학점에 비해서는 18학점은 할 만 한 수준인 것 같습니다.

이제 졸업까지 21학점만을 남겨두고 있습니다. 서강대학교는 정규학기에는 9학점 이상을 등록해야 되기 때문에 아마 7학기 12학점, 8학기 9학점을 듣게 될 것 같습니다. 올해 했던 고생으로 내년에는 고생하지 않기를 바랍니다.

별개로 해킹및정보보안 수업을 정말 재밌게 들었던 것 같습니다. CTF 재밌을지도…?

학교로 돌아왔다면 할 것은 하나

학부 재학생 신분이 되었다면 학부 재학생다운 일을 해야 하는 것은 당연합니다. ICPC 리저널에 국내 1회, 해외 1회를 채워서 출전하는 것보다 학부 재학생다운 일은 없습니다. 올해는 여전히 Redshift로, semteo04lem0nad3과 함께 출전했습니다.

ICPC에 출전하기 전에 합을 맞췄던 SUAPC 2023 Summer에서는 1위를 달성했습니다. 덕분에 1위를 달성해 본 대회가 두 개가 되었습니다.

이후 출전한 서울자카르타 리저널에서는 각각 19위와 15위를 달성했고, 내년 3월에 열릴 아시아태평양지역 챔피언십에 22순위로 진출하여 다음 대회를 준비 중입니다.

리저널 등수 목표는 15위였고, 신촌 결과로 의기양양해져서 내심 그것보다 높은 순위를 기대하고는 있었는데, 자카르타에서는 정확히 15위를, 서울에서는 15위보다 못 미치는 성적을 거뒀습니다. 목표 등수를 달성했던 자카르타에서도 낮은 페널티에 비해 2시간 19분 이후에 한 문제도 풀지 못한 것이 아쉬움으로 남았습니다. 한 문제라도 풀었으면 메달을 목에 걸고 돌아왔을 텐데요.

개인적으로 2019년 당시 Redshift의 강점은 1주 2회 정도의 잦은 연습에 있었다고 생각하는데요, 저도 그렇고 직장인이 된 semteo04도 시간이 많이 없어져서 1주 1회 연습도 돌리기 힘들 정도가 되었던 게 아쉬운 결과의 원인이었다고 생각합니다. 다만 이번 두 대회에서의 성적이 아쉬웠다는 것은 베트남에서 아쉽지 않게 대회를 치면 월드 파이널에 진출할 가능성이 없지 않음을 의미할지도 모르겠습니다. 쉬운 문제를 빠르고 정확하게 푸는 데는 자신이 있으니, 어려운 문제를 풀 수 있도록 열심히 준비해 보려고 합니다!

한 해 동안 고생했고 2월까지 같이 고생할 팀원들, 그리고 관심과 지원을 아끼지 않아 주신 이주호 교수님께 이 자리를 빌어 감사를 전합니다.

솔브드

한국 경쟁 프로그래밍 커뮤니티에서는 정말 많은 양질의 문제들이 출제되고 있다고 항상 생각해왔습니다. 알고리즘 학습자들이 경쟁 프로그래밍에도 재미를 붙이게 하고, 한국 커뮤니티에서 출제되는 문제들에 스포트라이트를 비출 수 있도록 올해는 아레나 대회아레나 레이팅을 도입했습니다. 오랫동안 계획만 했던 솔브드 공식 대회(그랜드 아레나)도 아레나 시스템 하에서 세 번 개최했습니다.

또한 결제 모듈의 도입을 바탕으로 솔브드 서포터를 도입하고, 굿즈 샵을 열었습니다. 아쉽게도 제가 굿즈 샵에서 큰 실수를 했고, 대규모 DDoS를 맞기도 해서 올해는 흑자와는 조금 거리가 있기는 합니다.

4월에는 무려 구데기컵 × solved.ac 콜라보레이션 카페가 합정에서 열렸습니다. 정말 상상 이상으로 많은 분들께서 와 주셨습니다. 대기가 너무 길어져서 죄송할 따름이었습니다. 브론즈 5 빨리 풀기 대결에서는 와이파이가 불안정한 게 가장 큰 변수였습니다.

많은 분을 만나뵐 수 있어서 즐거웠고 이후 비슷한 행사를 자주 마련할 수 있게 되면 좋겠습니다. 먼 길 와 주셔서 감사합니다!

5월에는 Bronze V 이상 유저가 10만 명을 넘는 고무적인 일도 있었습니다! 글을 쓰고 있는 시점에서는 12만 1천 명으로, 빠르게 늘어나고 있습니다.

이런 일들도 했습니다.

  • 올해 목표였던 Prisma로 마이그레이션 및 Redis 등의 캐시 레이어 도입을 해냈습니다. 웹 서버가 꽤 안정적이게 되었습니다.
  • 특히 올해 예기치 못한 DDoS를 통해 많은 백엔드/아키텍쳐 지식을 배웠습니다. 맞으면서 배우면 효과적입니다.
    • 우선 DDoS 공격이 랭킹 페이지의 쿼리가 느렸던 것에서 어느 정도 기인했기 때문에, 랭킹 페이지를 꽤 빠르게 동작하도록 개선했습니다. 2,000번째 페이지를 로드하는 데에 예전에는 2초 가량이 걸렸다면 지금은 0.1초 근처의 시간만이 소요되고 있습니다.
    • Redis를 도입하고 캐싱을 공격적으로 했습니다. 자주 액세스되는 데이터는 거의 전부 Redis 레이어를 추가한 것 같습니다.
    • 메시지 큐를 더 잘 활용하도록 했습니다. 예를 들어, 강제 갱신 요청을 메시지 큐로 보내고 별도 워커가 처리하게 한 뒤, 알림 기능을 만들어서 강제 갱신이 끝나면 사용자가 알림을 받을 수 있도록 했습니다.
    • 동시접속자 수에 대한 보수적인 고려를 하면서 설계하는 경험은 나중에 아레나 대회를 기획할 때 사람이 몰려도 빠르게 로드되는 아레나 스코어보드를 만드는 데에 많은 도움이 되었습니다. (클라이언트 입장에서도 BOJ 스코어보드보다 훨씬 빨리 로드됩니다!)
  • 움직이는 프로필 배경을 만들었습니다. 다만 용량 및 트래픽 비용 문제로 공격적으로 추가하지는 못하고 있습니다.
  • 영어일본어 버전 솔브드도 생겼습니다. 영어 사이트를 준비해 놓은 덕분에 아레나 대회가 생기고 Codeforces에 아레나를 홍보할 수 있었습니다.
  • 서포터 전용 기능으로 북마크가 추가되었습니다.
  • 아레나 개최 매뉴얼 및 부록으로 비공식 testlib.h 문서를 만들었습니다. 아레나 개최를 위한 매뉴얼이지만 일반 대회를 개최할 때에도 참고하기 좋도록 작성하려고 노력했습니다.

‘솔브드로만 먹고살 수 있을까?’를 검증하는 2년 중 1년이 갔는데, 현 시점만 놓고 보면 ‘아니다’ 쪽에 가깝기는 합니다. 다만 올해는 다른 일로 너무 바빴고, 만들고 싶었던 것들과 계획했던 것들 – 특히 길라잡이와 추가 서포터 기능들 – 을 다 만들지 못해 상당히 아쉬웠습니다.

내년에는 꼭 길라잡이 및 여러 생각했던 기능들을 만들고 싶습니다. 솔브드로 먹고살고 싶으면 이건 꼭 해야 하는 작업들에 가까워서, 어떻게든 만드려고 노력하게 될 것 같습니다. 솔브드의 여러 일들을 항상 가까이서 도와주시는 havana723님, cologne님, jh05013님, gs18115님, kipa00님 및 나열할 수 없는 수많은 분들께 항상 감사드립니다. 솔브드를 사랑해 주시는 모든 분들께도 정말 감사드립니다!

대회 운영, 출제, 참가

올해는 바빠서 문제 아이디어도 많이 내지 못했고, ICPC를 제외하고는 대회 참가도 적었습니다. SCPC를 나간 이래로 본선에 진출하지 못한 첫 번째 해였는데, SCPC Round 2 날이 JUNCTION ASIA 2023과 겹쳤던 게 컸습니다. 그렇다고 JUNCTION ASIA에서 수상을 한 것도 아니었기 때문에 다소 씁쓸하게 되었네요.

다만 대회 검수는 많이 했는데요, 솔브드에 아레나 대회가 생기면서 아레나 대회 대부분의 검수를 진행했습니다.

모든 아레나 대회를 꼼꼼히 검수하지 못했던 것은 아쉽다고 생각합니다(리스트되어 있지 않은 아레나들은 저 이외의 다른 분께서 꼼꼼하게 봐 주셨습니다). 지금 생각해 보면 대회가 2주에 하나 정도 주기로 열렸는데 8월부터 저 정도의 검수를 했다니 바쁠 만도 했을 것 같습니다.

솔브드 측 검수자는 솔브드가 따로 검수비를 지급합니다. 솔브드가 덜 영세해져서 더 많은 검수자를 섭외하고 더 많은 검수비를 드릴 수 있기를 희망해 봅니다.

소소하게는, 올해 어쩌다가 메이플스토리의 강원기 전 디렉터님을 뵐 기회가 있었는데 메이플컵 문제들을 직접 보셨다고 말씀하셔서 놀랐던 기억이 남습니다.

메이플컵은 출제 과정에서 메이플스토리 IP 사용을 위해 넥슨 검수를 거쳤는데요, 검수 과정에서 문제들을 확인하셨던 것 같습니다. 특히 〈헤카톤〉 문제를 언급해 주셔서 개인적으로 영광이었습니다. 문제에서 헤카톤을 공격하고 있던 싶프트(270레벨 아크)가 디렉터님의 기억에 남았을지는 잘 모르겠습니다.

타대생 난입 이벤트

고연전에 참가했습니다. 엥?

정말 어쩌다가 〈리듬게임 고연전〉의 운영으로 참가했습니다. 디자인을 하고, 대회 엔트리 시스템을 만드는 데에 힘을 쏟았습니다. 처음 Vercel을 써서 올려 본 Next.js 프로젝트였는데, 역시 Next.js는 Vercel에서 돌리라고 만든 프레임워크라는 걸 느끼게 되었습니다.

DJMAX 예선 및 오픈 콘테스트 선곡도 반쯤 제가 했습니다. 초안을 짜고 Jakads님께 검수를 받았는데, 최종적으로 과제곡에 〈Your Own Miracle〉 5B SC가 들어가게 된 건 다소 유감이지만 저의 100% 책임은 아닌 듯 합니다.

3D로 봅니다

올해도 디자인을 했습니다. 그래픽 디자인은 점점 취미의 영역이 되어가는 것 같다고 느낍니다. 하지만 하고 싶은 건 해야 되기 때문에 올해는 블렌더를 익혀서 3D를 활용한 디자인을 시도했습니다.

비교적 간단한 작업으로 뿌슝빠슝 배경들을 빠르고 쉽게 만들 수 있어서 좋은 것 같습니다. 그렇다고 3D 작업에 익숙해진 건 아니고, 디자인 아이디어가 생각나면 구현에 필요한 단계들은 매번 새로 찾아보게 되는 것 같습니다.

한별이

작년에 이어서 한별이 이모티콘이 나왔습니다! 영광스럽게도 수조님께서 그려주셨습니다. 이번에는 은하도 같이 있어요.

한별이는 제가 2014년에 그림 그리는 걸 배우고 싶어했을 적에 디자인했던 캐릭터인데요, 시간이 흐르면서 등장 빈도가 점점 줄다가 만우절에 솔브드에 깜짝 등장한 이후로 havana723님의 사랑에 힘입어 많은 그림이 탄생했고, 다시 전성기를 누리고 있습니다. 사실 솔브드 캐릭터는 아니고 제 개인의 캐릭터이긴 한데 이제는 솔브드를 떼고 생각할 수가 없게 되었습니다. (뭔가 적으면서도 신나서 이야기가 길어지는데 한별이의 히스토리와 여러 설정들에 대해서는 나중에 더 자세히 이야기할 기회가 있으면 좋겠습니다)

출국을 가장 많이 했던 해

올해는 출국을 정말 많이 했습니다. 공항에 무려 4번 다녀왔습니다.

  • 2022년 12월 30일 — 2023년 1월 1일: 일본 도쿄 (시부야)
  • 1월 28일 — 1월 31일: 일본 도쿄 (츠키지)
  • 11월 17일 — 11월 20일: 일본 홋카이도
  • 12월 1일 — 12월 4일: 인도네시아 자카르타

네 번의 여행 중에 일본을 세 번이나 갔습니다. 아마 ICPC 서울 리저널이 요코하마 리저널과 겹치지 않았으면 네 번 가게 되었을 것 같습니다. 확실히 일본은 부담없이 다녀오기 좋은 나라인 것 같습니다.

타국에서 보내는 첫 새해입니다. 아사쿠사에서 뽑은 2023년의 운세는 ‘흉’이었군요. 정말 그랬을까요?

도쿄에 올 때마다 시부야를 오게 되는 것 같습니다. 이제는 거리 자체가 꽤 익숙해질 정도가 되었습니다. 이전에 마지막으로 도쿄에 왔을 때는 2019년이었는데, 당시 공사중이었던 시부야 스크램블 스퀘어가 2023년에는 완공되어 있었습니다.

시부야 도전과제 중 하나인 ‘스크램블 교차로 스타벅스에서 말차 프라푸치노 마시기’를 달성했습니다. 〈최애의 아이〉에도 나온 그 스타벅스입니다.

홋카이도에도 노트북을 가져갔지만, 여행 내내 한 번도 열지 않았습니다. 대신 모든 걸 잊어버리고 푹 쉬다 오기로 결심하고 열심히 쉬다 왔습니다.

격무로 고생하다가도 온천에 오면 피로가 녹아내립니다. 처음 와본 온천은 너무 만족스러워서, 주변에 별 건 없었지만 여기서만 일주일을 묵고 싶을 정도였습니다. 온천 근처에 있던 광활한 건물이 대형마트라는 걸 빨리 알았으면 조금 더 좋았을 수도 있었겠어요.

삿포로 시내의 오락실에서는 E ・ S ・ M 인형을 뽑았습니다. 또 삿포로의 패밀리마트, 로손과 세븐일레븐에서 편의점 치킨을 하나씩 사먹어 봤습니다. 편의점 이름을 따 ‘패미치키’, ‘L치키’, ‘나나치키’였는데요, 분명 세 치킨이 모두 맛에 차이가 있었는데 정작 지금 글을 쓰면서는 어떤 치킨이 어떤 맛이었는지 하나도 기억이 나지 않네요.

비 예보가 있던 자카르타였지만 비가 오지는 않았습니다. 우산을 가져올 필요가 없었습니다. 안개가 낀 자카르타는 일본이나 한국보다 훨씬 사이버펑크스러운 곳일지도 모르겠습니다.

좁은 골목길을 누비는 수많은 오토바이와 자동차들, 스크린도어가 있는 버스 플랫폼, 택시처럼 영업하는 1인승 오토바이가 있는 인도네시아는 마치 다른 세상처럼 보였습니다. 쇼핑몰에 자리잡은 굽네치킨과 파리바게뜨를 보고 잠시 신기하다고 생각하기도 했습니다.

최초의 생일 파티

구데기컵 카페가 열렸던 곳에서 제 생일 파티 카페가 열렸습니다. 저는 생일파티를 한 번도 해본 적 없는데 havana723님께서 열어주셨습니다.

먼 길 찾아와 축하해 주셔서 정말 감사했습니다!

많은 분들께 성대한 축하를 받아 본 건 처음이었습니다. 남겨주신 방명록과 선물들은 계속 소중히 간직하고 있습니다! 정말 소중한 기억으로 남게 될 것 같습니다. 매년 최고의 생일 축하가 갱신되는 것 같아 항상 감사한 마음입니다.

생일 카페에서는 ‘시프트 영역’ 모의고사가 배부되었는데요, 문제가 궁금하셨던 분들을 위해 이 글을 빌려 공개합니다. 최고점은 70점 근처였던 것 같습니다. 아래에 답지도 공개하니 혹…시라도 제 TMI가 궁금하시다면 재밌게 참고해 주시면 감사하겠습니다. 모든 문제의 답은 2023년 8월 5일 기준입니다.

또 이렇게 많은 분들을 만날 기회가 있으면 좋겠다고 항상 생각하고 있습니다. 생일 카페는 제가 준비한 건 아니었지만 항상 오프라인 이벤트들을 기획하고 준비하면서 기대하는 부분이 되는 것 같아요.

즐겁게 살기

올해는 마이마이를 열심히는 못 했는데요, 그래도 이사를 오면서 오락실이 다소 가까워진 관계로 작년보다는 자주 갔던 것 같습니다. 1년동안 레이팅을 15310에서 15545로 올렸습니다. 이제 14레벨에도 SSS+가 조금씩 생기기 시작하네요.

반대로 메이플스토리는 현생이 바쁜 관계로 열심히 못 했습니다. 새로 생긴 전투력 지표만 놓고 보면 여태까지 안 돌았던 좀 더 높은 레벨들의 주간 보스들에 도전할 수 있을 것 같고, 지금 제 상태에서 더 강해지는 가장 좋은 방법은 검은마법사 파티에 들어가서 제네시스 무기 해방을 시작하는 것일 텐데요,

둘 다 어찌저찌 스펙은 될 텐데 아쉽게도 파티를 구하거나 보스 연습할 시간이 따로 없었던 것 같습니다. 그렇다고 대리 플레이를 맡기는 건 또 게임을 즐기는 방법이 아니라고 생각해서 안 했던 것 같아요.

마작은 3마 작호와 4마 작걸을 갔습니다. 분명히 승단 인증서를 캡쳐해 뒀었는데 어디 갔는지 모르겠네요.

지인들께서 자주 방문하는 바 포:루가 집에서 불과 500미터 거리라는 사실을 알게 되었어요.

로컬 칵테일 바는 이미 알고 있는 곳이 몇 곳 있었는데 이곳은 술 잘 모르는 제가 체감할 수 있을 정도로 다른 곳과는 (좋은 쪽으로) 다른 칵테일을 경험할 수 있는 곳이라고 느낍니다. 특히 정말 tea라고 불러도 좋을 듯한 롱 아일랜드 티와 위스콘신 스타일 그래스호퍼, 그리고 메뉴판에는 없는 프렌치 김렛이 꽤 취향이라 아는 맛이지만 갈 때마다 주문하게 되는 것 같습니다.

가끔 주말에는 디제잉 이벤트가 열리는 것 같습니다. 관심이 많지만 안타깝게도 아직 못 가봤습니다. 그래도 간혹 집에서 늦은 시간에 일이 잘 안 되면 방문해서 카페에서처럼 작업할 수 있는 편한 곳이 되었습니다. 술이 몸에 좋은 게 아니라는 건 다소 안타까운 사실이기는 하네요.

올해는 어땠고, 내년엔 뭘 할까

회고를 쓰기 시작할 때쯤에는 ‘올해 학교 일 / 다른 프로젝트로 엄청 바쁘게 사느라 한 게 없는데 쓸 게 있을까?’ 하고 생각했는데, 지금까지 썼던 회고 중에서는 제일 긴 글이 된 것 같습니다. 적지 않은 이벤트들도 있고, 더 길게 쓰고 싶었는데 그러면 평생 글을 쓰기만 하느라 절대 완성이 안 될 것 같아서 아쉽지만 간단하게만 적은 일들도 많은 것 같아요.

그럼에도 불구하고 꽤 아쉬운 한 해였습니다. 과제들이 한 주에 세 개씩 상황에서 여러 일들과 다른 중요한 프로젝트를 해내야 했는데요, 진행하는 프로젝트에서 회사에 다닐 때처럼 예상 시간 산정을 해서 작업했더니 절대 그 시간 안에 끝낼 수 없었습니다.

‘언제까지 끝내겠습니다’ 하고 질러 놨으니 작업을 최대한 완수하려고 날밤을 샜고, 결국 의욕은 의욕대로, 성적은 성적대로 떨어지고, 철야 작업은 목표만큼 하지 못하면서 책임도 지키지 못하는 상황들이 계속 발생했습니다. 시간 산정을 잘 하는 방법, 워크로드를 줄이는 방법에 대해 숙고해 보게 되었습니다. 철야 작업 동안 생산한 코드의 퀄리티보다 잠을 푹 자고 나서 생산한 코드의 퀄리티가 훨씬 좋다는 것도 체감했고요.

같은 이유로 솔브드 입장에서는 하려고 했던 것들을 많이 못 하게 되어 너무 아쉬운 한 해이기도 했습니다. 내년에는 학교 로드가 줄어들고 지금 하고 있는 프로젝트도 릴리즈를 바라보고 있으니 솔브드에서 계획했던 것들을 다 만들 수 있으면 좋겠습니다. 마음 같아서는 경과가 어떻든 졸업하고도 1년 정도 더 솔브드에 매진해 보고 싶습니다.

2024년에는 하고 싶은 일들을 좀 더 많이 할 수 있는 상황이 되겠지 하고 기대하고 있습니다. 이 소중한 시간을 그냥 흘려보내고 싶지 않아서 열심히 해 볼 작정입니다. 그러면서도 힘든 일들이 있더라도 언제나 제 곁에 있어 주는 소중한 사람들에게 조금 더 신경쓸 수 있는 제가 될 수 있으면 좋겠습니다.

새해는 우선 그랜드 아레나 파티를 여는 것과 여행비 모임통장에 1월 분 10만원을 보내는 것부터 시작해 보겠습니다. 조금 늦었지만 새해 복 많이 받으세요!

700,000원짜리 글

2월 3일 금요일

낙성대 자취방

통근을 위해 계약했던 낙성대 원룸의 계약기간은 2월 28일까지. 짐을 빼야 된다고 생각하면 여기에 있을 수 있는 날은 3주 남짓 남았습니다. 근처에 사는 직장 동료들과 함께 근처의 맛있는 음식점과 펍에서 함께했던 즐거운 시간들, 자취방에 친구들과 동료들을 데려와서 보드게임도 하고 음식도 나눠먹던 생활들을 이제는 놔줘야 한다고 하니 정말 아쉽습니다.

3월에는 복학을 해야 합니다. 동료들의 이직/복학 시기와도 맞아서 다들 낙성대를 떠나 편한 위치로 옮겨갑니다. 제 학교 또한 마포에 있기 때문에 굳이 낙성대에 계속 남아서 40분 걸려 통학할 이유가 없겠습니다. 그럴 바에는 본가에서 50분 통학하는 게 낫겠습니다.

그런데 본가에는 제 공간이 있기는 하지만 제가 마음대로 쓰기에는 무리가 있습니다. 누군가를 데려오는 건 생각하기 힘듭니다. 음악을 틀어 두고 새벽까지 작업한다거나 하는 건 실례가 됩니다. 또한 지하철이 피해가는 위치에 있어서 서울 어딘가를 가려고 하면 기본 40분은 잡아야 하는 곳이라 그다지 매력적이지 않습니다. 이외에도 여러 이유가 있지만 통학에 편도 50분이 걸린다는 것과 제 공간을 마음대로 쓰지 못한다는 점 때문에, 자취를 2년 더 하기로 결심하고 새로 살 집을 찾기 시작합니다.


2월 6일 월요일

자취를 2년 더 하겠다는 제 결정에 어머니께서는 꽤 아쉬워하셨습니다. 보증금도 월세도 제 돈이기는 하지만, 그래도 달마다 비용이 나가는 걸 막을 수 있으면 막는 게 좋겠다는 의견을 주셨습니다. 하지만 그런 이유보다는 제가 없었던 기간 동안 본가에 꽤 활기가 사라져서 그랬을 것이라고 생각합니다. 그래도 좋은 매물을 함께 알아봐 주시고 부동산도 같이 다녀 주셨습니다. 참 죄송하고 감사합니다.

모아 둔 돈이 생각보다 꽤 있어서 전세를 알아봐도 괜찮겠다는 생각이 들었습니다. 막연하게 대출 금리를 알아봤습니다. 청년을 위한 전세대출 상품은 상대적으로 저금리로 제공되는 경우가 많았습니다. 버팀목 전세자금 대출의 경우 연소득이 5,000만원을 초과할 것이기 때문에 신청할 수 없다고 보고, 카카오뱅크 대출을 알아봤습니다.

장기미거래로 계좌가 잠겨 있어서 정확한 한도는 알아보지 못했지만, 신청 페이지 메인에는 최저 4.42%의 금리최대 2.22억원까지 가능하다고 적혀 있었습니다. 이 정보를 보고 금리를 4.42%로 하여 전세방을 구했을 때 달에 얼마를 내야 하는지를 계산했습니다. 보증금 2억짜리 집을 월 이자 48만-55만 정도에 살 수 있는 수준이었습니다.

별개로, 낙성대에 있던 짐 40% 가량을 본가로 가져왔습니다. 집이 꽤 허전해졌습니다.

오늘 한 일

  • 원래 살던 집에서 짐을 40% 뺌

2월 7일 화요일

수천만 원이 들어 있던 적금을 깼습니다. 만기를 채우지는 못했지만 어차피 이자율이 0.9%밖에 안 돼서 깨려고 생각하고 있던 참이었습니다. 전세계약금이 필요할 경우 이체하기 위해서이기도 합니다.

전셋집을 알아보려니 전세사기가 걱정됩니다. 인터넷을 뒤지다가 HUG 전세사기예방센터라는 사이트를 찾았습니다. 전세사기 유형별 사례 및 대처방안이 부동산 지식이 없는 저 같은 사람도 이해하기 쉽게 적혀 있었습니다. 여기 적힌 내용을 꼼꼼하게 읽어봤습니다.


2월 8일 수요일

직방 앱과 네이버 부동산 앱은 나름 괜찮지만, 여러 집을 비교분석하기는 힘듭니다. 제 대출 정보와 연동해 월 얼마를 내게 될지 환산해 주는 함수를 만들고 여러 집들을 비교해 보기로 합니다.

여러 지역의 집을 알아봤는데, 저 정도의 돈을 주고 2년 사는데 학교 바로 앞 정도가 아니면 많이 후회하지 않을까 하는 생각이 듭니다. 그래서 대흥역 근처로 계약하기로 마음을 굳힙니다.


2월 9일 목요일

본격적으로 집을 알아보기 시작했습니다. 학교에서 도보 3분 거리의 집 한 곳을 마음에 담아 두고, 부동산을 방문했습니다.

전체적으로 희고 화사한 분위기에 전보다 꽤 넓직한 집이었습니다. 모니터 두 개를 쓰기 때문에 책상은 마음에 들지 않았지만, 공간 자체가 넓어 부엌 맞은편에 책상을 따로 놓고 저 책상은 다른 용도로 쓰면 되겠다 싶었습니다.

이전 자취방은 원룸이라면 당연하겠지만 가로 1.2m 세로 1.2m 정도의 작은 화장실이 있었습니다. 어느 정도냐면 키 180cm의 주취자를 눕혀 놓고 세척하기에는 꽤 무리가 있는 정도입니다. 이곳은 이전 자취방 화장실의 두 배 정도 크기에 보일러실까지 있어서 마음에 들었습니다. 게다가 싱크대도 넓고 인덕션도 두 구, 엘리베이터도 있습니다.

등기부등본을구가 비어 있었습니다. 따라서 설정된 근저당권이 없다는 뜻입니다. 근저당권이 없다는 뜻은 집주인이 집을 담보로 대출을 받지 않았다는 것을 말해 줍니다. 집을 담보로 대출을 받았다면 집주인이 대출금을 제대로 갚지 못했을 때 집이 경매에 넘어갈 수도 있기 때문에 조심해야 합니다.

원래대로라면 학교 주변 다른 부동산도 돌아보려 했지만 이곳이 꽤 마음에 들었고, 서울 부동산들이 항상 하는 ‘빨리 계약해야 한다’는 말에 못 이겨 계약을 체결합니다. 임대인께서 직접 오셨고, 신분증을 보여주셨습니다. 여기까지는 적어도 제가 아는 전세사기 사례와 예방법들에 관한 지식 내에서는 별 문제가 없었습니다.

전세보증금은 2억원. 계약금은 여기의 10%인 2,000만원입니다. 작은 금액이라고 할 수 없는 돈이 통장을 빠져나가고 나니 왠지 모르게 불안합니다. 2년 살 집을 이렇게 막 결정해도 되나 하는 생각이 듭니다. 아까 보고 온 것보다 집이 좁은 것 같고, 역에서 좀 먼 것 같기도 하고, 내가 모르는 사기 수법이 있으면 어떻게 하나 같은 생각도 듭니다. 하지만 이미 계약은 해 버렸고, 이제는 전세대출을 알아봐야 할 때입니다.

계약을 체결하고 집으로 돌아오는 중 어머니께서 ‘버팀목 전세자금 대출이 되지 않느냐, 퇴직했기 때문에 근로소득은 없는 것으로 볼 것 같다’고 하셨습니다. 마침 6시 직전이라 은행에 문의전화를 걸 수 있었습니다. 현재 퇴직자라면 근로소득을 0으로 보고 버팀목 대출을 받을 수 있다고 합니다. 그렇게 하면 연이율은 2.4% 이하로 줄어들고, 카카오뱅크의 4.44%보다는 두 배 적은 이자를 낼 수 있습니다. 이쪽으로 알아보기로 합니다.

늦은 시간이라 다음날 은행에 가 보기로 합니다.

오늘 한 일

  • 전세계약 체결 (전세보증금 2억원, 2023년 2월 25일부터 2년 계약)
  • 계약금 입금 (전세보증금의 10% = 2,000만원)

2월 10일 금요일

새로 살게 될 집과 가까운 은행에 가봐야 할 것 같습니다. 하지만 바쁘기도 하고, 우리은행 서강대지점은 사람이 항상 많기 때문에 높은 확률로 헛걸음질을 하게 될 것 같습니다.

우리은행 서강대지점에 전화를 해 봅니다. 대기 중인 고객이 51명이라고 합니다.

한 시간 후에 다시 전화했습니다. 대기 고객이 얼마 없었는데 그마저도 빠르게 빠졌습니다. 알고 보니 중앙 고객센터 같은 게 있고, 각 지점으로 로드 밸런싱 같은 걸 하는 것 같았습니다. 고객센터 직원 분께서는 제 실행예정일이 2월 25일이라는 말을 들으시고는 얼마 남지 않은 것 같다고 약간 당황하셨습니다.

서강대점으로 연결을 시도했습니다. 그러나 서강대점은 대출 쪽 직원이 한 분밖에 안 계신 곳이고, 그마저도 계속 통화중이셔서 실패했습니다. 서강대지점 근처 다른 지점에 문의드리고 싶다고 말씀드렸더니 신수동과 대흥동에는 지점이 없고, 공덕동에 금융센터가 있다고 하십니다. 그쪽으로 연결을 시도하셨으나 여기도 통화 중이셔서 실패했습니다.

아무래도 전화상담이나 방문상담 모두 어려울 것 같아서 서강대점에 예약을 잡았습니다. 오늘은 시간이 없었고, 가장 빠른 날짜는 다음 월요일이었습니다. 인터넷에서는 넉넉하게 대출 실행 2주 전에 은행을 방문하면 좋다고 되어 있었습니다만 다음주 월요일이면 잔금일로부터 2주 미만으로 남게 되기 때문에 불안해지기 시작합니다.

그 전에 제가 할 수 있는 게 있는지 알아보기 시작했습니다.

버팀목 전세자금대출은 주택도시기금이 보증공사와 은행을 통해 제공하는 대출상품입니다. 대출 프로세스는 대략 아래와 같습니다.

문서뷰어

위 프로세스의 ‘자격 확인’ 단계 중 ‘자격심사’와 ‘자산심사’는 미리 할 수 있는 방법이 있는데, 바로 주택도시기금의 인터넷대출신청(기금e든든) 웹사이트입니다. 빠르게 신청해 줬습니다.

대출 금융기관과 담보 종류를 선택해야 했는데, 별 생각 없이 우리은행 서강대지점과 주택도시보증공사(HUG) 보증을 선택했습니다. 그러다 전세대출을 이미 받아 본 친구의 ‘HUG는 2주만에 보증이 안 나올 것 같다’는 말에 대출신청을 취소하고 한국주택금융공사(HF)로 다시 넣습니다.

신청한 즉시 부적격 판정이 나왔습니다. 제가 국민임대주택에 살고 있고, 이미 기금 수혜를 받고 있기 때문에 부적격하다는 것이었습니다. 낙성대로 이사 오기 전에는 가족과 함께 국민임대주택에 살고 있었던 것이 사실이지만 지금은 그렇지 않아서 의아했습니다. 여하튼 주소 변경 내역이 포함된 주민등록초본을 제출하여 해결했습니다.

얼마 지나지 않아 또 소명자료를 제출하라는 고지가 왔습니다. 저는 최근에 창업하여 개인사업자가 되었습니다. 사업장을 임차했다면 보증금도 재산으로 보므로 사업장의 임대차계약서를 제출하라고 합니다. 재산이 3.6억 정도를 넘으면 안 되는데, 그랬다면 제가 대출을 알아보고 있지는 않았을 겁니다. 바로 제출합니다.

플랜 B 준비

아직 2주가 간당간당하게 남아 있기 때문에 혹시 모를 상황을 대비해 카카오뱅크 거래제한을 푸려고 시도해 봅니다. 공과금 고지서를 제출했는데, 이사올 때 이름을 바꾸지 않은 게 마음에 걸립니다. 그래서 카카오뱅크에 전화문의를 해 보니 이름이 다르면 어렵겠다고 하십니다. 다른 해제 수단으로는 6개월 내에 납부한 세금 영수증이 있는데, 2월으로부터 6개월 전이면 작년 8월입니다. 7월에 납부한 종합소득세 영수증밖에 없습니다. 다행히도 종합소득세는 연 1회만 내는 세금이기 때문에 괜찮다고 하십니다. 바로 제출하고 거래제한이 풀리기를 기다립니다.

오늘 한 일

  • 확정일자 발급
  • 기금e든든에 대출 신청
  • (플랜 B) 카카오뱅크 거래제한 해제를 위해 공과금 고지서 종합소득세 납부증명 제출

2월 11일 토요일

13일이 되기 전까지는 할 수 있는 게 없는데, 13일은 잔금일로부터 12일밖에 안 남은 날입니다. 아무래도 부족할 것 같습니다. 저의 이런 불안감을 알고 계셨는지 어머니께서 저도 모르는 사이에 부동산에 전화드려 잔금일 연기에 대해 여쭤보셨던 것 같습니다. 임대인 분과 합의해 입주일을 2월 28일로 연기했습니다.

부동산을 다시 방문해야 했습니다. 2,000만원이 걸려 있는데 한시라도 빨리 가야 할 것 같아서 택시를 타고 갔습니다. 3일이 늘어난 게 얼마나 큰 영향을 줄지는 모르겠으나, 최후의 보루 카카오뱅크도 적어도 15일 전에는 대출 신청을 넣어야 한다고 하여 아주 약간의 위안을 얻었습니다.

또한 HF 보증은 저는 받을 수 없다는 사실을 깨달았습니다. 간단히 말해서 HUG는 건물의 신용을 보고, HF는 세입자의 소득을 보는데, 버팀목 대출이 승인받는 조건은 제 근로소득을 소득심사에서 제하는 것이고, 그렇게 하면 저는 거의 무소득자가 됩니다. 이렇게 되면 HF 보증으로는 제가 필요한 만큼의 대출을 받을 수 없습니다. 무소득자의 보증한도는 4,500만원에 그치기 때문입니다. 보증을 바꿀 수 있는지 은행에 가서 물어보기로 합니다.

이제 월요일이 되기 전까지 딱히 할 수 있는 게 없습니다. 2,000만원도 잃고 집에도 입주할 수 없는 상황이 생길까봐 너무 불안했지만, 아무것도 할 수 없다는 사실을 받아들이고 자러 가기로 합니다.

오늘 한 일

  • 입주일 연기 (2023년 2월 25일 → 2023년 2월 28일)
  • 새 계약서에 대한 확정일자 발급

2월 13일 월요일

일어나자마자 다음 순서로 은행들을 방문했습니다.

  • 신한은행 대흥역점
    • 개장시간에 맞춰 갔으나, 잔금일자 2월 28일은 어렵다고 합니다. 신한은행 거래내역이 없어서 곤란할 것 같다는 말도 어렴풋이 들은 것 같습니다.
  • 우리은행 서강대지점 (예약)
    • 여기도 2월 28일은 어렵다고 합니다. 근처 다른 지점이 있냐고 여쭤봤더니 신촌역 금융센터를 추천해 주셨습니다. 빠르게 출발합니다.

그 와중에 카카오뱅크 거래정지가 해제되었습니다. 카카오뱅크는 잔금일 15일 전까지만 신청이 가능하니, 오늘 하지 않으면 안 됩니다.

빠르게 대출한도를 알아봤으나 1억원까지만 나온다고 합니다. 나머지 1억원은 제 재산을 어떻게 영혼까지 다 끌어모으면 마련할 수도 있고 아닐 수도 있을 것 같은데, 그러면 등록금까지 낼 돈은 없어집니다. 게다가 금리가 비쌉니다. 버팀목으로의 대환 대출은 이사를 또 가지 않는 이상은 어렵습니다. 카카오 대출은 플랜 B로서 두기로 마음을 굳히지만, 오늘이 지나가면 사라지는 선택지라는 게 부담을 줍니다.

이후에 은행 몇 곳을 더 방문합니다.

  • 우리은행 신촌금융센터
    • 여기도 어렵다고 합니다. 서강대지점을 추천해 주십니다. 이미 다녀오는 길이라고 하니 연세대 서강대에서 안 돼서 이쪽으로 오시는 분들이 많은데 안타깝다고 하십니다.
  • 우리은행 공덕동효성금융센터
    • 번호표를 뽑고 조금 기다렸는데, 여기도 안 됩니다. 적어도 1달 전에는 오셔야 한다고 하십니다.
  • 신한은행 마포지점
    • 어렵다고 하십니다.

5연속 거절을 당하고 여의도, 망원, 시청을 돌면서 모든 은행을 방문해 보기로 합니다. 본가에 5개 은행에서 안 된다고 전화드렸더니 어머니께서도 알아봐주신다고 하십니다.

  • 우리은행 아현동지점 (전화문의)
    • 충정로 쪽으로 이동하면서 전화문의를 드렸는데, 어렵다고 하십니다.
  • 우리은행 망원역지점 (전화문의)
    • 안 된다고 합니다.
  • 강서구 쪽 은행 (본가에서 전화문의, 정확히 어디인지는 모르겠음)
    • 일정상 가능하지만, 매물이 너무 멀어서 관리하기 힘들기 때문에 거절당했습니다.
  • 우리은행 충정로금융센터 (전화문의)
    • 지점 직원분으로의 통화연결에 실패했습니다. 바쁘신 것 같아서 고객센터에 이후 전화해 달라고 메모를 남겨 달라고 했는데, 공덕에서 우리은행 서소문지점으로 택시를 타고 가던 도중 지점으로부터 힘들겠다는 전화를 받았습니다.
  • 우리은행 서소문지점 (전화문의)
    • 충정로와 마찬가지입니다.

아침 8시 40분부터 신한은행에 가서 대기를 했는데, 바쁘게 뛰어다니다 정신을 차리고 보니 벌써 오후 1시입니다. 전화를 몇 통을 돌렸는지 모르겠습니다. 우리은행 고객센터 통화연결음이 정말 듣기 싫어지고 매번 앞에 있는 50명의 고객들을 기다리게 만드는 로드 밸런싱이 너무나도 야속해집니다.

엔드게임

몇 시간 동안 외판원 순회를 하고 있자니 희망이 없는 것 같습니다. 슬슬 선택해야 할 시간이 다가옵니다. 당장 두 가지 정도의 방법이 떠오릅니다.

  • a) 잔금을 어떻게든 치루고 이후에 버팀목 전세자금 대출을 알아본다(3개월 내).
    버팀목 대출은 잔금일 이후 3개월까지도 신청이 가능합니다. 단, (보증금) – (제 전재산)을 대체 어떻게 구하느냐는 이제부터 생각해 봐야 합니다. 승인이 되면 최고 2.4%의 금리로 살 수 있습니다.
    지인들에게 손을 빌리기는 너무나도 미안하고, 제 나이가 그렇게 많지 않은 걸 감안하면 몇천만원을 흔쾌히 빌려줄 수 있는 사람도 없을 것 같습니다. 급기야 대부업체를 검색해보기까지 이릅니다(무서워서 문의조차 안 해보기는 했습니다). 사람이 궁지에 몰리면 이렇게까지 될 수 있다는 걸 느낍니다.
  • b) 카카오뱅크 대출을 1억원이라도 받고 나머지 잔금을 어떻게든 마련한다.
    이 옵션은 이전 옵션보다는 난이도가 약간 낮지만, 금리가 두 배 정도 뜁니다. 그리고 여전히 몇천만원을 어떻게 구할지를 생각해 봐야 합니다.
    이 경우의 몇천만원은 그래도 열심히 일하면 1년 안에 모을 수 있는 정도의 돈인 것 같아 보이기는 합니다. 하지만 빠르게 결정해야 합니다. 오늘이 지나면 사라지는 옵션이니까요.

갈등합니다. 어떤 선택지든 인생이 정말 정말 어려워질 것 같습니다.

그러다가 다른 해결 방법이 떠오릅니다.

  • c) 임대인 분과 현재 세입자 분께 위약금이라도 지불하고 입주일자를 한 번 더 미룬다.
    2억 원에서 제가 이미 입금한 계약금 2,000만 원을 제하면 1억 8,000만 원입니다. 1억 8,000만 원에 대한 법정 최고 이율의 월 이자는 300만원입니다. 작은 돈은 아니지만, 무려 2,000만 원을 잃을 수 있는 상황에서 이 정도의 위약금을 지불하고 모든 프로세스를 다시 시작할 수만 있다면 흔쾌히 지불할 의향이 있습니다.

이미 입주일자를 미뤘다는 점에서 임대인 분께 너무나도 실례되는 방법이고, 이 방법도 나름의 불확실성은 가지고 있지만, 양해해 주신다면 저에게는 최선의 해결 방법입니다.

서강대점으로 돌아오다

원래 저는 문제 상황에서 다른 사람들의 도움을 잘 빌리지 않는 성격이지만 지금은 그런 걸 가릴 때가 아닙니다. 일단 입주일자를 언제로 맞추면 대출이 실행될 수 있을지 알아보기 위해 우리은행 서강대지점으로 돌아왔습니다.

대출 상담 직원 분과 긴 이야기를 나눴습니다. 상황을 설명해 드렸더니 3월 10일 이후 입주할 경우에는 괜찮을 것이라고 하십니다. 넉넉잡아 3월 17일로 잠정적으로 정하고, 필요한 서류 목록 등의 안내를 받았습니다. 이 시점에서 제가 이미 신청했던 기금e든든은 취소되었습니다.

정말 일자를 미룰 수 있을지는 불확실했는데, 직원 분께서 제가 불안해하고 있는 걸 눈치채셨는지 혹시라도 미루는 데 실패하더라도 최대한 도와주시겠다고, 사람 일이 안 될 것 같아도 막상 해 보면 되는 것들도 있더라고 말씀해 주셨습니다. 28일에 실행되는 게 가능한지를 떠나서 정말 힘이 되는 한 마디였습니다. 이 글을 빌어 감사를 전하고 싶습니다.

부동산에 위약금이라도 내고 입주일자를 미루고 싶다고 말씀드렸습니다. 임대인께 여쭤보신다고 합니다.

2시가 되어서야 밥을 먹을 수 있었습니다. 무슨 일이 있을지 모르니 학교 편의점에서 간단히 끼니를 때웁니다. 학교에서 밥 먹는 건 오랜만입니다.

여행에 가도 이 정도는 안 걸을 것

돌파구

부동산에서 연락이 왔습니다. 임대인께서는 크게 개의치 않으나, 현재 임차인께서 보증금을 돌려받아야 새 집에 입주할 수 있어서 이 점이 걱정되신다고 합니다.

초조하게 기다립니다.

다행히도 현재 세입자께서 제 상황을 이해해 주시고 대출이자를 제가 대신 내는 것을 조건으로 승낙해 주셨습니다.

면목이 없었습니다. 안도의 한숨을 쉬었습니다.

당일 4시 20분에 계약서를 다시 한 번 수정하기로 합니다.

다시 주어진 한 달

부동산에 도착해서 임대인 분과 현재 임차인 분과의 삼자대면을 했습니다. 공인중개사께서 제가 너무 죄송해하는 걸 보시고 제 잘못이 아니라고 안심시켜 주셨습니다. 사실 건물 때문에 대출이 나오지 않은 이상 꼼꼼히 알아보지 않은 건 제 귀책이고 여전히 제 잘못이라고 생각합니다.

입주일자를 3월 17일로 미루기로 하고, 전례를 찾아보기 힘든 계약 변경 합의를 맺었습니다. 골자는 이러했습니다.

  • 계약금을 5,000만 원으로 올립니다.
  • 월세를 70만 원으로 하여 제가 2월 17일부터 3월 16일까지 임차합니다.
  • 3월 19일까지 전세보증급 완납에 실패할 경우, 이후 3개월 간은 월세를 120만 원으로 하여 일할 지급합니다.
  • 6월 19일까지 전세보증금 완납에 실패할 경우, 퇴거합니다.

여기서 ’70만 원’이 전 세입자 분께서 대출 이자로 합의하신 금액입니다. 임대인 분의 입장에서 봐도 거의 무상 임차를 제공해 주신 것이나 다름없습니다. 정말 감사하지 않을 수 없는 일입니다.

그래도 현 세입자 분께 보증금을 돌려드려야 입주를 하실 수 있기 때문에 계약금이 올라갔습니다. 이전에 입금한 2,000만 원에 더해 추가로 3,000만 원을 입금합니다. 계약금 5,000만 원의 엄청난 계약이 되었습니다.

계약서를 다시 작성하고, 확정일자를 다시 받았습니다. 오늘부터 잔금일까지의 카운터는 32일로 리셋됩니다. 은행에 전화해서 연기 사실을 말씀드렸더니 정말 다행이라며, 하지만 1개월 이전까지는 또 프로세스를 진행하기 어렵기 때문에 2월 20일에 재방문해 달라고 해 주셨습니다.

2월 20일에 은행 예약을 잡았습니다. 오늘은 편하게 잘 수 있을 것만 같습니다.

오늘 한 일

  • 은행 십수 곳 방문
  • 입주일 연기 (2023년 2월 25일 → 2023년 3월 17일)
  • 계약금 인상분 입금 (3,000만 원)
  • 새 계약서에 대한 확정일자 발급

2월 20일 월요일

각종 서류를 챙겨서 아침에 은행에 방문했습니다. 은행에 가서도 엄청나게 많은 서류를 작성하고 서명했습니다. 의외로 20분 가량으로 끝났습니다. 기금e든든 신청을 따로 할 필요 없이 은행에서도 처음부터 신청이 가능한 것 같습니다.

건물도 문제 없고, 제 신용도도 괜찮아서 별 일 없으면 3월 17일에 대출이 실행될 것이라고 합니다. 다행입니다. 이율은 제가 생각했던 것보다 훨씬 낮은 1.2%였습니다. 한 달에 15만 원의 이자만 내면 되는데, 전에 살던 곳의 월세가 45만 원이었던 걸 생각해 보면 버팀목 대출은 정말 감사한 제도라고 느낍니다.

새로 작성한 합의서 상 2월 19일부터 이곳의 세입자는 저입니다. 새 집을 처음 들어가볼 수 있었습니다. 계약 직후에 ‘집이 좁진 않을까’ 걱정했던 것과는 다르게, 다행히도 생각보다 많이 넓었습니다. 다만 입주 청소가 필요해 보였고, 책상도 새로 사야 할 것 같았습니다.

안타깝게도 줄자를 새로 가져오지는 못해서 도어락 비밀번호만 바꾸고 낙성대로 돌아옵니다.

오늘 한 일

  • 은행에서 대출 신청
  • 새 집 도어락 비밀번호 변경

2월 22일 수요일

대출 신청 적격 판정이 됐다는 알림이 왔습니다. 사전 자산심사를 통과했다는 뜻입니다.

이제 물리적인 고생길만 남았습니다. 새 집을 청소하고, 낙성대에서 새 집으로 짐을 옮기기만 하면 됩니다.

이제 걱정해야 하는 건 이곳을 비우는 것입니다. 하루종일 이삿짐을 쌌습니다. 짐을 빠르게 옮기기 위해 25일 아침에 입주청소업체를 예약합니다.

2월 26일에는 이사를 마쳤습니다. 1년 반 만에 그렇게 정들었던 낙성대와도 이제는 작별의 시간이었습니다.


3월 17일 금요일

대출이 실행되었다는 문자를 받았습니다. 힘들었던 여정의 끝입니다. 이제는 돈 걱정 없이 이곳에서 살면서 행복하게 학교를 다닐 수 있을 것 같습니다.


마치며

지난달에 했던 마음고생은 여기에 형언할 수 없을 정도인 것 같습니다. 뼈가 깎이는 일들을 겪으면서 정말 많은 걸 느끼게 되었습니다.

카카오뱅크는 ‘최저‘ 4.4%의 금리에 ‘최대’ 2.22억원을 대출해 줍니다. 하지만 그 금리와 한도가 나한테 적용되는 것은 아닙니다. 계좌정지가 풀리기까지는 그렇게 판단하지 말았어야 했습니다.

버팀목 전세자금은 퇴직자의 경우 근로소득을 제합니다. 문의해야 알 수 있는 사항이었습니다. 문의해보지 않고 버팀목이 안 될 것이라고 판단하지 말았어야 했습니다.

인터넷 블로그들은 전세자금 대출은 2주 전에 신청하라고 합니다. 하지만 그건 학기가 시작되는 시기, 학교 근처 매물, 그것도 서울에서의 상황과는 거리가 멉니다. 최소한 한 달 전에는 은행에 문의했어야 했습니다.

이번 일을 겪으면서 만사를 안일하게 생각하지 말아야 된다는 교훈을 얻었습니다. 앞으로 제가 비슷한 일을 겪는 것을 예방하기 위해, 그리고 혹시 모를 다른 분들의 고생을 막기 위해 글으로 남겨 두려 합니다.

아직은 조금 더 정리가 필요하지만 지금은 새 집에서 나름 행복하게 살고 있습니다

전세계약 체크리스트 (23/3/20 추가)

  • 전세사기 예방
    • HUG 전세사기예방센터 꼼꼼히 읽기
      • 등기부등본 확인 – ‘을구’에 설정된 근저당권이 과하지 않은가?
      • 시세 확인 – 집값이 보증금보다 작거나 비슷하지는 않은가?
      • 임대인 확인 – 계약서에 적힌 임대인과 같은 사람이 와서 계약하려고 하는가? 다른 사람이 왔다면, 위임장이 있고 위임장에 찍힌 도장을 증명할 인감증명서가 있는가?
      • 이중계약 확인 – 이전 세입자가 아직 살고 있는가?
  • 버팀목 전세자금대출
    • 넉넉하게 1달~3주 전에 은행에 방문하여 상담하는 것을 추천
      • 1달보다 더 전이라면 아직 신청이 불가능할 수 있음
    • 대출 조건을 만족해야 함, 아래는 2023년 3월 기준 그 중 일부
      • 무주택자 세대주, 또는 실행일로부터 1개월 이내 세대주 예정자
      • 주택도시기금대출, 은행재원 전세자금대출 및 주택담보대출 미이용자
      • 소득 ≤ 5,000만 원, 자산 ≤ 3억 6,100만 원
        • 소득금액증명을 발급해 소득 확인 가능
        • 현재 무직자라면 근로소득을 0으로 봄
        • 기타소득의 경우 증빙을 제출해야 할 수 있음
      • 전용면적 ≤ 85㎡, 보증금 ≤ 3억 원
    • 대출 한도는 2억 원이나, 만 25세 미만일 경우 1.5억 원 이하임
      • 만 25세 미만인 경우 우대금리 0.3%p
    • 자세한 내용은 은행과 상담할 것
      • 우리 1599-0800, 국민 1599-1771, 기업 1566-2566, 농협 1588-2100, 신한 1599-8000
  • 카카오뱅크 전세자금대출
    • 1달~15일 전 안에 신청해야 함
    • 한도와 금리는 카카오뱅크 앱에서 실제로 신청서를 작성하여 확인할 것
      • 메인 화면에 나오는 것은 ‘최저’ 금리와 ‘최고’ 한도로 본인에게 적용되는 것이 아닐 수도 있음
    • 대출 조건을 만족해야 함
    • 자세한 내용은 은행과 상담할 것
      • 1599-3333

새로운 시작의 앞에서

2022년 회고

3년의 휴학 기간 동안 산업기능요원으로 복무했습니다. 이제 학교에 있었던 시간보다 회사에 있었던 시간이 더 길어졌습니다.

코로나는 확실히 무서웠고 그 광풍을 저도 피해갈 수 없었습니다. 그러나 이 글을 쓰고 있는 지금은 그 무서움이 꽤 농담이 된 것 같습니다. 18학번으로 입학했지만 비대면 수업을 받는 시대는 거치지 못하고 넘어가버렸습니다.

회사를 차렸습니다

4년간 만들어 오고 있는 solved.ac는 제가 가장 즐겁게 엔지니어링하고 있는 프로젝트입니다. 그래서 다시 학생이 되는 지금이 아니면 언제 해 보겠느냐는 생각으로 회사를 차렸습니다.

복학과 졸업 이후에도 다니던 회사를 계속 다닐 수 있는 옵션은 있었습니다. 급여도 적당히 만족스러웠고, 업무 프레셔도 높지 않았고 사람들도 좋아서 고민이 정말 많이 되었습니다. 하지만 제 프로그래밍-디자인-기획의 복합 역량을 제일 잘 발휘할 수 있는 프로젝트이며, 그렇게 많지는 않지만 이미 10만 명 가까운 유저가 사용 중이라는 것도 결정하는 데에 도움을 줬습니다.

여태까지 저는 제가 하고 싶은 일을 하면서 살았을 때 제일 즐겁게 살았습니다. 그래서 졸업까지 남은 2년을 지금 저에게 있어서 제일 즐거운 일을 오래오래 할 수 있을지 아닐지에 대한 테스트베드로 삼아보려고 합니다. 솔브드는 어디로 가게 될까요?

복무만료

2월에 훈련소를 다녀왔고, 5월에 복무만료가 되었습니다. 이제 예비군입니다.

코로나 시대의 훈련소는 정말 재밌는 곳입니다. 훈련을 3주간 하는데, 그마저도 반 정도 기간은 단체 격리라 야외 훈련은 마지막 1주에 몰아서 합니다. 그런데 조교들까지 단체 확진돼서 우리는 사격훈련과 수류탄 훈련 외의 훈련을 받아보지 못했습니다.

그리고 저도 훈련소 안에서 코로나에 걸려서 논산에서 어디 경기도로 끌려가서 개별 격리 당하고, 그곳에서 수료까지 했습니다.

이외에는 인터넷 편지 받은 거를 제외하고는 모든 군대 이야기는 재미없으니 하지 않겠습니다. 편지 보내주셔서 감사합니다!

성과 자랑

제가 2019년에 정한 PS 인생 목표는 이랬습니다.

올해는 이 중 하나를 더 이뤘습니다. 바로 구글 코드잼입니다!

구글 코드잼 성적은 2019년 2라운드(2,443rd), 2020년 2라운드(1,427th), 2021년 2라운드(1,328th)였습니다. 특히 2021년에는 배열 인덱스를 잘못 잡아서 히든 테스트케이스를 놓치고 진출을 실패했던지라 너무너무 아까웠는데 다행히도 작년의 실수를 올해 만회할 수 있었습니다.

SCPC 2022 Final을 통과했다는 건 무슨 말일까요?

SCPC는 올해도 무수상입니다. 4년 연속인데 언제 상을 타볼 수 있을지 모르겠습니다. 사실 2019년이 가장 가능성 있었을 것 같은데요…

코드포스는 열심히 안 치다가 다시 쳤더니 퍼플로 내려갔습니다. 레드는 너무 요원해 보입니다. 적의환향 어디 갔냐고….

갑자기 분위기 해커톤

즉흥적으로 팀을 꾸려 나간 Junction Asia 2022에서 2등을 했습니다. 중고등학생 때는 해커톤을 많이 나갔는데, 대학교에 와서는 알고리즘 문제해결 관련 필드에 있느라 해커톤은 잘 안 나갔습니다. 해커톤을 마지막으로 나갔던 게 거의 2017년?쯤이었던 것 같으니 5년만입니다.

부산에서 열리는 온사이트 해커톤이었습니다. 제가 나갔던 어떤 해커톤보다 큰 규모의 해커톤이었습니다. 호텔도 지원해 주고, 피자도 줍니다.

금요일부터 일요일까지의 대회여서 저는 개인사유로 휴가 쓰고 회사 몰래 나왔습니다.

4명 팀인데 프론트엔드 엔지니어가 4명, 백엔드 엔지니어 3명이었던지라 개발은 다른 분들께 맡길 수 있겠다고 생각해서 저는 개발은 많이 안 하고(위에 보이는 노트북에 스티커 붙이는 프론트엔드만 개발했습니다), 대신 프레젠테이션을 만들고 디자인에 공을 들였습니다. 여기서 Figma를 처음 써 봤는데 정말 세상에 이렇게 편한 디자인 툴이 있을 수가 없다는 생각이 들었습니다. 이후 모든 프레젠테이션을 Figma로 만들고 있습니다.

다년간의 해커톤 경험으로 빠르게 작업하지 않으면 잠을 설치면서 개발하고 디자인할 걸 알고 있었기 때문에 디자인은 첫 날에 거의 끝내버렸고, 둘째/셋째 날은 프로젝트가 어떻게 시장에서 먹힐지를 어필할지 열심히 생각하면서 프레젠테이션을 깎았던 것 같습니다. 해보니까 빠르게 작업하지 않으면 잠을 설치는 게 아니고 그냥 예전의 저는 작업을 빠르게 하지 못했던 거고 빠르게 해도 잠은 어찌됐든 설치는 거였습니다.

블록체인이라는 분야에 대한 막연한 두려움과 이것저것 때문에 블록체인 트랙으로 가게 될 거라고는 상상도 못했는데, 블록체인을 무서워하지 말고 그냥 한번 데이터베이스처럼 써 보라는 Chainapsis 발표를 듣고 설득당했던 것 같습니다. 무엇보다 Ignite CLI가 너무 사용하기 쉽게 되어 있었습니다.

즐겜하러 나왔는데 트랙 2등을 하는 영광을 누렸습니다. 상금은 아웃백에 썼어요. 감사합니다!

오랜만에 해커톤을 나가 보니 제일 힘든 건 집에 돌아와서 바로 다음날 출근하는 거였던 것 같습니다.

소프트웨어 개발

솔브드

올해는 크고 작은 다른 일들이 많아서 솔브드에 쏟을 수 있는 시간이 많지 않았습니다. 길라잡이는 시간을 많이 쏟아야 하는 컨텐츠이기 때문에 본업이 있는 상황에서는 만들기 어려웠던 것 같습니다. 대신 내실을 다지는 개발을 위주로 했습니다.

  • SEO에 조금 더 신경을 썼습니다. 오픈 그래프 스펙을 도입하고, 자동 트윗을 게시할 때 그래픽을 만들어 주도록 했습니다.
    • 다만 자동 트윗 이미지 생성은 최적화할 부분이 많아 보입니다. Puppeteer를 써 봤다 정도에 의미를 부여할 수 있을 것 같습니다…
  • 솔브드의 UI 코드를 정리해 @solved-ac/ui-react를 만들었습니다. (후기)
    • 이 과정에서 styled-components를 걷어내고 emotion으로 스택을 바꿨습니다.
  • 아직 완벽하지는 않지만, 영어로 i18n을 했습니다.
  • 문제 검색 쿼리를 최적화했습니다. DBA가 된 기분이었습니다.
    • 작년까지는 8천 문제 푼 사람들 5명의 교집합을 구하려고 하면 서버가 터졌습니다…
  • 길라잡이 에디터의 기반을 아주 약간 다졌습니다.

내년 목표는 이렇습니다.

  • 길라잡이 에디터를 사용할 수 있는 상태까지 발전시키기
  • 가능하다면 백엔드에서 Sequelize 걷어내기. Sequelize를 오랫동안 사용해 본 결과 이건 ORM이 아닌 것 같습니다. 앞으로는 Prisma를 쓰든 EdgeDB를 쓰든 할 것입니다.
  • 백엔드 내실 다지기. 사용자가 많아지면서 웹 서버가 가끔 죽는데, 지금은 Redis도 SQS도 없습니다. 더 늦기 전에 추가해야 합니다.

적어놓고 보니 한 게 많이 없는 것 같습니다. 훈련소도 다녀왔고, 특히 재택에서 출근 근무로 바뀐 탓에 출퇴근 시간 2시간이 사라져 버려서 그런 것 같네요… 퇴근하고 나면 정말 피곤합니다.

이외에도

올해도 정보올림피아드 대회 시스템 프론트엔드 유지보수 작업을 했습니다.

한국정보과학교육연합회의 단계별 프로그래밍 교육 프로그램 BIKO를 만드는 데에 참여했습니다.

평소 팬이었던 ARForest님의 컴필레이션 앨범 The Unattended와 3집 Deep Inside 앨범 사이트를 작업했습니다. Framer Motion으로 애니메이션 작업을 했습니다. WebGL이 배우고 싶어졌습니다.

대회 운영과 출제

NYPC

올해도 시스템 개발과 출제를 맡았습니다. 참가자인 척 끼어 있는 출제진을 찾아보세요!

저는 본선 1519부문 5번 〈지름길〉 문제를 냈습니다. 최단 거리 트리를 생각하다가 두 노드의 최단 거리 트리를 합친 걸 최소화하는 문제는 어떨까 하는 생각에 발제했는데, 어쩌다 보니 가장 어려운 문제로 출제되었습니다. 여러 비하인드가 있는데 이야기 가능한 범위가 어디까지인지는 모르겠습니다.

위의 링크를 들어가 보고 아셨을 수도 있겠지만 해설 사이트도 새로 작업했습니다. 원래도 GitHub에 올라와 있는 오픈 소스 프로젝트여서 GitHub의 좋은 점들을 활용하고 싶었고, GitHub Actions와 Next.js SSG를 사용해 MDX로 작성된 문제 파일을 수정하면 자동 배포가 되도록 구성했습니다. 기존에는 Jekyll과 Kramdown 엔진을 사용해 수식을 작성했는데, 인라인 수식을 $$ ... $$로 작성해야 하는 아주 끔찍한 문법을 쓰고 있었기 때문에 프로젝트를 그냥 처음부터 다시 만들었습니다.

NYPC 출제진으로 일하는 것도 정말 즐거운 경험이었습니다. 저는 이제 퇴사했지만 혹시 출제에 관심이 있으시다면 넥슨 입사 어떠신가요? 의외로 게임 클라이언트뿐만 아니라 웹 프론트엔드/백엔드, 블록체인, MLOps 등 정말 여러 분야에서 채용을 진행하고 있습니다. 보충역 산업기능요원을 알아보고 계신다면 제가 다녔던 엔진스튜디오도 좋은 옵션이라고 생각합니다. 엔진 혹은 넥슨에 레퍼럴이 필요하시면 제 메일로 문의 부탁드립니다.

ICPC 서울 리저널

휴학 중이라 ICPC에 나갈 수 없었는데, 올해는 온사이트로 열리게 되어서 스태프로 일했습니다. 본선에 오신 분이라면 저를 만났을지도 모르겠습니다. 제가 풍선을 달아 드렸을 수도 있구요.

사실 작년에도 참관하기는 했습니다. 스코어보드 공개할 때 제가 잠깐잠깐 나옵니다… 내년부터는 다시 참가자로 대회를 나가 보려고 합니다.

저는 시간에 여백이 부족해서 따로 글을 쓰지는 못했지만 같이 운영해 주신 스탭 분들의 블로그 후기들을 읽어 보시면 스탭으로서의 현장 경험을 조금이나마 느낄 수 있으실 것 같습니다.

UCPC

작년에는 학교에서 팀을 꾸려서 대회에 나왔지만 올해는 다시 전대프연으로 돌아와서 대회 운영을 도왔습니다.

UCPC는 출제로는 연이 별로 없구요, 대신 디자인과 운영에 도움을 드렸습니다. 이번 로고 모양 폼보드 명찰과 폼보드, 티셔츠 등이 제 작품입니다. 개인적으로는 꽤 마음에 들었던 디자인들입니다.

대회 당일에 정말 많이 뛰어다니면서 땀도 많이 흘리고 힘들었던 기억이 있습니다. 200명을 수용할 수 있는 합리적인 가격의 대관처는 정말로 찾기 어렵습니다. 그리고 협소한 대관처는 꽤나 덥습니다.. 이후에 킨텍스에서 진행된 ICPC에서 일하면서 정말 부러웠습니다.

SPC / 서강 프로그래밍 대회

제가 항상 제일 쉬운 문제와 제일 어려운 문제를 내는 대회입니다. 올해에도 어김없이 적당히 쉬운 문제 하나제일 어려운 문제 하나를 냈습니다. 어려운 문제 쪽은 개인적으로 잘 냈다고 생각하지만 쉬운 문제 쪽은 머리가 꼬일 수 있는 지문 + 약간의 케이스 워크 때문에 1~2학년 디비전의 두 번째 문제로 내기에는 약간 부적절했던 것 같다는 소회입니다. 이 자리를 빌어 사과드립니다… 하지만 졸업하실 때는 이 정도는 푸셔야 해요.

언젠가부터 소프트웨어중심대학이 잘려서 학교의 지원을 받기 힘들게 되었고, 학교 지원만으로 충분히 대회를 열 수 있었던 예전과는 다르게 후원도 알아봐야 하고 고생이 많으셨을 텐데 열정 넘치는 멋진 분들께서 운영해 주셔서 대회가 성료될 수 있었던 것 같습니다. 참 다행입니다. 항상 감사드립니다.

빅파이 아직은 안 물립니다. 감사합니다.

이외에도

2023년 1월에 열리는 보드게임컵을 준비 중입니다. 온라인 대회지만 다른 오프라인 대회만큼 고생하고 있는 것 같습니다. 참가해 주시면 기쁠 거예요!

컨퍼런스

고려대학교 중앙 컴퓨터 동아리 KUCC에서 《코딩 테스트 및 알고리즘 문제해결 공부 방법》을 발표했습니다. 코딩 테스트가 개발자 취업 과정에서 어떤 단계에 있는지부터 설명하고, 무슨 언어를 고르면 좋을지, 공부 시작은 어떻게 하면 좋을지, 문제 하나를 해결할 때 시간 분배는 어떻게 하면 좋을지, 그리고 합격하기 전까지 어떻게 공부하면 좋을지 설명했습니다. 저 개인적으로는 코딩 테스트를 피험자로 본 적은 없지만 넥슨 엔진스튜디오 면접 TF에서 일한 경험과 프로그래밍 대회를 준비하던 경험을 녹여 예비 개발자 분들께 도움이 될 만한 내용을 꽉꽉 눌러 담았습니다. 이 발표 자료는 코딩 테스트를 준비하는 분들께 제가 강력히 추천하는 자료이기도 합니다.

프로그래머스의 초청으로 프로그래머스 컨퍼런스 1st에서 《모두의 성장을 위한 서비스 만들기: solved.ac 개발 경험을 토대로》를 소개했습니다. solved.ac를 만들어가면서 했던 — 기여 시스템 설계, 가이드라인 설정, AC 레이팅 설계 — 등에 관련된 길었던, 어찌 보면 계속되고 있는 고민들에 대한 답을 냈던 경험을 정리해 보고 이를 통해 커뮤니티 운영자로서 배운 점들을 공유했습니다. 발표를 준비하면서 커뮤니티의 공감을 얻으려면 확고한 방향을 갖고 기획해나가야 한다는 점을 다시 한 번 되새길 수 있었습니다.

한국항공대학교 학술제에서 《새내기 코딩 마법사를 위한 2차 전직 준비하기》를 주제로 이제 막 학교에 들어온 학생들에게 앞으로의 ‘전직 루트’를 소개했습니다. 학교에서 알려주는 것과 회사에서 하게 될 것들은 다르기 때문에, 회사에서 필요로 하는 역량들에 대해 설명하고, 이를 ‘전직 퀘스트’에 빗대어 어떤 퀘스트들이 있고 어떻게 준비하면 좋은지 발표했습니다. 앞서 고려대학교 KUCC에 했던 코딩 테스트 관련 내용도 간단히 소개했습니다.

지식을 공유하는 건 즐거운 일이라고 생각하지만 사실 저는 제 말의 무게에 힘이 실리는 걸 별로 좋아하지는 않습니다. 제가 알고 있는 내용이 틀릴 수도 있고, 모두에게 적용할 수 있는 것도 아닐 수 있기 때문입니다. 그래서 발표를 부탁받으면 준비하는 데 시간을 많이 쏟게 되는 것 같습니다. 제가 공유한 지식이 누군가에게는 긍정적인 도움이 되었으면 좋겠습니다. 지금 다니고 있는 학교에서도 뭔가 발표해 볼 기회가 있으면 좋겠다 싶은데 서강대는 컨퍼런스가 예전엔 Release에서 주최하는 것이 있었다가 요즘은 안 열리는 것 같아 아쉽네요….

초청해 주신 KUCC, 프로그래머스, 그리고 한국항공대학교 소프트웨어학과에 다시 한 번 감사드립니다.

디자인

solved.ac의 복잡한 페이지 구조를 어느 정도 정리하는 작업을 했습니다.

아이덴티티를 정립하는 것을 목표로 전대프연 UCPC 디자인을 했습니다. 웬만하면 앞으로도 이 로고를 유지하려고 합니다.

서강대학교 프로그래밍 대회 디자인도 작업했습니다.

여기 플래티넘 5 주변 이펙트를 만들었습니다.

쓸데없이 멋진 시즌 종료 보상도 만들었습니다.

이외에도 이것저것 자잘한 디자인을 했는데, 모아보고 나니 상당히 적은 양입니다. 올해는 정말 바빴나 봅니다.

일상 이야기

자취 생활 끝

2022년 8월 28일부터의 낙성대 자취 생활은 2023년 2월 28일을 끝으로 끝나게 됩니다. 회사 출근을 위해서 계약했던 집인데, 학교가 마포~신촌 근처라 낙성대에서 통학하기에는 참 애매해졌습니다.

자취 생활은 생각보다 어렵지는 않았습니다. 설거지나 청소는 할 만 했구요, 제일 어려웠던 건 세면대에 걸린 머리카락 빼내는 거였던 것 같습니다. 그리고 새롭게 알게 된 지식은 치킨스톡은 상온에서 곰팡이가 필 수 있다는 사실입니다.

1년 반 동안 살면서 추억을 많이 쌓았습니다. 가령, 이탈리아 방식의 카르보나라를 할 수 있게 됐습니다.

요리도 해 보고, 회사 동료들을 데려와서 보드게임도 하고, 링고 가서 치맥 하고 했던 즐거운 기억들이 생각납니다. 낙성대역 5번 출구에서 언덕을 꽤 올라가야 나오는 집이지만 복학하면 그리워질 것 같습니다.

낙성대 주민을 위해 자취 생활 하면서 자주 갔던/시켜먹었던 가게 목록을 정리해 보겠습니다. 리뷰는 믿지 마세요. 제가 맛을 보장합니다 👍

  • 백채김치찌개 낙성대점(봉천로 590, 낙성대 4출): 깔끔하고 맛있는 김치찌개입니다. 배달보다는 식당에 가서 먹는 게 이득입니다. 다만 식당에 가서 먹으려면 두 명 이상이서 가야 된다는 점이 흠이라면 흠이네요… 보달라에 치즈계란말이로 변경해서 드세요.
  • 쟝 블랑제리(낙성대역길 8, 낙성대 4출): 이 동네에는 왜 체인 빵집이 없나 고민했는데, 이곳 때문인 것 같습니다.
  • 오월의 김밥(봉천로 605, 낙성대 1출): 아침-점심에만 하는 유명한 김밥집입니다. 가게에 가서 주문하면 줄을 오래 서야 될 수도 있어서, 꼭 전화로 예약하고 가지러 가야 합니다.
  • 피자네버슬립스 샤로수길점(봉천로 534 2층, 설입과 낙성대 중간쯤): 페퍼로니 피자는 꼭 드셔보세요. 라지는 엄청나게 크니까 주의하세요… 하프앤하프도 됩니다.
  • 옷살(관악로 164 B1층, 설입 2출): 근본 인도 음식점입니다. 매운맛 단계와 고기 종류를 커스텀할 수 있고, 양도 꽤 됩니다. 카레 여기만큼 하는 곳은 아직 못 봤습니다. 배달도 해 주는데 가끔 맥도날드보다 빨리 옵니다.
  • 삼백돈(남부순환로230길 48, 설입 1출): 삼백돈 체인의 본점입니다. 개인적으로는 돈카츠 진짜 잘 합니다. 정돈에 약간 못 미치는 수준? 배달도 해 줍니다. 이수점이랑 여기서 둘 다 배달이 되는데 여기가 좀 더 낫습니다.
  • 링고(봉천로 518-4 2층, 설입과 낙성대 중간쯤): 알고리즘 하는 사람들한테는 이미 well-known인 호프집입니다. 세계의 수많은 맥주들을 만나볼 수 있습니다. 이런 종류의 맥주가 있었나 싶은 맥주들은 다 여기서 처음 만나봤던 것 같습니다. 제가 스타우트를 제일 좋아한다는 사실도 처음 알았구요.
    근데 여기는 치킨도 진짜 잘합니다. 동네에서 제일 잘하는 것 같아요. 가격대가 좀 있지만, 치킨과 플랑베, 그리고 기네스 칵테일은 꼭 한 번 가서 드셔보시는 걸 추천합니다!

배달 맛집도 정리해 봅니다.

본가에서 통학할지 신촌에 집을 새로 얻을지는 고민 중입니다. 제가 움직이는 데 쓰는 시간을 상당히 아까워해서 통학은 별로 하고 싶지 않을 것 같기도 합니다.

한별이 광고

신분당선 판교역 강남 방면에 걸린 한별이 광고를 보신 적이 있나요? 올해는 생일선물로 무려 지하철 광고를 선물받았습니다! 정말 예쁜 한별이 감사합니다 매일 보면서 퇴근했어요

여러가지 일들

제주도로 휴가를 다녀왔습니다. 9.81파크에서 카트도 타고, 카페 그루브에서 멋진 일몰을 보고, 정말 멋진 경험이었어요.

마작을 배웠습니다. 마장에서 스안커도 해 봤습니다. 쯔모!

아직은 다른 사람 패 안 보고 내 패만 보고 칩니다. 그러니까 레이팅이 안 오르죠..

마치며

다사다난했던 해는 아니었지만, 큰 결정들을 했고 큰 변화를 앞두고 있는 해였습니다. 안정적이던 회사를 나오고 회사를 차렸습니다. 자취 생활도 끝나갑니다. 내년에는 어디로 흘러가게 될까요? 어떻게 되든 할 수 있는 한의 최선을 다하고 싶습니다.

월파 후기는 아직도 쓰지 못했습니다. 빠르게 정리해서 올려 보고 싶은데, 시간이 많이 없었던 것 같습니다. 기억이 사라지기 전에 정리해야겠습니다.

올해도 수고하셨습니다. 내년에도 힘내 봅시다. 새해 복 많이 받으세요! 🎍

모스크바 ICPC 월드 파이널에 다녀왔습니다 (2)

ICPC 월드 파이널 참석 후기 — Привет!

인천공항 코로나 검사센터

버거킹을 먹은 후에는 인터넷으로 미리 코로나 검사를 예약하고 인천공항 코로나 검사센터에서 검사를 받았습니다. 당시에는 보건소에 가면 누구나 무료로 코로나 검사를 받을 수 있던 시절이었지만, 보건소 검사결과는 언제 나올지 모르는 반면 러시아 입국 시각을 기준으로 72시간 내에 받은 검사 결과가 필요했기에 한 명 당 10만 원 가량의 거금을 들여서 검사를 받았습니다.

비행기는 오후 11시 반에 출발합니다. 오후 1시에 PCR 검사를 받고 무려 10시간을 때워야 하는 슬픈 상황입니다.

사실 레드시프트가 해외 대회를 치러 간 건 처음이 아닙니다. 2019년에 태국 방콕 리저널에도 참가했었는데요, 당시 제가 팀노트 25장 × 3권을 무려 잉크젯 프린트로 인쇄하느라 늦어서 공항철도에서 내리자마자 게이트까지 뛰어갔는데도 비행기를 놓칠 뻔 한 적이 있었던지라 이번엔 일찍 공항에 왔습니다.

semteo04의 화려한 카드 마술

카드 셔플 문제의 출제자 semteo04는 서강대학교 마술 동아리 MASU-Z 부원입니다. 시간을 때우면서 신기한 마술들을 볼 수 있었어요.

한별이 아크릴

제가 모스크바 여행을 다녀온다고 하니 solved.ac 일러스트 작가님이 여행객 한별이 아크릴을 선물해주셨습니다. 제가 평소에 메고 다니는 가방이랑 같은 걸 메고 있네요. 저는 정말 성덕이 아닐까요? 이 글을 빌어 다시 한 번 감사의 말씀을 드립니다 🙏 

오래 걸어다니다 보니 피곤하고 덥고 온 몸이 땀 범벅이 돼서 샤워할 수 있는 곳을 알아보다가, 면세영역에 샤워실이 있다고 해서 일단 출국심사를 받았습니다.

사람 없는 공항

오른쪽이 출국심사대입니다. 심각한 코로나 상황을 보여주기라도 하듯 사람이 몇 명 안 보이는 공항 면세영역입니다. 터키나 러시아는 어떤 상황일지, 우리가 다녀오는 동안 우리나라는 어떻게 될지 걱정이 앞섭니다. 면세구역 중앙이라 아직 몇 명 보이기는 하지만 게이트와 가까워질수록 우리 말고는 아무도 없어서 비현실적인 기분이었습니다.

그리고 아쉽게도 코로나 상황 때문에 샤워실은 문을 닫았더라구요.

거대한 비행기와 작은 나

그렇게 이 시국에 해외에 나가보게 되었습니다.

여정표

앞선 포스트에서 언급했던 것과 같이 이 여정은 터키항공 TK091편으로 튀르키예(당시 터키)의 수도 이스탄불까지 날아가고, 여기서 환승해 터키항공 TK413편으로 러시아 브누코보 공항까지 가는 여정이었습니다. 여정표만 보면 5시간 반 정도만에 갈 수 있을 것 같지만 튀르키예와 한국의 시차는 6시간이라 TK091편만 무려 11시간 반이나 걸립니다. 가 본 곳이 전부 아시아뿐이라 6시간 초과의 비행기를 타본 적 없는 저로서는 걱정 반 설렘 반이었어요. 와 내가 드디어 시차 적응이라는 걸 해볼 수 있다니!

운좋게도 제가 창가 자리라서 인천 야경을 찍을 수 있었어요.

인천의 야경

11시간 반 앉아 있으면 굉장히 배고프죠. 밤에 출발한 비행기라서 저녁 기내식이 나왔습니다. 공항에서 저녁을 먹었지만 그냥 또 먹기로 합니다.

비빔밥

기내식은 비빔밥과 물고기 요리 중 하나를 고를 수 있었고 비빔밥은 외국 항공사 기내식 치고는 꽤 맛있었습니다. 터키항공은 튀르키예의 자존심인가?

심지어 이 비행기는 (꽤 비싼 값을 주면) 엄청 느린 위성 인터넷을 쓸 수 있게 해 줍니다. 기내에서 여자친구에게 깜짝 밤인사를 전할 수 있었어요. 트위터를 할 수 있는 속도는 아니었고….

그렇게 밥을 먹고 편하게 잤습니다. 자고 일어나니까 밥을 한 끼 더 줍니다.

아침 기내식

11시간 반 비행이라 기내식이 두 개 나오는 것 같네요. 약간 느끼하지만 맛있었습니다.

어떻게 보면 한나절동안 정말 아무것도 안 하고 앉아만 있는 거라 약간 사육당하는 느낌이 들더라구요. 하지만 피곤했기 때문에 먹고 또 바로 잤어요.

기념사진을 찍는 raararaara 선배를 찍는 shiftpsh의 기념사진

얼마 안 잤는데 튀르키예에 거의 도착해 있었습니다. 11시간 알차게 보냈네요! 답답한 비행을 가장 알차게 보낼 수 있는 방법은 바로 수면이 아닐까 싶네요.

굉장히 숙련된 파일럿이었는지 비행기 착륙을 무슨 고급 세단 승차감이 들도록 할 수 있다는 걸 처음 알았습니다. 터키항공은 신인가?

아무튼 러시아에 가자마자 호텔에서 씻겠다는 다짐으로 가득한 네 명은 지친 몸을 이끌고 환승을 합니다.

이스탄불 국제공항 면세점

이스탄불 국제공항은 웅장한 별천지였고 튀르키예는 다른 세계에 온 건가 싶을 정도로 사람이 많았습니다. 당시 우리나라 방역 상황에서는 상상하기 힘든 인파입니다.

샤워실 안내판이 눈에 띄고 면세점 내에 제가 정말 좋아하는 쉐이크쉑도 있었지만 환승 시간 간격이 그렇게 여유가 있는 편은 아니라서 바로 게이트로 이동하기로 합니다.

튀르키예에서의 아침

현지시각 새벽 5시에 도착했고 새벽 7시 45분 비행기를 타야 되기 때문에 날이 밝아오는 걸 볼 수 있었습니다. 우리나라와의 시차는 6시간이지만 비행기에서 너무 잘 잤는지 시차는 이미 적응해버렸습니다.

환승 티켓

최종 목적지인 모스크바로 출발합시다! 이번엔 두 시간만 가면 됩니다.

아침 기내식

보통 서울-제주 비행기는 기내식을 주지 않는데 터키항공 TK413편은 두 시간 비행임에도 불구하고 아침 기내식을 줍니다! 졸지에 아침 기내식을 두 개 먹어버린 돼지가 되었습니다. 꿀꿀. 근데 맛있었어요. 터키항공은 정말 최고의 항공사가 아닐까….

Привет, Россия!

러오환

긴 여정 끝에 드디어 러시아의 브누코보Внуково 국제공항에 도착했습니다. 셰레메티예보Шереметьево가 인천공항이라면 브누코보는 김포공항쯤의 포지션인 것 같습니다. 튀르키예는 가까운 나라니까요.

입국심사장으로 이동합니다. 러시아는 제1세계 국가들에게는 아직도 까다로운 입국 정책을 유지하고 있습니다. 하지만 적어도 러시아가 우크라이나와 전쟁하기 전까지는 한국의 이미지는 굉장히 좋기 때문에 입국심사는 큰 걱정 없이 통과할 거라고 믿었습니다.

그리고 실제로 두 명은 별 문제 없이 통과했습니다. 영어를 잘 모르는 눈치였는데, 영어로 몇 가지 물어보는 시도를 하더니 그냥 들여보내줬습니다.

하지만 두 명이 통과하고 나니까 입국심사대의 문이 전부 닫히고 다른 두 팀원이 입국심사대 저편에 갇혀 버렸습니다 …?

영문도 모른 채 30분동안 입국심사대를 경계로 두고 불안에 떨고 있었습니다.

나중에 물어보니 함께 입국한 다른 한국인의 일행으로 오해받아서 여권을 압수당하고 이것저것 물어봤다고 합니다. 우리나라도 아니고 남의 나라에서 이런 일을 겪다니 국제 이산가족 비슷한 게 될까 봐 정말 무서웠어요.

코카-콜라 바닐라

무서움은 코카-콜라 바닐라로 녹이기로 합니다.

처음 뵙겠습니다, 모스크바

모든 입국 과정을 무사히 마치고 공항 로비로 나왔더니 ICPC 자원봉사자 분들께서 우리를 기다리고 계셨습니다!

WELCOME!

브누코보는 모스크바와는 조금 거리가 있는 곳이라 모스크바 중심에 있는 숙소로 가려면 꽤 이동해야 합니다. 다행히도 ICPC에서 택시를 지원해 줘서 편하게 이동할 수 있었습니다.

얀덱스 택시

러시아판 카카오+네이버라고 할 수 있는 얀덱스Яндекс 택시를 두 대 불러 이동했습니다. 얀덱스는 검색엔진 회사인데 번역도 하고 택시도 하고 배달도 하고, 게임 플랫폼도 있고, 러시아 국내에서 구글보다 점유율이 높은 것까지 판박이입니다. 하나 다른 건 우리나라의 모든 곳에서 카카오 라이언 캐릭터를 볼 수 있는데 얀덱스는 캐릭터는 없는 거 같다 정도네요.

고속도로를 타고 크라운 플라자 호텔로 가는 길에서 차들을 많이 볼 수 있었는데 그 중에는 한국 중고차도 간간히 보였습니다. ‘최대적재량 4500kg’라는 한글이 적힌 현대 트럭이 인상깊었어요.

모스크바는 이렇게 세 개의 큰 순환도로로 이뤄져 있습니다. 중앙에 있는 순환도로 안에 크렘린과 붉은 광장이 있고, 이 근처에서 ICPC 월드 파이널이 개최됩니다. 우리나라로 치면 브누코보 공항은 김포공항쯤 되고, 대회 장소는 광화문 근처라고 할 수도 있을 것 같습니다. 물론 이제 모스크바 면적은 서울의 4배에 달하기 때문에 광화문 근처에서 이런 대회를 열 수 있는 공간이 있는가 하면 그건 또 모르겠다는 생각이 들지만 여하튼 그렇습니다.

호텔은 대회 장소에서 그렇게 멀지 않은 곳이었습니다. 역시 ICPC 8연속 우승을 차지하고 있는 러시아의 심장 모스크바에서 열리는 ICPC여서 그런지 만반의 준비를 한 것 같다고 느꼈습니다.

로비
객실
객실 뷰

모스크바 강변을 따라 지어진 러시아 건축 양식의 건물들이 보이는 멋진 뷰가 있는 객실이었습니다. 그림같이 아름다워서 눈을 뗄 수가 없었어요.

모스크바 산책

첫째 날에는 다들 시차적응도 해야 했고 십 몇 시간동안 비행기 타고 고생하느라 많이는 못 돌아다녔습니다. 다만 멀리까지 와서 호텔에만 있기는 아까우니까 산책을 나가기로 합니다.

개인적으로 공공디자인에 관심이 많아서 눈여겨봤는데 모스크바의 그것은 꽤 마음에 들었습니다. Moscow Sans를 사용하고 있는데 이런 디자인 언어가 대중교통과 거리 안내판 등 많은 곳에 적용되어 있었습니다.

그리고 사람들이 마스크를 안 쓰고 다닙니다. 실내에서도요! 당시는 2021년 9월이었고 우리나라는 음식점에서 식사를 오후 9시까지밖에 할 수 없었던 시국이었던지라 적잖은 문화충격을 받았죠.

숙소 근처 스몰렌스카야Смоленская 역까지 걸어가서 지하철을 타 보려고 역에 들어가서 노선도를 구경하고 있으니, 역무원 분께서 다가오셔서 미숙한 영어로 노선도에 그려진 붉은 별을 가리키면서 ‘여기 가면 멋진 거리도 있고 레닌 동상도 있다’ 같은 추천을 해주셨지만 여기까지 걸어온 것만 해도 힘에 부쳐서 내일 가 보기로 합니다.

스몰렌스카야 근처에는 아르바트Арбат 거리가 있습니다. 아르바트는 거리의 화가들이 많기로 유명합니다. 그래서 그런지 돌아오는 길에 캔버스에 유화 그림을 그리는 화가 분을 뵐 수 있었어요. 거리에서 그림을 그리는 광경은 우리나라에서는 잘 볼 수 없었던 광경이라서 유럽에 왔다는 실감이 나게 해 주는 무언가였네요.

모스크바 음식

저희와 비슷하게 온 경북대학교 Catdriip 팀과 연락이 닿아서 근처 식당에서 저녁을 먹기로 합니다. 찾아간 곳은 서강대학교 프로그래밍 대회 문제 Ресторан의 소재가 되기도 했던, 레스토랑 마트료시카Ресторан «Матрешка»입니다.

모스크바 강을 따라 걸어가면서 모스크바 야경을 볼 수 있었는데 밤의 모스크바도 엄청 예뻤습니다. 첫 번째 사진 왼쪽의 으리으리한 건물은 호텔이라고 하네요. 레스토랑 앞에는 마트료시카 조각상이 있었어요.

음식점에 들어오니 카운터에서 외투를 보관해 주시고 신발장처럼 번호표를 나눠주셨습니다. 이것도 신기한 부분이었는데, 며칠 살아보면서 느꼈던 부분이라면 러시아 사람들은 외투를 입고 대신 안에 따뜻한 옷을 입지는 않는 것 같았습니다. 실내 온도가 높은 대신 외투 보관소가 대부분의 시설에 있었던 느낌이었어요. 어쩐지 외투 입고 따뜻하게 입으니까 많이 덥더라구요.

왼쪽이 Redshift, 오른쪽이 Catdriip

dogdriip님과는 개인적으로 친분이 있어서 자주 뵈었지만 exqt 님과 skeep194 님은 초면이었습니다. 이쪽도 여러 사정으로 인해 2019년 서울 리저널 팀 구성과는 약간 다른 구성으로 출전했습니다.

메뉴판에 약간 의외의 음식이 보이는데, 러시아에는 의외로 전통 만두Пельмени가 있고 꽤 대중적이라고 합니다. 유럽과 아시아의 영향을 모두 받은 결과일까요?

저는 닭고기 포자르스키 코틀레타Пожарские котлета을 주문했습니다. 이름은 뭔가 치킨까스일 거 같고, 생긴 것도 실제로 도깨비방망이 같은 걸 끼얹은 치킨까스처럼 보이기는 하지만 되게 부드러운 다진 닭고기 튀김입니다.

맛은 예상할 수 있는 맛보다 맛있고, 약간 느끼했고.. 식감은 고로케 같은 느낌이었어요. 고로케도 좋아하고 닭고기도 좋아해서 개인적으로는 꽤 마음에 들었어요! 아마 서울에서 러시아 식당을 갈 일이 생긴다면 메뉴판에서 찾아보게 될 것 같네요.

물이 부족해서 더 달라고 요청했는데 이게 나중에 영수증에 떡하니 적혀 있었다는 점은 조금 당황스러웠네요. 심지어 에비앙… 무려 2,070루블, 당시 가격으로 33,120원이 7인 식사의 물 값으로만 나갔다는 건데… 이럴 때는 한국이 역시 최고인 것 같고 그렇죠.

알 수 없는 사진

러시아는 음식점 9시 영업제한 같은 게 따로 없었어서 늦게까지 맛있게 먹고 야경을 감상하며 천천히 숙소로 돌아왔습니다.

모스크바에서의 하루

아직 ICPC 공식 일정 시작까지는 하루 더 남은 관계로 다음 포스트도 아마 관광 이야기가 될 것 같네요. 1년만에 다시 쓰려니까 기억이 조금씩 사라져가는데 빨리 쓸 걸 하는 후회가 남습니다… 빨리 ICPC 얘기 하고 싶은데 어떻게 대회가 6일치 일정이나 되는지 모르겠네요. 여유가 되는 대로 더 써 보겠습니다!

시리즈: ICPC World Finals Moscow

  1. 모스크바 ICPC 월드 파이널에 다녀왔습니다 (1)
  2. 모스크바 ICPC 월드 파이널에 다녀왔습니다 (2)

모스크바 ICPC 월드 파이널에 다녀왔습니다 (1)

ICPC 월드 파이널 참석 후기

여기 졸업을 앞두고 있는 사람 두 명과 펍지 엔지니어 한 명, 넥슨 엔지니어 한 명이 있습니다. 이 사람들은 어쩌다 이런 시국에 인천공항 버거킹에 모이게 되었을까요.

세렌디피티

휴가를 쓰고 호캉스를 온 날 조식을 먹으러 가려던 찰나 이상한 메일을 받게 됩니다. Fwd: ICPC World Finals Moscow – Sogang University라는 제목의 메일입니다. 월드 파이널? 대체 왜? 하는 심정으로 열어본 메일에는 믿기 힘든 내용이 적혀 있었습니다.

‘서강대학교 ICPC 관련인들께, […] 팀 Redshift가 모스크바에서 열리는 월드 파이널의 참가 자격을 얻게 되었습니다. 10월 1일에서 6일까지 모스크바에 올 수 있으면 됩니다. 한국에서 코로나19가 유행하면서 모스크바까지 오는 것이 힘들지도 모르겠습니다만, (아직까지 참석 가능성에 대한 회신이 없는 관계로) 팀이 정말 희망이 없는지 ICPC 매니저께서 확실히 알아야 합니다. 임 코치님께 회신을 요청해 주시면 감사하겠습니다.’

월드 파이널이라니? 내가? 왜?

2년 전에 ICPC 서울 리저널에서 8위에 오른 적이 있습니다. 8위까지 티켓이 내려갔다니, 싶지만 중요한 건 이게 아닌 것 같습니다. 침착하게 아래에 포워딩된 메일을 읽어봤습니다.

‘안녕하세요 코치님, […] 8월 9일 오후 11:59 CST까지 회신 부탁드리겠습니다. 이 때까지 회신이 없으면 참가하지 못하는 걸로 간주하도록 하겠습니다. 질문이 있으면 자유롭게 회신 부탁드려요. 월드 파이널에서 뵙길 바라겠습니다!’

맙소사, 오늘은 8월 12일인데…

빠르게 머리를 굴려 봅니다. 스팸메일은 아닌 거 같다. 진짜 월드 파이널에 진출한 거 같긴 하다. ICPC 본부에서 8월 9일까지 답장을 주라고 했는데, 8월 12일에 이런 메일이 왔다. 그것도 학회 홈페이지 맨 밑에 적힌 메일 주소로 왔다.

그러면 제가 할 일은 명확했습니다. 최대한 빨리 회신을 보내야 합니다. 바로 코치 교수님과 팀원들에게 전화를 걸어서 협조를 구했습니다.

첫 번째 산: 참가 신청

2019년 레드시프트는 17학번 박건(lvalue), 17학번 이준석(semteo04)과 저(shiftpsh)로 이루어진 팀이었습니다. 같은 나이라서 서로 편하게 반말하고 있어요. 글을 읽고 계신 분들이라면 이름보다는 핸들이 더 익숙할 테니, 앞으로는 핸들로 적도록 하겠습니다.

semteo04는 펍지에서 산업기능요원으로 복무 중입니다. 그렇다는 건 보통 평일 아침에 일어나 있고, 따라서 전화를 받을 수 있다는 뜻입니다. 누구보다 경쟁 프로그래밍에 진심인 친구여서 아마 월파라면 무슨 일이 있어도 휴가를 쓰고 비행기에 함께 오를 것입니다. 그리고 몇 분 안 지나 제가 옳게 봤다는 걸 확인할 수 있었습니다.

lvalue는 졸업하고 KAIST AI대학원에서 연구를 하고 있습니다. 아마 아침에 안 일어나 있을 것입니다. 평소에도 전화를 안 받기로 유명합니다. 나중에 연락하기로 합니다. 다행히도 트위터 맞팔이라, 멘션이나 DM을 보내면 곧잘 확인할 것입니다.

코치 교수님께서는 제 어셈블리프로그래밍 교수님이셨는데, 당시 러시아발 해외입국자는 14일 자가격리가 필요했기 때문에 안타깝게도 본인께서는 참석하지 않길 원하셨습니다. 그리고 이후 받은 lvalue의 연락에서 연구하느라 바빠서 참석하기 어려울 것 같다는 답변을 들었습니다.

이렇게 시작부터 두 가지 문제가 생겼습니다.

  • 코치가 참석할 수 없다면 팀의 참가자격은 유지되는가.
  • 팀원이 참석할 수 없는 경우에도 그러한가.

다행히도 예외적인 경우였기 때문에 팀원을 2019년 혹은 2020년 리저널 참가 이력이 있는 학생으로 대체 가능했으며, 코치가 참석하지 않아도 괜찮다는 답변을 받았습니다.

2021년 레드시프트는 lvalue 대신 전해성(seastar105) 선배와 함께 UCPC에 출전해서 5등상을 받은 바 있습니다. 이 구성으로 다시 출전하고 싶었지만 안타깝게도 seastar105 선배께서는 당해년도 리저널 본선 출전 이력이 없으셨습니다.

그래서 학회 슬랙에서 최대한 빠르게 모집했습니다. 이윤제(yjyj1027) 선배와 이상원(gumgood) 선배께서 빠르게 연락을 주셨습니다. gumgood 선배께서 더 빠르게 연락을 주신 관계로, 이렇게 모스크바행 레드시프트가 결성되었습니다. 메일을 받고 7시간만입니다.

ICPC 시스템에 등록된 화면

이후 임지환(raararaara) 선배께서 co-coach로 오시길 희망하셔서, 이렇게 4명이서 여행 계획을 세우게 되었습니다.

티켓은 10위(UNIST Underdog 팀)와 11위(경북대학교 Catdriip 팀)까지 내려가서 한국에서만 7개 팀이 출전하는 유례없는 해가 되었습니다. 대회 참가를 위해서는 예방접종을 완료해야 했는데, 아시아태평양 지역 내에서 한국과 일부 나라를 제외하고는 백신 수급 상황이 좋지 않거나, 러시아발 입국자에 대한 자가격리 조치가 강력했거나, 아예 입출국을 허용하지 않았습니다. 한국의 비교적 나은 방역 상황으로 인해 운좋게 티켓을 얻었다고 생각합니다.

두 번째 산: 백신

사람들은 종종 제 장점을 강력한 추진력을 가졌다는 것이라고 말합니다. 반대로 말하면 앞만 보고 가느라 사소한 것들을 놓치는 건 약점이라고 할 수 있을 것 같습니다. 일단 참가할 수 있다고 질러놨지만…

참가자들은 예방접종을 완료해야 합니다

…출국 전에 예방접종을 완료해야 했습니다. 출국 예정일은 9월 말, 지금은 8월 12일이었습니다. 50일가량 남은 상황이었습니다. 그러나 fully vaccinated의 의미는 ‘접종 완료 후 14일 경과’이고, ‘접종 완료’는 2차접종이 필요한 백신의 경우 2차접종까지를 의미하기 때문에 2차접종을 36일 안에 받아야 한다는 뜻이 되었습니다.

네 명 모두 1차조차 미접종이었습니다. 당시 Pfizer 백신은 1차와 2차접종 사이 간격이 6주(=42일)였고, 그조차도 접종받기 너무나 어려웠습니다.

먼저 정부의 도움을 얻는 방법을 알아봤습니다. 질병관리청까지 올라갔다 내려온다고 합니다. 왠지 오래 걸릴 것 같은 느낌이 듭니다. ICPC는 소관부처가 어디일까요? ICPC는 경제활동일까요?

초청장이 있긴 하지만 여권번호가 적혀 있지 않아 아마도 승인해주지 않을 것 같았습니다. 그래도 일단 서류를 작성해 보냈습니다.

하지만 만에 하나 불승인되면 출국할 수 없게 됩니다. 불확실한 도박에 걸 수 없었습니다. 모두가 머리를 싸매면서 각자의 방법으로 갖가지 채널로 문의했습니다.

그러던 중 다행히도 저희 어머니께서 동네 병원에 직접 전화를 걸어 예약을 성공하셨습니다. 같은 방법으로 저뿐만 아니라 팀원 모두 동네 브루트포싱으로 1차접종 예약에 성공합니다. 접종일은 바로 이틀 후인 8월 14일이었습니다.

8월 14일은 UCPC 본선이기도 했습니다. 타이레놀 한 알을 먹고 바로 서강대 앞 스터디 카페로 달려가 UCPC 본선을 치뤘습니다.


1차접종은 가능한 한 최대한 빠르게 했지만 2차접종을 앞당기는 것이 필요했습니다. 당시 Pfizer 백신은 6주 후에 접종이 가능했습니다.

다행히도 접종 간격을 앞당기는 것은 보건소에 문의를 넣으면 비교적으로 쉽게 처리할 수 있었습니다. 양천구보건소에 수십 번 전화를 시도한 끝에 접종 간격을 4주로 단축할 수 있었습니다. 팀원 모두가 9월 11일에 2차접종을 완료했고 9월 말 출국 일정에 차질이 없게 되었습니다.

세 번째 산: 여행 일정과 경비

semteo04와 저는 산업기능요원으로 복무 중입니다. 그게 무슨 뜻이냐면 대학생이지만 직장에 다니고 있다는 뜻이고, 그게 무슨 뜻이냐면 여행을 다녀오려면 휴가를 써야 된다는 뜻입니다. 남은 휴가일 수를 고려해서 여행 일정을 잘 짜야 합니다.

또 하나 문제는 여행 경비였습니다. ICPC에서 지원해 주는 것은 대회 기간 중의 숙식 비용뿐이었습니다. 대회 기간을 벗어난 비용과 비행기값은 우리가 부담해야 했고, 이는 결코 만만한 비용은 아닙니다.

학교의 힘을 빌리기로 합니다. 방콕 리저널에 참가했을 때

㉠학교 대표가 아니라서 지원해줄 수 없다, ㉡학교 대표로 중국(2010년 월드 파이널) 갈 때는 지원해줬으니 나중에 ㉢학교 대표가 되어 와라’

는 말을 듣고 살짝 분했던 기억이 있습니다. 이제는 학교가 뭐야 국가대표가 되었으니 당당히 지원해 달라는 연락을 드렸습니다.

하지만 아무리 ㉢학교 대표가 되더라도 시국에 학교가 지원을 해주는 것도 학교 입장에서는 부담스러울 수 있을 거라고 생각했고, 백신 접종 간격을 4주로 단축시키기 위해 + 휴가를 쓰기 위해 당장 항공권이 필요한 상황이었습니다. 그렇게 고민하던 찰나 정말 감사하게도 ㉡학교 대표의 최백준(baekjoon) 선배께서 도와주실 수 있다는 말씀을 해 주셨습니다.

그렇게 외교부 홈페이지를 바쁘게 뒤져보면서 경유 노선을 찾아봤습니다. 유력 후보를 조사한 결과 다음과 같았습니다.

  • (모든 나라) → 러시아: ICPC에서 특별 비자를 발급해 줄 예정
  • 한국 → 폴란드: 도착 후 24시간 이내 출국(경유) 시 자가격리 면제
  • 한국 → 터키: 접종확인서가 있는 경우 자가격리 면제
  • 한국 → 프랑스: Pfizer, Moderna, AstraZeneca 백신 2회 접종 후 2주 경과
  • 한국 → 네덜란드: 접종확인서가 있는 경우 자가격리 면제

따라서 한국 → 러시아, 한국 → 폴란드 → 러시아, 한국 → 터키 → 러시아 중 하나를 타는 게 이상적이어 보였습니다. 가는편으로는 출발 시간이 제일 괜찮아 보였고 최단 소요시간이 붙어 있었던 폴란드항공을 타고 가기로 합니다. 백신 접종 연장을 위해 항공권이 당장 필요했고, 제가 당장 보유 현금은 제일 많았기에 일단 결제했습니다.

이번 달 끼니는 삼각김밥으로 때워야 합니다.

그리고 오는편은 가격이 싼 터키항공으로 예약했습니다. 항공권 예약을 마치고 백신접종 기간도 단축시키고 휴가도 썼습니다. 미필인 semteo04와 저는 국외여행허가서 신청을 완료합니다. 남은 휴가 8일 모두를 러시아에 쏟아부었습니다. 다만…

네 번째 산: 지원 불가, 그리고…

법인카드 결제분만 지원이 가능하며, 그 중에서도 재학생에게만 지원이 가능하다는 답변이 돌아왔습니다. 이미 결제했기 때문에 지원이 힘들다는 것이었습니다. 백준님께는 죄송하게 된 일이지만 사실 그렇게 큰 충격은 아니었습니다.

그러나 진짜 문제는 따로 있었습니다.

당시 러시아는 경유항공편의 경우 경유지를 제한하고 있었습니다. 그 중에 폴란드가 없었습니다.

ICPC 운영 측에 비자 발급을 도와줄 수 있느냐고 여쭤봤더니 ‘러시아 정부 차원에서 입국승인 행정명령을 내렸기 때문에 안심해도 좋다’는 답변이 돌아왔습니다. 불안하지만 일단은 안심합니다.

그러나 진짜 문제는 따로 있었습니다.

오는편이 연착되었습니다. 연착 자체는 큰 문제가 아니지만, 휴가를 전부 소모해버려 이대로면 산업기능요원 복무가 연장되고 맙니다.

결국 불안했던 가는편을 포함해 모든 항공권을 취소하고, 새로 여정을 짜기로 했습니다. 가는편은 9월 28일 터키 경유 밤비행기로, 오는편은 10월 8일 대한항공 직항으로 결정합니다.

새로 항공권을 결제하면서 2명분의 경우 학과 지원을 받을 수 있었고, 나머지 2명분의 경우 네 명이 똑같이 분담하기로 결정했습니다(~32만 원). 싼 값에 러시아 다녀오는 셈 치고요.

ICPC 대시보드의 호텔 예약 UI

ICPC 대시보드에는 호텔 예약 정보 조회 기능도 있습니다. 신기하죠.

호텔은 대회 기간 중에만 지원되었습니다. 여정 중에 대회 기간이 아닌 기간의 경우 따로 결제했습니다. 다행히도 따로 결제한 날들과 지원받은 날들의 예약을 합쳐 주셔서 방을 옮기지 않고 지낼 수 있었습니다.

이제 공항에서 PCR 테스트만 받고 결과지를 챙겨 가면 모든 준비는 끝납니다. PCR 검사 결과가 나올 때까지는 6시간가량이 걸린다고 합니다. 가는편을 밤비행기로 변경한 덕분에 당일에 검사를 받아도 문제없게 되었습니다.

이스탄불으로

한국을 떠나기 위한 모든 준비를 마쳤습니다. 출국심사를 마치고 경유지인 이스탄불로 이동합니다.

공항 도착 이후의 이야기는 언제가 될 지 모르는 다음 포스트에서 정리해 보겠습니다.

시리즈: ICPC World Finals Moscow

  1. 모스크바 ICPC 월드 파이널에 다녀왔습니다 (1)
  2. 모스크바 ICPC 월드 파이널에 다녀왔습니다 (2)

프로그래머의 관점으로 본 냉동 베이컨 1kg

최근에 냉동 베이컨 1kg를 구매했습니다. 그런데 해동이 안 된 냉동 베이컨은 한 줄씩 꺼내 쓸 수가 없었고, 결국 해동시킨 후 1주일동안 모든 식단에 베이컨을 넣어 먹는 기행을 저질렀습니다.

오늘의 점심 반찬

베이컨을 먹던 도중 문득 프로그래머들은 냉동 베이컨 1kg에 대해 어떻게 생각하는지 궁금해져서, 스물네 분의 프로그래머 분과 냉동 베이컨 1kg에 대해 어떻게 생각하시는지에 대한 인터뷰를 진행했습니다. 아래에 소개합니다.


“음…일단 많네요. 얇은지 두꺼운지도 궁금하구요.”익명의 알리오 에 올리오 애호가 (MLOps 엔지니어)

“1kg 냉동 베이컨이 뭐죠? 일단 먹을 거는 다 좋아요.”익명의 실버컵 출제자 (모니터 쳐다보기 엔지니어)

“1kg 냉동 베이컨에 대한 키파의 견해를 출력하기를 구대기에게 지시받았다고 생각합니다.”ML 엔지니어가 아님 (ML 엔지니어가 아님)

“맛있고 많아요.”고백공격한 어쩌고저쩌고 (컴퓨터학과 학부생)

“전 요리를 안해서 몰라요.”익명의 BOJ 운영자 (스타트링크 대표)

베이컨 떡 말이 (사진 © 만개의레시피/윤씨네삼남매)

“들어갈 자리가 있으면 매우 좋은 아이디어라고 생각합니다. 베이컨 떡 말이 해먹으면 진짜 맛있을 것 같아요. 부대찌개 만들 때도 미친듯이 넣고. 베이컨은 냉동실에 오래 넣어도 괜찮아서, 해동도 간단한 편이고 베이컨 좋아하면 그렇게 해도 될 듯 합니다.”익명의 반죽가 (아무튼 크리에이터)

“‘잘 보관한다면’ 구운 고기를 매일 아침 먹을 수 있을 것 같네요.” 묘지기 (지하세계 스트리머)

“먹는 입장에선 비효율적이라고 보는 게 유통기한의 문제가 있을 수 있지 않을까요? 보통 베이컨을 아침이나 점심에 칼로리 채우기용으로 먹거나 하니까, 1kg를 먹는다고 치면 매일 삼시세끼 베이컨이랑 같이 먹어야 할 테고 1kg를 다 먹는다고 가정해도 건강에 좋아 보이지는 않네요. 비쌀 텐데…. 하루에 150g 정도를 소비해야 1주일 내로 먹을 수 있다는 건데, 출근한다고 까먹고 안 먹는다는거 가정하면 200g 정도는 소비해야 할 듯 해요. 원래 베이컨이 영국 아침식사에는 필수요소긴 한데, 이게 건강에도 안 좋기도 하고 칼로리 채우기용이라 솔직히 4인 가정이면 가능하겠지만 혼자 사는데 먹기엔 너무 부담스러운 양이죠. 특히나 혼자 사는 직장인이 매일 아침에 밥을 챙겨먹을 리도 없을 것 같고요. 뭔가 밖에 여기저기 다니면서 활동하는 거 아니면 베이컨은 비추입니다. 기름기도 많고….”익명의 아즈사와 코하네 팬 (연구원)

“로켓프레시로 사면 쌉니다. 바이럴은 아닙니다.”프로그래머 아님 (그래픽 디자이너)

데이터센터 인수 썰

“베이컨을 1kg나 사둘 필요가 있을까 싶지만, 100g 사서 나중에 부족한 것보단 1kg를 사서 쟁여놓는 게 낫지 않나 싶습니다. 데이터센터 인수 썰처럼 더 저렴한 것도 있고요.” 익명의 바다를 헤엄치는 민물고기 (육군? 정보보호병)

“자취생 필수품이군요. 냉동고에 충분한 공간이 있다면 쟁여 놓을 가치가 충분한 물건이네요.”익명의 지나가던 트위터 요정 (전자오락 기술자)

“냉동 베이컨은 안 사봐서 모르겠네요. 하지만 있다면 좋을 것 같네요.” cubelover (넥슨 ML 엔지니어)

“베이컨 맛있지요 😋 근데 여기선 보통 냉장 상태로 판매가 돼서 냉동 베이컨은 경험해 보진 못했네요. 미국인 아침 식사에 필수요소예요.” 익명의 일본식 라면 애호가 (NVIDIA MLOps 엔지니어)

“1kg…. 일단 있으면 먹겠지만…. 생각보다 양이 많아서 냉동시킬 때 요령이 필요할 거 같은 느낌이네요. 종이 호일을 두고 한 장 한 장이나 한 말이 정도씩 나누면 서로 안 붙어서 먹을 때나 보관할 때 편해요.”익명의 체대생 (학부생)

“아무래도 많다…라는 생각밖에 할 수가 없는 양의 고기입니다. 양의 고기가 아니고 돼지의 고기이기는 하지만, 그런 건 아무래도 좋습니다.”키파 (알리오 에 올리오 엔지니어)

베이컨 잼 (사진 © Delish/Lauren Miyashiro)

“적당히 먹고 싶은 만큼 먹고 남은 걸 베이컨 잼 같은걸 만들면 될 것 같아요. 자기가 만들기 싫으면 다른 사람 시키세요.”익명의 퇴사한 직장 상사 (새내기과정학부 3학년)

“저는 그거 갖고 싶어요. 구워서 밥에도 먹고 파스타도 해 먹고 에그 인 헬도 해 먹고 볶음밥도 해 먹고….”익명의 프랑스는 베이컨 (컴퓨터공학과 3학년)

“냉동 베이컨은 몇 달 갈 걸요? 근데 여기저기 넣어먹기 좋아서 예전에 샀는데 금방 다 먹었습니다.”개어렵네요 (대충 써주세요)

“1kg를 언제 다 먹어요?”저는 열심히 써주세요 (대충 쓰면 안돼요)

“그렇게 많이 필요한가요? 베이컨이 유통기한이 짧지 않던가….” 하늘구름 (낙서하는 개팔자)

“직접 사봐서 당사자성이 있는 주제입니다. 파스타와 볶음밥을 무한히 요리해 먹으면 다 먹을 수 있습니다. 근데 1kg씩이나 되는 주제에 냉동이라 예쁘게 안 떨어지는게 정말 화가 납니다.” 익명의 탈수학자 (소프트웨어 엔지니어)

“오 하나 살까요? 사야겠어요.”익명의 김준원 (루팡)

“샌드위치나 파스타 등등에 넣어먹으면 생각보다 금방 먹을 거 같긴 한데, 엄청 물릴 것 같아요….”고양이 (노르웨이 숲 고양이)

“베이컨을 라면에 넣어 먹으면 맛있어요.”익명의 영국인 (영국인?)

“배고파요.”익명의 블로거 (방구석)


어떠셨나요? 프로그래머는 냉동 베이컨 1kg에 대해 어떻게 생각하는지 알 수 있었던 유익한 시간이었던 것 같습니다. 여러분은 냉동 베이컨 1kg에 대해 어떻게 생각하시는지 댓글로 알려주세요!

위드 코로나 체험판 다운로드 및 설치

2021년 회고

ICPC World Finals Moscow

코로나가 올해 12월에는 끝나있을 줄 알았죠. 일일 확진자 수가 최고치를 갱신 중이라는 작년 회고가 무색하게, 연말 확진자 수는 만 명에 가까워지고 있어요. 하지만 위드 코로나 체험판과 이런 시국에 다녀온 월드 파이널 덕분에 작년보다는 여기저기 많이 돌아다녔답니다.

덧없는 인생 목표

운좋게도 ICPC World Finals에 초청받게 되었습니다. 대회에 참여하려면 팀원 세 명이 모두 접종완료여야 하는데 한국의 백신 수급 상황이 좋았던 영향이었습니다. 모스크바 시내도 구경하고, 문제도 구경만 하다 왔어요.

2010년 이후로 11년만에 서강대학교 이름을 올렸습니다

2019년에는 월드 파이널을 그렇게 나가고 싶어했던 것 같은데, 월드 파이널 진출이 나름의 인생 목표였습니다. 그런만큼 엄청 멀게 느껴졌던 곳이기도 했구요. 그런데 이렇게 허무하게 달성해 버렸네요. 마음 한 켠에 애매함이 남습니다. 사실 제가 원했던 건 월드 파이널 진출 자체가 아니라 한국 리저널에서 월드 파이널에 진출할 만한 실력을 갖는 것이었는지도 모르겠습니다.

좋은 경험이었지만 87위라는 성적은 개인적으로는 정말 정말 많이 아쉬웠고, 비록 2019년 서울 리저널 상위 팀이었기에 기회를 잡았던 것도 맞는 말이지만 코로나 시국이 아니었다면 진출하지 못했을 것이기에 목표를 제대로 이루지 못한 것 같다는 생각이 계속 듭니다. 그래서 이미 이룬 목표지만 복학 후에 한 번 더 도전해 보려고 합니다. 아쉬움을 풀고 싶어요.

팀 레드시프트를 찾아보세요!

월드 파이널 참가 및 모스크바 여행 후기를 작성하고 있습니다. 기대해 주세요!

소프트웨어 개발

solved.ac

3.0.0

올해도 작년에 이어 solved.ac 개발에 많은 노력을 쏟았습니다. 올해에도 큼직한 기능들을 정리해 봅시다.

  • 출처 기반 문제 검색. (1월) 문제 출처를 기반으로 검색할 수 있습니다. from:sogang, from:ioi2021 같은 게 되죠.
  • AC 레이팅. (3월) 경험치 기반 티어 산정을 버리고 새로운 레이팅을 도입했습니다.
  • Express로 처음부터 끝까지 다시 구현된 백엔드. (6월)
  • solved.ac 디스코드 및 디스코드 연동. (6월) solved.ac 계정과 Discord 계정을 연결해 solved.ac에서 티어가 변경되면 Discord에서 역할이 바로 변경되게끔 했습니다. 본인의 solved.ac 닉네임을 채팅 닉네임으로 사용해야 하기 때문에 서버 채팅 관리 부담도 적죠.
  • 트위터 연동. (6월) 문제를 풀면 실시간으로 트윗을 올려 줍니다.
  • 스트릭. (7월) 연속으로 문제를 해결한 날짜 수를 계산해 줍니다. 스트릭이 생긴 이후로 문제를 풀고 싶은 마음이 더 생기지 않았나요?
  • 별조각. (10월) 문제를 풀고 기여를 하면 뭔가 재화를 드려요.
  • 문제 해결 이벤트. (11월) 우여곡절은 많았지만 빼빼로 데이 이벤트를 진행했습니다. 진짜 빼빼로를 보내드렸어요.
  • 코인과 코인샵. (11월) 프로필 배경과 스트릭 프리즈를 구매할 수 있어요.

정말 많네요!

3월에 AC 레이팅 업데이트를 하고 나서는 기존에 PHP로 짜여 있던 백엔드를 전부 Express.js로 포팅했는데요, 기존의 백엔드 서버가 EC2에 올라가 있고 제가 FTP로 수정했으며 버전 관리 같은 거 하나도 안 했다면 믿으시겠나요? 지금은 상상할 수도 없는 일이네요.

Github Actions

solved.ac의 API 셋은 기존에도 방대했어서 Express로 포팅하는 데에는 장장 3달이 걸렸습니다. 하지만 포팅이 완료된 6월 이후의 업데이트 내역들을 보면 DP를 참 잘 돌린 거 같아요. 시간이 된다면 포팅 후기도 작성해 보고 싶습니다. 사실 이렇게 말하면 나중에 결국 안 쓰게 되긴 합니다. 시간을 내서 써야 하는 건데 어렵더라구요.

백엔드를 포팅하고 나서 지금까지, 즉 3월부터 12월까지 새로 알게 된 큼지막한 기술과 방법론들을 정리해 보면

  • Github Actions: CI/CD
  • AWS ECR을 통해 ECS에 무중단 배포
    • Github Actions를 사용해 자동 배포까지
  • Sequelize: ORM
  • yarn 워크스페이스와 lerna를 이용해 모노레포 구축
    • 클라이언트와 서버 간 쉬운 코드 공유를 통해 효율적인 작업환경 구축
  • Express로 레이트 리미팅 미들웨어 제작
  • SQL optimizer hints를 이용한 쿼리 최적화 — 문제 고급 검색 속도를 엄청나게 향상했어요

정도가 있겠습니다. 저는 되게 야매로 개발한다고 주장하고 실제로도 그러고 있는데, 이제야 조금 제대로 뭔가를 만들고 있다는 느낌이네요. 그래도 아직 많이 부족하다고 느끼고, 더 성장하고 싶습니다. 이제는 TDD를 해보고 싶은데….

내년에는 새로운 기능 개발보다는 길라잡이를 작성할 수 있는 기반을 마련하는 데 열중하고 싶습니다. 길라잡이가 너무 너무 너무 너무 미뤄졌죠 죄송해요 내년에도잘부탁드려요

뭔가 (상대적으로) 챌린징한 프론트엔드 태스크와 챌린징한 백엔드 태스크를 매년 번갈아 하는 거 같은 느낌이네요. 내년에는 길라잡이 기반을 완성할 수 있을까요?

한국정보올림피아드 대회 프론트엔드

대회 시스템 사용 가이드

올해는 온라인으로 개최된 한국정보올림피아드의 대회 시스템 프론트엔드를 직접 설계 및 개발했습니다. 디자인도 다 했습니다.

수많은 챌린징한 프론트엔드 태스크를 다뤘습니다. 예를 들어…

  • 웹소켓을 통한 실시간 채점 정보 취득
  • 언어 서버가 없어서 완벽하지는 않지만, 약간의 편의를 제공하는 자동완성
  • 크기 조절이 가능한 문제 스테이트먼트 / 코드 에디터 2분할 화면, 너무 길어지면 잘리며 버튼을 누르면 열고 닫을 수 있는 코드 블록, LaTeX 렌더가 가능한 스낵바, 비버챌린지(유저가 상호작용할 수 있는, 캔버스에 랜더하는 자바스크립트 코드를 동적으로 엠베드하기) …
  • 부정행위 예방을 위한 화면 녹화 및 기타 여러 솔루션

등이 있습니다. 더 자세하게 말하지는 못하지만 정말 힘들었던 프로젝트였습니다. 제가 대학생이 되어서 알고리즘 문제해결을 시작해서 그런지 정보올림피아드에 나가보지 못한 걸 아쉬워했는데요, 이렇게라도 참가하게 되어 뿌듯했던 프로젝트였습니다. NYPC도 마찬가지구요!

준비되지 않은 나 앞에 성큼 다가와 버린

파트장

왠진 모르겠는데 회사를 다니다 보니까 직함이 생겼어요…. 와아….

부족한 실력으로 면접관도 되어 보고 회사의 여러 일들에 관여하게 되다가 12월에 파트장으로 발령받았어요. 작은 파트긴 하지만 처음으로 해 보는 매니징이라 잘 해낼 수 있을지 겁나네요.

저 잘 하고 있는 걸까요? 그렇지 않더라도 저를 믿어 주고 계시는 분들께 실망이 되지 않도록 잘해내봐야겠어요

새삼 이 때가 얼마나 좋았는지 실감이 나요. 사실 아직은 저거 ‘팀장님’으로 바꾸면 유효하긴 한데

대회 프로그래밍

NYPC

NYPC 시스템 개발에 이어 올해는 출제를 했습니다.

저는 예선 1번 계단예선 7번 루트가 많은 트리를 냈습니다. 계단 문제는 제가 계단을 하루에 100층씩 오르면서 살을 뺐던 걸 문제로 만든 거고, 루트가 많은 트리는 회사에서 의자에 앉아서 빙글빙글 돌다가 어 이거 괜찮네 하고 낸 문제입니다. 최고의 대회에 제 문제들을 선보일 수 있어서 너무 영광이었습니다!

영상에서 저를 찾아보세요!

대회 운영 참여

작년만큼은 아니지만 올해도 많은 대회의 운영에 참여했습니다.

대신 작년보다 훨씬 많은 문제를 출제했습니다. 이제 문제 은행을 만들어 놓고 대회에 필요할 때마다 하나씩 꺼내 쓰고 있어요.

SPC 2021

특히 NYPC와 SPC는 온사이트로 치뤄져서 즐거웠습니다. 이대로 위드 코로나를 이어가서 Hello 2022를 온사이트로 열면 좋았겠다는 생각은 있었지만 정말 안타깝게도 새로운 변이가 나타나 버렸네요…. 다음 온사이트 대회는 언제 열릴 수 있을까요.

코드포스

2021년의 코드포스 기록

어쩌다 운 좋게 찍은 오렌지를 박제해 두고 기고만장했던 것 같습니다. 1월 28일에 대회를 한 번 치고 11월까지 안 치다가 다시 쳤더니 퍼플을 넘어 블루를 다녀왔습니다.

1년을 잃어버렸습니다. 다시 마음을 다잡아야겠습니다.

대회 참가

올해는 UCPC에 참가자 신분으로 출전했습니다. 의외로 참가자로서는 처음 본선을 나가 봤고, 5등상(12등)이라는 괄목할 만한 성적을 냈습니다.

코드잼 3라운드와 SCPC 수상이 올해의 작은 목표였지만…

SCPC는 잘 모르겠고, 코드잼은 어이없는 실수를 해서 3라운드에 진출하지 못하게 됩니다.

3년 연속으로 코드잼 2라운드에 SCPC 파이널리스트인데요, 올해 목표 내년에는 제발 제발 이룰 수 있었으면 좋겠습니다. 노력해야겠습니다.

이외에도 ICPC 월드 파이널에 참가했습니다.

그래픽 디자인

블렌더

올해는 처음으로 3D를 만져봤습니다. 간단하게 solved.ac 프로필 배경들을 만들어봤습니다.

또 위에도 언급했지만 정보올림피아드 프론트엔드 UI/UX 디자인을 했습니다. 재밌었어요.

올해도 포스터를 만들었습니다.

이외에

심심했던 작년과 달리 올해는 인생 이벤트가 참 많았던 해였습니다.

어쩌다 보니 좋아하는 사람이 생겨서 사귀게 되었습니다.

같이 파스타도 먹으러 가고 돈까스도 먹으러 가고 곰탕도 먹으러 가고 김치찌개도 먹으러 가고 치맥도 하러 가고 카페도 가고 칵테일바도 가고 모든 순간을 함께하고 있습니다. 최고로 행복한 나날들을 보내고 있어요.

그리고 최고의 생일축하를 받았습니다. 절대 잊지 못할 거 같아요.

원래 부모님과 같이 살았는데, 회사가 너무 멀어서 낙성대에서 자취를 시작했습니다. 출퇴근 시간이 왕복 1.5시간 정도 줄었고, 샤로수길에서 배달이 됩니다.

다만 이게 문제가…. 12월부터 6월까지 매일 계단을 100층씩 오르면서 살을 15kg나 뺐는데, 자취 시작하고 나서 배달 음식 자주 먹고 애인과 여기저기 같이 다니다 보니 딱 뺀 만큼 다시 쪄버렸습니다. 다시 빼버리겠다는 결심으로 매일 집 뒷편 산을 오르고 있습니다.

자취하면서 마파두부랑 카르보나라를 자주 해먹었습니다. 요리 실력이 늘었어요. 카르보나라는 크림 카르보나라는 아니고 노른자랑 치즈로만 맛을 내는 카르보나라인데, 많이 연습했더니 이제 노른자를 익히지 않고도 따뜻한 카르보나라를 만들 수 있게 됐습니다. 자취방이 인덕션이 1구라 여전히 조금 어렵긴 해요.

노트북이 고장나서 새로 샀습니다. 메인 작업 컴퓨터로 이미 맥을 쓰고 있긴 하지만, 맥북은 하이퍼커넥트에서 인턴할 때 잠깐 써 본 걸 제외하면 인생 처음으로 써 보네요. 일정 성능 이상이라면 배터리가 오래가는 게 제일 중요하다고 생각해서 14인치 프로 모델로 샀습니다. 잘 산 거 같아요.

마지막으로 한동안 잘 안 보였던 한별이가 올해 다시 돌아왔습니다. 엄청 귀엽지 않나요? 언젠가는 라이브2D를 보고 싶다는 나름의 염원이 있었는데 올해 드디어 이뤄졌습니다.

귀여운 그림도 많이 추가되었어요. solved.ac 프로필 배경에도 많이 등록되었습니다.


올해 신년 목표는 ‘한 해 적당히 잘 보내기’였습니다. 이 정도면 적당히 잘 보냈을까요? 전혀 예상하지 못했던 행복한 일들도 많았고, 제 기고만장함을 반성하게 되는 일들도 있었네요.

내년엔 산업기능요원 복무가 만료됩니다. 회사를 계속 다닐지 복학해서 공부를 일찍 마칠지, 복학한다면 복수전공을 할지 대학원을 준비할지 머릿속에서 고민이 끊이지 않네요.

새해 복 많이 받으세요! 내년에는 위드 코로나 정식판을 즐길 수 있으면 좋겠습니다. 🔔

이른바 명예로운 자가격리를 당한 거지

2020년 회고

강변북로 사진
서강대교에서 찍은 강변북로

올해부터 블로그에 1년 단위로 뭘 했는지 회고를 써 보기로 했습니다. 나중에 잊어버리면 슬프잖아요.

애초에 애인도 친구도 없어서 약속 없는 핑계를 코로나 때문이라고 둘러댈 수 있는 좋은 한 해였습니다. 이른바 명예로운 자가격리를 당한 거죠. 저희 집에서 가장 가까운 박쥐 동굴 방향으로 하루에 세 번 절하고 있습니다.

그래도 코로나가 12월에는 끝나있을 줄 알았는데 그것도 아니더라구요. 일일 확진자 수 최고치 연일 갱신 중이고 저는 집에서 재택근무를 하고 있습니다. 엇 그래도 이제 직장은 있군요 다행이에요

소프트웨어 개발

solved.ac

이미지
살아남았다

올해는 solved.ac 개발에 꽤 집중했습니다. 올해 솔브드에 새로 생긴 큼직한 기능들은 다음과 같습니다.

  • 문제 정렬. (2월) 문제 목록에서 문제 순서를 쉽게 정렬할 수 있습니다.
  • 고급 검색. (2월) 문제 제목뿐 아니라, 맞은 사람 수, 문제 레벨, 내가 푼 문제 등에 필터를 걸 수 있고, AND, OR 등의 연산자를 이용해 검색하는 것이 가능해졌습니다. 검색 쿼리 문법을 직접 만들고, 이를 해석하는 파서 등도 만들었습니다.
  • 프로필 배경. (2월) 프로필을 배경으로 꾸밀 수 있게 되었습니다.
  • 라이벌. (4월) 다른 유저를 라이벌로 등록하고, 라이벌들과 나의 순위를 볼 수 있습니다.
  • 프로필 사진. (5월) 프로필 사진을 올릴 수 있게 되었습니다.
  • 화이트리스트제 종료 및 베타 종료. (6월 5일) 지금은 상상하기 힘들지만, 6월 이전에는 솔브드를 사용하려면 제게 이메일을 보내서 화이트리스트에 등록되어야 했습니다. 6월부터는 기존처럼 크롤링 및 파싱을 하는 방식에서 BOJ에서 유저 정보를 직접 받아오는 방식으로 바뀌어서, 누구나 사이트를 사용할 수 있게 되었습니다.
  • 코드 교환. (8월) 리딤 코드를 입력해 배경과 프로필 뱃지 등을 교환할 수 있게 되었습니다.
  • 자동 갱신. (11월) 이것도 지금은 상상하기 힘들지만, 11월 이전에는 문제를 풀고 나서 프로필에 있는 ‘갱신’ 버튼을 직접 눌러줘야 했습니다. 지금은 문제를 푸는 즉시 경험치가 반영되기 때문에 굳이 갱신 버튼을 누를 필요가 없습니다.

이제 BOJ와의 통합 작업도 거의 마무리되어 solved.ac에 굳이 들어오지 않고도 BOJ에서 solved.ac 문제 난이도와 태그 정보를 확인할 수 있게 되었습니다. 또한, 길라잡이 등의 새로운 기능들이 공개를 앞두고 있습니다. 내년에도 잘 부탁드려요!

Javascript 프레임워크의 세계로

solved.ac의 소스 코드는 원래 대부분 PHP로 되어 있었습니다. 프론트엔드 코드가 복잡해지면서 유지보수에 무리가 갔고, PHP의 특징적인 여러 요소들 때문에 코드 베이스가 PHP인 이상 추가적인 무언가를 개발하기는 힘들겠다 싶었습니다.

그래서 컴포넌트를 만들고 재사용하기 좋다고 들은 React로 무작정 프론트엔드 포팅을 시작했습니다. 검색엔진 최적화도 해야 해서 SSR을 지원해 주는 Next.js도 같이 사용했고요.

당시에는 리액트에 대해 하나도 몰랐지만 지금은 현업에서 매일 사용하고 있을 정도로 익숙해지기 쉬운 프레임워크라고 느낍니다. 진작에 이걸 왜 안 했지? 싶을 정도로요. 참고로 리액트를 쓰기 이전에는 제가 만들었던 사이트들은 아무 프레임워크도 사용하지 않고 오직 vanilla JS로만 돌아갔습니다.

이후에는 Typescript도 적용해 프로젝트를 리팩터했습니다. 타입 추론이 상당한 개발 효율을 가져다주는 것을 체감할 수 있었습니다. 가령 기존에는 API response에 대한 타입 정의가 없어서(게으르게도 명세도 딱히 해 두지 않았었습니다), 필드나 타입을 헷갈려서 오류가 발생하거나 개발 속도가 느렸었는데, 지금은 타입 정의를 열심히 만들어서 제 human error로 오류가 발생할 수 있는 가능성을 대폭 줄였습니다. 되게 기본적인 거지만 나름 뿌듯했던 경험이라 소스 코드를 첨부해 공유해 봅니다.

type SolvedPageContext = NextPageContext & GlobalProps

export type SolvedPage<
  P = { siteTitle?: string[] },
  IP = P
> = NextComponentType<
  SolvedPageContext,
  IP & { siteTitle?: string[] },
  P & { siteTitle?: string[] }
>

export default SolvedPageContext

이렇게 정의하면 페이지의 Props의 타입 정의가 어떤지에 따라 getInitialProps에서 반환해 줘야 하는 타입이 결정됩니다. 아래 페이지의 경우 props.result의 타입이 Problem[]으로 정해져 있기 때문에 ProblemList에서 렌더 로직을 짜기가 상당히 편해집니다. 에디터 연동은 두말할 것도 없구요.

type Props = SolvedApiResponse<SearchProblems>

const LevelProblems: SolvedPage<Props> = (props) => {
  // ...
  return (
    <PageLayout>
      <h1>
        <TierMark value={level} locked={false} showName={true} />
        {caption ? ` — ${caption}` : null}
      </h1>
      <ProblemSortController
        currentSort={newQuery.sort}
        currentDirection={newQuery.direction}
      />
      <div>
        <ProblemList
          result={props.result}
          page={page}
          keys={['id', 'title', 'solved_count', 'average_try']}
        />
      </div>
    </PageLayout>
  )
}

LevelProblems.getInitialProps = async (ctx) => {
  // ...
  try {
    const response = await SolvedApi<SearchProblems>(token).get(
      '/search/problems.json',
      {
        params: {
          query: queryString,
          page: +(page ?? 1),
          sort: sort ?? ctx.currentSettings?.problem_sort_by,
          sort_direction:
            direction ?? ctx.currentSettings?.problem_sort_direction,
        },
      }
    )
    return {
      siteTitle: ['문제', '레벨', levelName(+(level ?? 0))],
      ...response.data,
    }
  } catch (e) {
    // ...
  }
}

여하튼 이런 식으로 기존에 PHP로 짜여 있었던 프론트엔드를 몇 달에 걸쳐 전부 React + Typescript + Next.js로 다시 짰습니다.

안타깝게도 백엔드는 아직도 PHP로 되어 있습니다. 현재는 길라잡이를 만들면서 백엔드도 Node + Express로 다시 구현하려는 계획을 갖고 있습니다. 완료되면 solved.ac에서 PHP 코드를 찾아보기 힘들게 되겠네요.

취업

넥하

위의 개발 경험 덕분에 6월 중순부터 넥슨컴퍼니 산하의 엔진스튜디오에서 일하게 되었습니다. 회고를 쓰고 있는 지금 시점으로 입사한 지 벌써 반 년이 넘었네요.

게임회사지만 제 주 업무는 웹 프론트엔드 엔지니어입니다. 사내외 여러 서비스의 개발을 맡아 하고 있습니다. 어떤 서비스라고 말하긴 그렇지만 아마 이 글을 읽고 계신 분들 중 적지 않은 분들께서 제가 작업했던 서비스를 이미 사용해 보셨을 겁니다. 😉

이미지
서버는 오로라

여담으로, 회사에서 매달 넥슨캐시를 일정량 지급하는데 쓸 데가 딱히 없어서 메이플스토리를 시작했습니다. 이제 모라스 코앞이네요. 12월 30일에 모라스에 갔습니다. 어쩌다 보니 받는 것보다 많이 결제하고 있지만 결제한 만큼 월급으로 돌려(?)주니 괜찮지 않을까라고 생각하고 있어요..


대회 프로그래밍

코드포스

올해는 그토록 염원하던 오렌지를 드디어 갔습니다.

2100

근데 레이팅이 딱 2100점입니다.

근데 이 어려운 걸 한 번 더 해냅니다.

+0

이 사람은 대체 뭐 하는 사람일까요? 대체 어떻게 했던 걸까요?

오렌지 수문장

그래프가 딱 2100에 걸쳐 있습니다.

오렌지가 되니까 Div 1 이외에서는 레이팅 변동이 일어나지 않습니다. 근데 Div 1은 자주 열리지도 않고, 열리는 날에는 제가 뭔가 바빠서 매번 못 치게 되더랍니다. 뭐 한마디로 게을러진 거죠. 복학할 때 적의환향하겠다던 시프트는 대체 어디로 가고? 다시 열심히 쳐야겠어요.

대회 개최

이미지
보셨나요? 저의 15 연속 검수!

UCPC 2020을 개최하고, 많은 대회에서 검수 및 출제를 했습니다.

  • 진짜 최종 구데기컵 2 – 출제, 검수
  • UCPC 2020 (전대프연 여름 대회) – 운영 총괄, 출제, 검수, 조판
  • SUAPC 2020 (신촌지역 연합 여름 대회) – 출제, 검수, 조판
  • 신촌지역 연합 캠프 2020 – 검수
  • SNUPC 2020 (서울대학교) – 검수
  • Uni-CODE 2020 (UNIST) – 검수, 조판
  • SPC 2020 (서강대학교) – 검수, 조판

알고리즘 문제 제작과 검수, 프로그래밍 대회 진행 프로세스에 대해 과도할 정도로 많은 것들을 배울 수 있었던 한 해였습니다. 특히 글을 잘 쓰는 법을 배울 수 있었어요. 기회가 되면 SUAPC/SPC 출제/검수 후기도 작성해 보고 싶습니다.

대회 참가

여러 대회에 참가했으나 올해는 다소 부진했습니다.

  • ICPC Asia-Seoul 2020 National First Round – 팀 Redshift로 출전, 5/12솔브 #36
    • 풀이를 옳게 생각했던 건 3문제나 더 있었는데.. 강의실 키보드 탓을 했습니다.
  • SCPC 2020 – Finalist, 172/1000
    • 4번 문제가 되게 풀릴 거 같이 생겼길래 3시간동안 4번 문제만 잡다가 결국 못 풀고 망했습니다. 점수를 긁읍시다 여러분.

팀 연습 때는 NxxRC 8~10솔브 밀고 다녀서 잘하겠지 싶었는데 막상 한국 예선에서 저런 성적이 나와서 당황스러웠습니다. 개인 연습 부족인 거 같네요.

…적의환향 할 수 있을까요?

스터디 진행

Sogang ICPC Team에서 연초에 아래 주제들을 다루는 스터디를 진행했습니다.


그래픽 디자인

많은 프로그래밍 대회 운영에 참가하면서, 자연스럽게도 관련 포스터를 만들게 됐습니다.


프로그래밍 대회 문제들에 들어가는 그래픽도 많이 만들었습니다.


solved.ac 공식 SNS 계정이 생기면서 정사각형 모양의 그래픽도 만들었습니다.

solved.ac 웹 디자인은 포토샵이나 일러스트를 켜서 하지 않고 CSS로 직접 하기 때문에 따로 목업 디자인 같은 건 따로 없습니다.

아쉽게도 예전처럼 개인작을 만들거나 할 여유는 없었네요.


이외에

휴학하고 회사 다니면서 아무것도 안 한 줄 알았는데 정리해 보니까 뭔가 한 게 꽤 있었네요. 건강검진에서 많이 쉬라는 소리를 들어서 내년 목표는 바쁘지 않게 한 해를 보내는 것으로 해야겠습니다.

이미지
갤럭시 노트20 울트라 5G

휴대폰을 갤럭시 노트 20으로 바꿨어요. 흰색이 정말 예쁘길래 흰색으로 샀는데 잘한 선택인 거 같아요. 5G폰이지만 5G가 너무 안 터진다는 소리가 많아서 5G를 쓰지 않기 위해 자급제로 샀습니다. 근데 정작 노트에서 가장 중요한 기능이라고 할 수 있는 S펜은 자주 안 쓰게 되더라구요. 왼쪽에 달려 있어서 그런가..

라프텔

저어어엉말 오랜만에 애니메이션을 열심히 봤습니다. 넷플릭스도 열심히 봤습니다. 베스 하먼을 보고 체스 세트를 샀어요. 근데 잘 못 두는 거 같네요.

이미지
신도림역 출발열차 (특징: 신도림에서 출발함)

신도림역 출발열차의 존재를 알고 삶의 질이 올라갔어요.

이미지
츄니즘

세가의 리듬게임 ‘츄니즘’이 한국에 정식 발매되어서 휴가 쓰고 한주 내내 다녀왔어요.

이미지
서강대교에서 찍은 여의도

자전거를 유난히 많이 탔던 해였던 거 같기도 하네요. 특히 학교에서 놀거나 문제 풀다가 or 상수역 오락실에서 놀다가 서강대교 건너서 집에 따릉이 타고 자주 왔는데, 이제는 코로나 시국이 심해져서 자전거 타고 밖에 돌아다니기도 눈치 보이게 되었어요. 코로나가 없던 시절이 너무 그립네요..


솔브드 백엔드 Node.js 포팅도 마치고 싶었고, 그림도 그릴 줄 알게 되면 좋겠다 싶었고, 코드포스 레드도 가고 싶었고, 되게 하고 싶었던 게 많았어요. 다 못 이뤄서 올해 별로 한 게 없었던 줄 알았는데.. 정리해 보니까 이런 시국 속에서도 올해 되게 뭔가 많이 했었네요 😅 제가 너무 하고 싶은 게 많았나봐요. 좀 한가하게 살아도 되겠습니다. 건강검진에서도 많이 쉬라는 소리를 들었구요.

이 정도면 올해 나름 잘 보냈네요. 신년 목표도 한 해 적당히 잘 보내는 걸로 해야겠습니다. 새해 복 많이 받으세요~ 🔔

UCPC 2020을 개최했습니다

UCPC 2020 개최 후기

기회가 되어 올해 전국 대학생 프로그래밍 대회 동아리 연합전대프연 회장을 맡아 UCPC 2020을 개최했습니다. 2019 서강대학교 프로그래밍 대회에 이은 두 번째 대회 운영입니다.

전대프연은 알고리즘 문제해결을 좋아하는 25개 대학교의 26개 동아리의 연합이고, UCPC는 전대프연에서 매년 개최하는 프로그래밍 대회입니다. 보통 가을에 열리는 국제 대학생 프로그래밍 경시대회 한국 리저널의 연습 격 대회로 시작해서, 지금은 국내에서 열리는 프로그래밍 대회 중에서 커뮤니티 대회로는 가장 큰 규모를 갖고 있습니다.

왜 하겠다고 했나요?

대회를 코디네이트하는 건 힘듭니다. 그래서 선뜻 총대를 매겠다고 나서는 경우는 드물고, 실제로 3년 전엔 대회가 안 열린 적도 있었습니다. 4월이 되어도 아무도 대회 총괄을 하려는 사람이 없어 올해는 제가 열어보겠다고 했습니다. 저는 당시 휴학 무직 백수로 즐겁게 하루종일 뒹굴뒹굴 감자칩 먹으면서 매일 컴퓨터랑 눈싸움이나 하고 있었는데, 아마 휴학하고 있지 않았다면 상당히 바빴을 테니 나서지도 않지 않았을까 싶습니다.

인수인계를 받자마자 대회 기획을 시작하고, 출제자를 모집했습니다. 그러나 올해는 큰 문제가 있었습니다. 경우에 따라 기획의 근간이 바뀔 수도 있는 아주 큰 문제였습니다. 바로..

준비되지 않은 우리 앞에 성큼 다가와 버린 코로나 시대

코로나 큐

2020년을 살아가는 여러분께서는 모두 마음 속에 우선순위 큐 하나쯤을 갖고 계실 겁니다. 바로 코로나 시대가 끝나면 할 일이라는 이름의 우선순위 큐입니다. 저는 벌써 원소가 120개를 넘어가려고 합니다. 코로나 끝나면 여행 가야지, 코로나 끝나면 맛집 탐방 다녀야지, 코로나 끝나면 못 봤던 친구들 만나서 밥 먹어야지, … 분명 4월즈음에만 해도 큐가 이렇게 커질 거라고는 생각하지 못했습니다. 상황이 괜찮아질 줄 알았으니까요.

UCPC도 마찬가지였습니다. 대회가 열릴 7월즈음에는 상황이 괜찮아지겠지-라는 막연한 기대가 있었습니다. 그래서 오프라인으로 대회를 진행하려고 계획했습니다. 오프라인으로 개최하는 것이 좋은 이유를 나열해 보자면:

  • UCPC는 프로그래밍 대회 동아리 회원들의 교류와 경쟁의 장을 목표로 하고 있습니다.
  • 부정행위 검사가 힘듭니다. 참가자가 다른 팀 코드를 베꼈는지는 쉽게 알 수 있습니다. 하지만, 예를 들어, 3인 팀 대회인 UCPC에서 4인 이상의 팀원이 코드를 작성한다던가, (진짜 정말 극단적인 예시로) 대회 중에 tourist에게 문제 해법을 물어보고 이를 이용해 해결하는 등의 부정행위는 막기 힘드며 검사하는 것도 거의 불가능에 가깝습니다.
  • UCPC와 같은 규모의 대회에는 운영비가 많이 필요합니다. 그래서 스폰서의 도움이 절실합니다. 하지만 온라인으로 진행할 경우 오프라인으로 진행하는 것보다 스폰서에게 후원에 대한 메리트를 어떻게 줄 수 있을지 생각해내고 이를 어필하는 것이 상대적으로 어렵습니다.

반면 온라인으로 개최하는 것도 나름의 장점이 있습니다.

  • 예산에서 대관료를 고려할 필요가 없어집니다.
  • 대회장에 오지 않아도 됩니다. 지방에서 서울로 올라와서 참가하시는 분들의 경우 대회 참여를 위해 만 하루를 잡고 참가하시는 경우가 흔하다고 들었습니다. 이런 모든 비용을 절감할 수 있습니다.

분명 온라인 대회로 진행해서 얻을 수 있는 장점들도 있지만, 오프라인 대회로 개최하는 것의 장점이 훨씬 크리티컬했기에 할 수만 있다면 오프라인으로 진행하고 싶었습니다.

그러나 모두가 아시는 대로…

…하루 10명대였던 확진 판정은 갑자기 다시 30명, 40명, 80명이 되었고, 오프라인 대회로 개최할 경우 스태프가 방역을 책임질 수 없겠다는 생각이 들어 오프라인 개최를 포기하게 되었습니다.

정작 이 글을 쓰고 있는 시점에서는 일일 확진자가 100명 넘게 발생하고 있네요.

온라인이기 때문에 할 수 있는 것을 하기

그래서 할 수 있는 거라도 최대한 재밌게 해 보기로 했습니다. 일단 위에서 오프라인 대회의 장점으로 언급되었던 것들을 온라인으로 어떻게 살릴 수 있을지에 대해 먼저 고민해 봤습니다.

  • 교류와 경쟁의 장 제공 – 기존에 대회장에서 하던 풀이 방송과 스코어보드 방송을 Twitch 온라인 방송을 통해 진행하기로 합니다. 물리적인 공간보다는 덜하겠지만, 실시간 댓글을 통해 교류할 수 있게 됩니다.
  • 스폰서 어필 – 온라인 방송 중 방송 화면의 공간을 일부 활용해 스폰서 로고를 지속적으로 노출합니다. 스튜디오가 구해진다면 후원 세션을 참가자들이 가장 많이 볼 시간대인 대회 종료 직후 ~ 문제 해설 전에 진행합니다.

부정행위에 대한 고민이 가장 많았습니다. 대략 다음과 같은 의식의 흐름을 거쳤습니다.

  • 웹캠이 있으면 부정행위를 막을 수 있을까?
    • 웹캠이 있다고 해도 스크린에 카카오톡 같은 걸 띄우면 충분히 부정행위를 할 수 있지 않을까? 그럼 스크린 녹화도 필요할까?
    • 스크린 녹화를 하더라도 다른 장비가 있으면 충분히 부정행위를 할 수 있지 않을까?
    • 애초에 참가팀 50팀이 동시 접속할 수 있는 화상 채팅 서비스가 존재할까?
    • 존재한다고 하든 안 하든 우리가 그 화면을 전부 모니터링할 수 있는 여력이 있을까?
  • 웹캠은 힘들 것 같으니 카피 체크를 하자
    • 팀 간의 복붙은 막을 수 있겠지만 4명 이상이 한 팀으로 친 경우는 어떻게 막을 수 있을까?
    • 4명 이상이 한 팀으로 치지 않았더라도, 예를 들어 누군가 대회 중에 대회 문제를 random Codeforces red한테 물어봐서 푼다면? 어떻게 막을 수 있을까?
    • 그 코드는 언제 다 읽을까?
  • 결국 어떻게 해도 부정행위를 막을 수는 없는 거 아닌가?
  • 근데 어차피 부정행위 해서 높은 점수 받고 못 보던 사람이 스코어보드 위에 있는 상황이 발생하면 다 티나지 않을까?

결론은 PS 커뮤니티를 믿고 코드 카피 체크 이외의 별도의 부정행위 검사를 하지 않는 것으로 났습니다. 커뮤니티 대회였기에 가능했던 결정이었습니다. 큰 상금이 걸린 기업 대회였다면 이런 상황에서 상당히 곤란했을 것입니다.

인터넷 방송

Twitch Sports: Getting Started | Twitch Blog
인터넷 방송 플랫폼 트위치

그렇게 결정하고 나니 인터넷 방송이 대회 기획에서 출제와 검수를 제외한 가장 중요한 요소가 되었습니다. 프로그래밍 대회에 많이 참여해 보셨고 (무려 ICPC 월드 파이널!) 관련 스트림도 자주 하시는, 세계적인 인기를 자랑하는 월클(World Class) 스타 정재헌Gravekper님께 참여해주실 수 있는지 여쭸고, 흔쾌히 승낙해 주셔서 함께 온라인 방송을 기획하게 되었습니다.

방송에서 뭘 다루면 좋을지, 방송을 언제부터 켜면 좋을지, 화면은 어떻게 구성하면 좋을지 등등을 대회 직전까지 열심히 논의했습니다. 인터넷 방송에는 문제 풀이, 스코어보드, 후원 세션은 필수로 들어가야 했고, 이외에 대회에 참여하는 사람들도, 참여하지 않는 사람들도 모두 볼 수 있다는 점을 감안하면서 대회 종료 전에 뭘 하면 좋을까를 고민했습니다. 이에 온라인 방송이 있는 다른 대회들을 참고했습니다.

  • ICPCIOI는 대회 중에 실시간 스코어보드와 문제 해설을 보여줍니다. ICPC 방송은 생각보다 재밌습니다. 그래서 사실 제가 하고 싶었던 이상에 가까웠던 방송 형태이긴 하나, 온라인 대회이고 웹캠 사용을 포기했기 때문에 화면에 보여줄 수 있는 게 없었고, UCPC 방송은 대회 참가자들도 볼 수 있는 방송이었기에 문제 해설도 보여줄 수 없었습니다.
  • 반면 Google Hash Code 방송은 참가자들이 대회 중에 시청할 수 있습니다. 그래서 대회 시작 전후에만 방송을 하고, 대회 중에는 아무것도 보여주지 않습니다.

하지만 대회 중에 아무것도 보여주지 않으면 심심하기 때문에 간단히 스코어보드를 띄워 두기로 결정했습니다.

문제 풀이와 후원 세션도 걱정이었습니다. 지금까지 UCPC 풀이는 출제자가 강단에 나와 슬라이드를 보여주는 식으로 진행했고, 후원 세션도 마찬가지였습니다. 근데 올해는 어쩌죠?

다행히 감사하게도 작년에 이어 고려대학교 SW중심대학사업단에서 장소를 제공해 주셔서, 고려대학교 정보대학의 대형 강의실 하나를 스튜디오로 사용할 수 있었습니다. 기존처럼 출제진이 강단에서 슬라이드로 발표하고 이를 카메라로 찍어 방송할 수 있었습니다.

출제와 검수

코로나 시대가 되어도 프로그래밍 대회에서 변하지 않는 것은 바로 출제와 검수입니다. 올해는 제가 여름에 회사에 갈 걸 우려해 대회 준비를 일찍 시작했습니다. 출제진은 우리나라 최대의 알고리즘 문제해결 커뮤니티인 BOJ Slack에서 모집했고, 이후에 추가로 call for tasks를 통해 문제 공모를 받았습니다. 올해는 공모받은 문제가 많아 출제진 풀이 상당히 컸습니다.

슬랙

기획을 포함해 모든 소통은 Slack으로 진행했습니다. Slack의 (무료 버전의) 최대 단점은 메시지가 10,000개 이상 쌓이면 이전 메시지들은 하나씩 못 보게 된다는 것인데요, 마침 코로나로 인해 Slack에서 3달간 무료로 Standard Plan을 제공해 주고 있어서 고민 없이 사용했습니다.

문제마다 하나의 채널을 만들어 최대한 맥락을 잃지 않고 대화할 수 있도록 했습니다. 또한 대회 전반적인 공지를 올릴 #general 채널, 인터넷 방송을 기획할 #broadcasting 채널, 컨테스트 도중 생기는 라이브 이슈에 대응할 #contest-finals / #contest-preliminaries 채널 등을 필요에 따라 주제 단위로 만들어 활용했습니다.

Zapier

특히 박수찬tncks0121님의 도움을 받아, Slack과 Zapier 연동을 사용해 call for tasks로 메일을 받으면 메일 내용을 자동으로 Slack 채널에 포워딩해 주도록 설정할 수 있었습니다. 다만 Zapier의 문제인지 후술할 UCPC 메일서버 문제인지는 모르겠지만 메일이 몇 개 누락되는 경우가 생겼습니다. 이런 경우엔 제가 UCPC 메일함에서 직접 공모받은 문제를 출제 채널에 배달해야 했습니다.

구글 드라이브

출제/검수 현황과 문제 자료 관리 등에는 Google Drive를 사용했습니다. G Suite에 제공되는 기능인 공유 드라이브를 적극적으로 활용했습니다.

출제

대회 분위기 정하기

출제 초기에는 예선과 본선 각각의 적절한 난이도 커브를 결정해 주는 것이 중요합니다. 문제들이 너무 쉬우면 대회 중에 문제를 전부 해결하는 팀은 대회가 끝날 때까지 할 게 없어서 심심해지고, 반대로 너무 어려우면 문제들에 압도당한 팀들이 좌절하게 되기 때문입니다. 그래서 먼저 난이도 커브를 정하고, 이에 맞춰서 어떤 문제를 내야 할지, 문제 풀에서 어떤 문제는 사용하고 어떤 문제는 사용하지 말아야 할지 등을 결정할 수 있습니다. 작년 서강대 대회 출제 후기에서 언급했던 것이기도 합니다.

UCPC 2020 출제 현황 시트 – 블로그 글의 이해를 돕기 위해 연출되었습니다

이와 관련해 작년 UCPC와 올해 UCPC의 가장 큰 차이는 문제의 난이도를 가늠할 수 있는 수단인 solved.ac의 존재였습니다. 서울 리저널의 난이도 분포를 참고해서 문제 풀에 있는 문제들의 난이도들을 각자 가늠해 보고, 예선과 본선 중 어느 쪽에 사용할지 플로우를 잘 돌렸습니다. 또한 시트에 추가적으로 알고리즘 분류를 적어 넣어, 한 분야에 너무 치우친 컨테스트가 되지 않도록 문제 배치를 잘 해주었습니다. 다만 검수 과정에서 난이도와 분류 정보를 보는 것은검수에 악영향을 끼칠 수 있어서 해당 시트는 출제진만이 편집했고, 검수 현황 시트를 따로 만들어 두었습니다.

문제 난이도를 가늠하는 현장

Call for tasks로 공모받은 문제들도 이렇게 출제진끼리 난이도를 가늠해 보고 대회에 필요하리라 생각된 문제들을 채용했습니다. 공모받은 문제들과 내부에서 출제한 문제들이 많아서 아쉽게도 사용할 수 없게 된 문제가 많았습니다.

디스크립션과 데이터 작성

Polygon

데이터의 무결성을 최대한 보장하기 위해 디스크립션 작성을 제외한 모든 작업은 Polygon에서 testlib을 사용해 진행했습니다. Polygon 서버가 다소 불안정해서 조마조마한 상황이 몇 번 있었고, 패키지 전체를 자주 백업했습니다.

solved.ac Overleaf

문제지는 solved.ac 서버에 올라가 있는 비밀의 시크릿 프린세스 self-hosted Overleaf에서 작업했습니다.

디스크립션데이터 작성에 있어서는 대회 참가자가 문제 디스크립션을 이해하거나 기타 문제에서 중요하지 않다고 생각되는 이슈들을 해결하는 데 시간을 소비하지 않도록 하게 하기 위해 다음 원칙에 따라 UCPC 출제 컨벤션을 만들고 이를 최대한 지키려 노력했습니다.

  • 일부러 디스크립션을 이해하기 어렵게 하는 컨셉의 문제가 아닌 경우, 디스크립션은 한 번만 읽어도 이해할 수 있을 정도로 이해하기 쉬워야 하며, 디스크립션이 문제 해결을 방해해선 안 됩니다.
    • 같은 맥락에서 어려운 수학 기호 및 개념은 가능할 경우 최대한 사용하지 않습니다. 갓 고등학교를 졸업한 사람이 봐도 이해할 수 있는 수준이어야 합니다. 이를테면, ‘$A$의 모든 원소들의 제곱의 합’이라고 적을 수 있는 것을 굳이 ‘$\sum_{a\in A} a^2$’라고 적지 않습니다.
    • 글과 문자가 쉽게 구분되면서 문자가 글을 읽는 데 방해가 되는 일이 없도록 해야 합니다. 따라서 모든 문자는 기울임꼴로 작성하고, 수식에는 띄어쓰기를 잘 하며, 기호는 정확한 것을 사용해야 합니다.
  • 입출력 변수의 범위는 입출력 섹션에 한꺼번에 명시하는 것이 가장 좋습니다.
  • 데이터는 무결해야 합니다. 명시한 형식과 다른 데이터가 있어서는 안 되며, 입력 데이터에 대한 정답이 아닌 데이터가 출력 데이터로 되어 있어서는 안 됩니다.
  • 생소한 입출력 방법 등으로 참가자가 고생하는 일이 없어야 합니다. 특히 EOF로 출력의 끝을 명시하는 입력 데이터들이 그렇습니다.

또한 디스크립션을 굳이 Polygon에서 작업하지 않은 이유가 있다면, BOJ의 문제 출제 플랫폼인 BOJ Stack의 존재 때문입니다. BOJ에서 대회를 개최하기 때문에 대회 전에 문제들을 전부 BOJ로 옮겨야 하는데요, 대회 직전에는 디스크립션 수정이 잦습니다. 근데 Polygon에서 디스크립션을 관리하게 되면 어차피 만들어야 하는 문제지에서도 디스크립션을 수정해야 하고, BOJ Stack에서도 디스크립션을 수정해야 합니다. 또한 BOJ Stack에서는 LaTeX을 최대한 쓰지 말아달라고 하기 때문에 TeX로 작성한 문제들을 전부 HTML로, 이를테면 $1 \leq N, M \leq 200\ 000$ $1 \leq N, M \leq 200\ 000$과 같은 식은 1 ≤ N, M ≤ 200 1 &le; <em>N</em>, <em>M</em> &le; 200 000으로 다시 포맷해야 하는데, 이는 생각보다 상당히 고통스럽습니다. 이런 공수를 줄이고자 Overleaf에서만 디스크립션을 관리했습니다.

물론 HTML로 포맷하는 공수조차 줄이고자 그냥 모든 문제에 TeX을 사용했습니다. 이렇게 할 경우 Overleaf에서 Stack으로 문제 본문을 복사+붙여넣기 하면 세팅이 끝납니다. 참 쉽죠.

문제 삽화가 그려지는 과정

문제와 해설에 사용될 그림의 경우, 그림을 요청하는 채널을 따로 만들어서 출제진의 요청을 받고 제가 그림을 열심히 제작했습니다.

마지막으로 정해는 ICPC 경향에 맞춰 C++과 Kotlin(또는 Java)으로 모두 작성했고, 해당 언어들로 문제를 해결 가능함을 보장했습니다.

검수

문제 초안이 완성되면, 문제를 검증하게 됩니다. 주로 다음과 같은 항목들을 검증해야 합니다.

  • 데이터와 디스크립션의 포매팅이 올바르고well-formed 무결한지 (UCPC 컨벤션을 지키는지)
  • 출제자의 풀이가 완벽한지
  • 출제자가 의도하지 않은 풀이로 풀리지는 않는지, 출제자가 의도하지 않은 풀이로 풀렸다면 그 풀이도 정답으로 허용할 것인지

검수진은 바로 위와 같은 항목들을 꼼꼼히 확인하는 역할을 합니다. 출제진들 사이의 교차 검수crosschecking 이외에도 외부 검수진을 모셔 와 검수를 진행했습니다.

검수의 흔적

참가팀들이 틀린 방법으로 접근할 것 같은 풀이(‘사풀이’라고도 합니다)를 미리 예상하고, 이를 적절히 막습니다. 방법은 여러 가지입니다. 예를 들어,

  • 어떤 자연수 $N$이 소수인지 판별해야 하는 문제에서, $N=1$이 입력으로 들어오는 경우를 제대로 처리하지 못하는 코드들을 틀리게 하기 위해 $N=1$인 데이터를 준비할 수 있습니다. (예외 처리 데이터)
  • 혹시라도 고려하지 못한 경우가 있을 수 있으니 랜덤에 의존해 제작한 일반적인 데이터를 추가로 더 준비할 수 있습니다.
  • 아예 틀린 방법으로 문제를 해결하는 코드가 준비한 데이터를 운좋게 전부 통과하는 경우가 있다면, 틀린 방법으로 풀면 틀리거나 시간 초과를 받는 데이터를 준비할 수 있습니다. (반례 데이터)
  • 출제자가 의도한 풀이보다 훨씬 쉬운 풀이로 풀리는 경우 시간 제한을 조정하거나 문제에 등장하는 상수들의 제한을 조정할 수도 있습니다. 의도한 풀이로 접근하면 풀리지만 의도하지 않은 풀이로 접근하면 시간 초과를 받도록 적절히 제한을 조정합니다.

등과 같은 과정을 거쳐 문제를 완벽하게 만들었습니다.

다들 모여

이 참가자는 WA를 받고 생존한 후에 다른 참가자를 소환합니다.

재작년과 작년의 참가 조건이 마음에 들었고, 그대로 유지했습니다. 석박통합과정 학생의 참가 조건만 명확하게 정했습니다.

  • 3명이 1개 팀으로 참가해야 함
  • 학부생이라면 재학과 휴학을 불문하고 참가 가능
  • 대학원생이라면 석사과정 또는 석박통합 2년차까지 참가 가능
  • 다른 학교 구성원끼리 팀을 이루어 참가 가능

수상 경력에 따라 제한 조건을 둘까도 생각해 봤는데, UCPC는 역시 한국 최강자전의 컨셉인 것도 있는 것 같아 딱히 두지 않았습니다. 총 299팀이 예선대회에 참가를 신청해 주셨습니다.

매년 하던 것처럼 Google Forms를 이용해 참가 신청을 받고 GMail을 통해 공지사항을 전송했는데, 대회 규모가 커지면서 이 방법을 계속 사용하기엔 다소 무리가 있는 것 같다는 생각을 했습니다.

  • 참가자 중 메일 주소에 오타를 낸 참가자들이 몇몇 계셨습니다. 실제 예시로, nvaer.comnaver.com, gamil.comgmail.com, kaist.co.krkaist.ac.kr 등으로 도메인에 오타를 낸 메일 주소들을 확인할 수 있었고, 제 수작업으로 고쳤습니다. 도메인 오타는 어찌저찌 고칠 수 있는데 @ 앞 부분에는 과연 오타가 없었을까요? 이메일 인증에 기반한 서비스를 사용하거나, 이를 직접 구현해야겠다고 느꼈습니다.
  • 예선 계정 정보 메일 299개를 하나하나 작성해 보냈습니다. 또한 GMail에 일일 전송 메일 수 제한이 있다는 사실을 이 대회 운영하면서 처음 알았습니다. 이 때 대량 자동 메일 전송 시스템을 구축했어야 했는데, 그러지 못했던 것이 후술할 예선대회 대참사로 이어집니다.

예산 확보

출제자 분들과 검수자 분들께 노력에 대한 합당한 대우를 드리고, 참가자 분들께 상을 드릴 수 있도록 예산을 정했습니다. 온라인 대회였기 때문에 장소나 비품, 식사 등에 대한 고려는 할 필요가 없다고 생각했으나.. 오산이었습니다. 온라인 방송을 할 장소와 장비가 필요했고, 상품이 있다면 상품을 배송할 비용도 필요했습니다. 대관료와 장비, 배송비 등을 종합해 보니 온사이트로 치뤄진 예년 예산만큼은 못해도 상당히 무거운 예산이 나왔습니다.

감사하게도 대회를 열겠다고 하자마자 케니소프트, 알고스팟, 스타트링크, 그리고 고려대학교 SW중심대학사업단에서 후원 의사를 보내 주셨습니다. 이후에도 여러 개발 기업에 무작정 메일을 보냈고(…) 마인즈랩네이버 D2에서 출제와 검수 비용을 지원해 주셨습니다. 대단히 감사합니다! (solved.ac의 경우 사실상 제 개인 후원이기 때문에 논외로 합니다)

온라인 대회여서 기존의 후원 세션을 기존처럼 진행할 수 없어 어떻게 어필할 수 있을까 고민했습니다만, 오히려 온라인 대회이고 공개된 온라인 방송으로 대회를 진행하기 때문에 굳이 참가자가 아니더라도 대회 방송을 볼 수 있고, 따라서 알고리즘 문제해결에 대한 충분한 관심이 있는 시청자들에게 기업을 홍보할 수 있다는 점을 어필하기로 했습니다.

사실 출제와 검수는 이전에 서강대 대회를 총괄해 본 적이 있었기에 어느 정도 익숙한 부분이었습니다. 하지만 서강대 대회는 학과 사업이어서 후원사를 구할 필요가 없었던 반면 UCPC의 경우에는 우여곡절이 많았고, 실수도 했습니다.

가장 큰 실수는 후원 조건을 명확하게 정하지 못했고, 또 이를 후원사에 제대로 공유하지 못했던 것이었습니다. UCPC에서는 홍보 기업 발표 세션을 진행하는데, 온라인 방송으로 홍보 세션을 진행하면 참가자들이 도중에 방송을 이탈해 효과가 반감될 것을 우려하여 후원 조건 금액을 높게 정했습니다. 그러나 죄송하게도 다른 바쁜 일들에 정신이 팔린 제 불찰로 인해 이를 공유받지 못한 후원사가 계셨습니다. 다음 대회부터는 이번 일을 반면교사로 삼고, 가능하다면 파이콘의 예처럼 후원 조건을 합당하고 명확하게 정하고 홈페이지에 공지하며 후원사와 긴밀히 소통할 수 있도록 해야겠습니다.

후원 기업들에 다시 한 번 무한한 감사를 드립니다.

예선 방송 리허설(7월 23일): 폭풍전야

대회 전에 리허설을 통해 방송 진행 계획을 구체화했습니다. 운영진들과 함께 안암의 명물 고고 인디안 쿠진에서 카레를 먹고, 대회 중 스튜디오로 사용될 고려대학교 정보대학 강의실에 숭고한 연합대회가 진행되는 도중 급습해 모여 강의실의 배치와 장비 등을 확인하고, 인터넷 속도는 방송을 송출하기에 충분한지, 강의실 구조 상 풀이 and/or 후원 세션은 어떻게 하면 좋을지 논의했습니다. 관련해서는 가장 고민을 많이 하신 재헌님의 UCPC 2020 방송 후기를 참고하시면 좋습니다.

OBS가 브라우저 화면을 겹쳐 띄워 둘 수 있다는 것을 이용해 기획한 대로 제가 대회 직전(당일 새벽 3시까지!)에 React로 간단하게 방송 씬을 만들었습니다. 코드는 여기 올라와 있습니다.

예선(7월 25일): 이 곳이 어둠의 기운으로 가득차 곧 무슨 일이 일어날 듯 합니다

방송 씬을 만드느라 날을 새고 10시에 고려대에 도착해서 세팅을 시작했습니다. 운영진들은 과연 올솔이 몇 팀이나 나오고 언제 제일 먼저 나올까 내기를 합니다.

막상 대회 시간이 다가오니까 대회 진행 플랫폼인 BOJ가 500 Internal Server Error와 502 Bad Gateway 에러를 뱉기 시작합니다. 어…? 이대로는 대회를 정상적으로 진행할 수 없겠다 싶어 대회 시작을 14:10으로 10분 연기했습니다.

그런데 좀 잠잠해지나 싶더니 14:07쯤 되니까 같은 현상이 다시 일어나는 거였습니다. 10분을 더 연기할까 고민하고 있던 찰나, BOJ Stack도 먹통이 되었습니다. 대회 정보는 BOJ Stack이라는 관리 페이지에서 수정해야 합니다. BOJ Stack이 접속이 막히면 운영진도 대회 시간을 수정할 수 없습니다.

Media Tweets by Haachama Sukidesu (@Haachama_Suki) | Twitter

’14:20에는 괜찮아지겠지? 그럼 종료 시간을 10분쯤 연장해야겠다’고 생각했습니다. 서버는 비웃기라도 하듯 계속 접속을 거부했습니다.그런 와중에 UCPC 관련 메일 아래에 적혀 있던 제 전화번호로 참가팀들의 전화가 걸려오기 시작했습니다. 운영진도 대회 서버에 접속할 수 없는 상황임을 알려 드렸습니다.

이제는 대회를 어떻게 할지 빠르고 공정하게 결정해야 했습니다. 특히 여러 지역에서 모여서 대회를 치기 위해 스터디룸을 빌리는 팀이 많다고 알고 있어, 이 분들의 피해가 최소화되도록 하려면 어떻게 해야 하나 고민했습니다. 그 와중에 대회 사이트에서 문제 제목을 읽은 팀이 있다는 제보를 받았습니다. 문제 제목을 읽은 팀이 있었다는 것은 문제를 읽은 팀이 있었을 수 있다는 뜻도 되므로 신중하게 결정해야 했습니다.

정말 다행히도 이번 UCPC는 온라인 대회였기에 공간의 제약을 받지 않았고, 본선에 몇 팀이 출전하더라도 수용할 수 있었습니다. 그래서 아예 기업 대회 Qualification 라운드의 형식으로 본선 커트라인을 명시하고 시간을 대폭 연장하기로 결정합니다. 그리고 단체 메일을 보냈습니다.

그런데, 감사하게도, 구글이 제가 아이패드(구글 계정 입장에서는 ‘새로운 기기’)로 대량의 메일을 보내려는 시도를 감지하고 전대프연 계정을 차단시켰습니다. 제가 회장이 되면서 바꾼 비밀번호로는 로그인이 안 됐고 이전 비밀번호로 인증을 받아야 했는데, 무려 제 전전전임 회장께서 설정하신 비밀번호였습니다. 당장 연락을 드렸지만 회신을 무작정 기다릴 수도 없는 상황이었어서, 제 개인 메일으로 단체 공지와 문제지를 전송했습니다. 이 때가 오후 3시였습니다.

서버 상황은 오후 4시를 즈음하여 개선되었고 코드를 제출할 수 있는 상황이 되었습니다. 예선대회에서도 해설과 스코어보드 공개를 할 예정이었고, 이를 위해 출제진들이 모여 있었으나, 안타깝게도 이후 방송은 진행하지 못했습니다. 여러모로 아쉬웠습니다. 예선 당일 서버 사고가 일어났던 이유는 여기에서 읽을 수 있습니다.

결과적으로 본선 진출 팀은 총 170팀이 되었고 의도치 않게 역대 최대 규모의 본선이 되었습니다. 컷을 5문제로 잡았으면 좋았겠다는 의견도 많았으나 안타깝게도 결정 당시에는 출전 팀들의 실력을 가늠하기 힘들었습니다.

본선도 규모가 예선 못지않게 커져버렸고, 본선대회에서도 같은 일이 되풀이되면 안 되었기에 만반의 준비를 했습니다. 우선 스타트링크와 함께 이런 일이 일어난 원인을 분석하고 당시 일어났던 상황이 재발되지 않게 하기 위한 기술적 조치를 취했습니다. 본선도 BOJ에서 치루는 것으로 결정했으나, 혹시 모를 사태에 대비하기 위해 UCPC 운영진도 DOMjudge 서버를 직접 구축해 대비했습니다.

본선(8월 1일):

이미지
대회 본부

정말 다행이게도 본선대회는 아무 문제 없이 순조롭게 잘 진행되었습니다.

서버 대비와 별개로 본선대회를 위해 준비한 것들이 몇 개 더 있었습니다. 그 중 가장 눈여겨볼만했던 건, 대회 중에도 공지했던 바 있지만, 이번 UCPC는 스코어보드 공개의 재미를 위해 프리즈 기준을 다소 특이하게 잡았던 것이었습니다.

프리즈 시간은 대회 종료 60분 전이었으나, 프리즈 시간과 관계없이 어떤 팀이 9문제를 해결한 순간 이후 그 팀의 모든 제출이 비공개되는 식이었습니다. 이를 위해 BOJ에서 스코어보드를 제공하지 않고 scoreboard.ucpc.me라는 별도의 사이트에 스코어보드를 띄웠습니다. 박수찬tncks0121님께서 운영자 스코어보드의 모든 제출을 $n$초마다 가져와서 가릴 건 가리고 공개 스코어보드에 보여주는 파이썬 스크립트를 짜 주셔서 가능했던 일이었습니다.

풀이는 원래 라이브로 방송하려 했으나, 풀이 슬라이드가 대회 중에 완성되기도 했고, 진행을 비교적 여유롭게 하기 위해 녹화방송으로 바꿔 진행했습니다. 풀이 슬라이드가 방송에서 사용한 것과 공개된 것이 다른데, 방송에서의 풀이 슬라이드는 출제진이 생각한 난이도 순서대로 문제가 정렬되어 있고, 공개된 풀이 슬라이드는 A, B, C.. 순입니다. 특별한 이유가 있다면 공개 슬라이드에서는 풀이가 필요한 문제를 더 빨리 찾게 하기 위함이었습니다.

본선 해설 및 스코어보드 공개 영상

본선대회를 성공적으로 종료하고 저를 제외한 운영진은 고기를 맛있게 먹으러 갔다고 합니다. 저는 안타깝게도 당일 너무 피로해서 그냥 집에 와서 곯아떨어졌습니다. 비극적인 엔딩이네요.

어땠나

힘들지만 의미있는 경험이었다고 말하면 식상할까요?

힘들었던 것들

전대프연 회장을 하는 것은 힘든 일이라고 익히 들어서 알고 있었지만 구체적으로 어떤 게 힘든 일인지는 잘 몰랐습니다. 이제 대략 알게 되었습니다.

  • 후원사를 구하기가 상당히 힘들었습니다. 온라인이어서 더 그랬습니다. 올해 ICPC도 후원 사정이 좋지 않다는 걸 생각하면 어디나 비슷한 것 같습니다. 그래서 개인적으로 옆 나라 리저널의 후원 사정이 꽤 부러웠습니다.
  • 상금 처리라던가 참가 상품을 택배로 보내야 했던 것도 힘든 점 중 하나였습니다.
  • 6월 말에 넥슨코리아 엔진스튜디오에 산업기능요원으로 입사하게 되었습니다. 6월까진 무직 백수여서 몰랐는데, 대회 코디네이팅과 왕복 3시간의 출퇴근 생활을 병행하는 것은 체력적으로 상당히 힘든 일이었습니다. 회식 도중에 나와서 대회 개최를 준비했던 적도 있습니다.
  • 이외에는, 참가자 등록이 번거로웠습니다. 특히 재학증명서와 휴학증명서 등을 일일이 확인하는 작업이 너무 번거롭고 힘들었습니다.
후원사 구하기와 재학증명서 처리는 사천왕 중에서도 최약체…

그렇지만 저는 온사이트 대회를 준비했던 건 아니었기 때문에 다른 해보다는 비교적 쉽게 준비한 것이 아닌가 싶습니다.

놓쳤던 것들

대회 중에 발생한 이런저런 예외적인 상황들에 대해 제대로 and/or 빠르게 대처하지 못했던 게 아쉬웠습니다. 앞서 언급했던 것들만 다시 언급하자면, 가령…

  • GMail은 하루 발신 제한량이 있었고, 제가 shiftpsh.com과 ucpc.me 도메인으로 발신하기 위해 개인적으로 월정액을 내고 사용했던 메일서버에도 마찬가지로 하루 발신 제한량이 있었습니다.
  • 사소하게는 call for tasks 메일 계정과 Slack을 연동시켜 주는 Zapier 스크립트가 간헐적으로 동작하지 않는 문제가 있어서 공모받은 문제를 확인하지 못할 뻔 하기도 했습니다.
  • 이메일 주소를 이메일 확인 등의 방법으로 검증하지 않아 메일 전송 과정 중에서도 누락되는 메일들이 발생했습니다. Google Forms를 사용하는 대신 직접 대회 등록 사이트를 만들었다면 좋았을 것입니다. 위의 이유와 맞물려 메일을 자동으로 발송해 주는 시스템이 있었다면 더 좋았을 것입니다.
  • 대회 서버가 다운되었을 때 의논할 시간이 부족한 상황에서 대회 진행 형식을 결정해야 했습니다. 이런 상황이 발생했을 때는 미리 어떻게 하면 좋겠다는 계획을 세웠더라면 참가자들의 피해와 스트레스를 줄일 수 있었을 것입니다.
  • 방송 계획과 대본을 미리 짜놓지 못해 다소 매끄럽지 못하게 진행된 것 같아 아쉬웠습니다.
  • (이건 예외적인 상황은 아니었고, 제가 정신없어서였지만) 제 불찰로 후원사와의 소통이 제대로 진행되지 못한 부분이 있었고, 안타깝게도 이로 인해 다소 불미스러운 일이 발생했습니다.

UCPC는 이제 예선 기준으로 참가 인원 1,000명을 바라보고 있을 정도로 커진 대회입니다. 코딩 테스트 열풍으로 인해 알고리즘 문제해결 및 경쟁 프로그래밍 입문자들이 갈수록 많아지고 있고, 이런 기조가 사그라들지 않는 한 대회 규모는 계속 커질 것으로 생각됩니다. 이런 규모의 대회라면, 이런 규모의 대회에서 일어날 수 있는 갖가지 상황들을 미리 파악하고 숙고하여 대비하는 것이 옳겠다고 뒤늦게 느낍니다.

그럼에도 좋았던 것들

우여곡절도 많았지만 전대프연으로써는 처음 시도했던 온라인 대회를 성공적으로 마무리할 수 있어서 뿌듯합니다. 코로나 시국도 프로그래밍 대회는 이기지 못했네요. 😎

대단하고 멋진 분들과 함께 최고의 커뮤니티 대회를 만들 수 있어서 즐겁고 뿌듯했습니다. 온라인 대회여서 안타깝게도 참가자 분들과는 만나지 못했지만요.

그래서 회장 1년 더 하나요?

이 팀은 사실 시프트를 제외한 레드시프트 팀인데, 제가 대회 같이 안 치고 혼자 운영하러 가서 삐진 나머지 이름을 이렇게 지었나 봅니다

사실 UCPC 2020 직후에도 SUAPC에서 운영과 출제를 했고, 신촌 캠프 대회와 SNUPC에서도 검수 및 조판으로 참여했습니다. UCPC에서 얻은 경험과 리소스가 상당히 많은 도움이 되었습니다.

운영진 16콤보

하지만 내년에도 회장을 할지는 잘 모르겠습니다. 일단 이제 직장에 다니고 있기도 하고, 무엇보다 결정적으로 휴학생 팀으로 나간 ICPC 2020 인터넷 예선에서 너무 처참한 성적을 받았기 때문입니다.

여러 대회를 운영하고 출제하고 검수하느라 바빴고, 게다가 solved.ac 개발로도 바빴던 나머지 제가 문제해결 연습을 할 시간이 부족해져서라고 생각했고, 지금은 다시 팀 연습도 하고 코드포스도 자주 나가고 BOJ 문제도 열심히 풀고 있습니다. 내년 대회에는 참가자로서 참여하고 싶습니다. 복학할 때 적의환향赤衣還鄕해서 레드시프트 이름값 해야죠.

이런 현실이… 이런 현실이 있단 말이냐?

결론은 내년 전대프연을 이끌어 주실 분을 모십니다. 뭐 없으면 어쩔 수 없고…

마치면서

전대프연과 UCPC에 특별한 관심을 갖고 지원해 주신 고려대학교 SW중심사업단, 마인즈랩네이버 D2, 그리고 알고스팟구종만님과 케니소프트박현민525hm님께 깊은 감사를 드립니다. 특히 예선 서버 문제로 새벽 코딩을 불사하며 끝까지 이슈 해결을 위해 수고해 주신, 전대프연의 초대 회장이자 이제는 스타트링크최백준baekjoon님께 각별한 감사를 드립니다.

검수는 물론 대회 운영 전반에 있어서 기술적으로 많은 도움을 주신 박수찬tncks0121님, 훌륭한 문제를 출제해 주신 김동현kdh9949님, 김창동sait2000님, 나정휘jhnah917님, 노영훈Diuven님, 모현ahgus89님, 문창현ckdgus2482님, 반딧불79brue님, 배근우functionx님, 심유근cozyyg님, 이동관windflower님, 이상헌evenharder님, 이종영moonrabbit2님, 정기웅QuqqU님, 조창민Ronaldo님, 그리고 열정적으로 검수해 주신 류호석rhs0266님과 홍은기pichulia님께 진심으로 감사의 말씀을 드립니다.

이외에도 대회 막바지에 운영에 큰 도움을 주신 공인호inh212님, 김영현kipa00님과, 실험적인 형태의 대회임에도 대회 진행자를 흔쾌히 맡아 주신 정재헌Gravekper님께도 대단히 감사드립니다.

마지막으로, UCPC 2020에 참가해 주신, 알고리즘 문제해결을 사랑해 주시는 참가자 여러분께 감사드립니다.


대회 리소스

다른 프로그래밍 대회를 개최하시는 데 도움이 될 수 있도록 UCPC 2020에서 사용된 자료들을 인터넷에 공개했습니다.

오픈소스

  • ucpcc/ucpc2020-site UCPC 2020 대회 사이트
    Jekyll로 제작한 정적 사이트입니다. 대회 공지사항 등을 적기 위해 만들었습니다.
  • ucpcc/problemsetting-guidelines UCPC 디스크립션 작성 및 포매팅 컨벤션
    UCPC 문제 제작을 위해 수립한 컨벤션입니다. 일관적인 데이터와 디스크립션 작성에 도움을 줄 수 있습니다.
  • ucpcc/ucpc2020-description-layout UCPC 2020 문제지 레이아웃
    마개조된 olymp.sty입니다. 2019 서강대학교 프로그래밍 대회 문제지 레이아웃을 바탕으로 제작했습니다.
  • ucpcc/ucpc2020-solutions-theme UCPC 2020 솔루션 Beamer 테마
    Beamer와 함께 사용할 수 있는 테마입니다.
  • ucpcc/ucpc2020-broadcast-scene UCPC 2020 방송 씬
    OBS가 씬에 웹 브라우저를 사용할 수 있다는 사실에 착안하여 React로 제작한 16:9 방송 씬입니다.

공유 문서

  • UCPC 2020 문제 출제 현황 시트
    대회 운영에 활용했던 출제 현황 시트 레이아웃입니다. 운영 당시 그대로의 시트는 아니고, 이해를 돕기 위해 체크박스 상황은 연출했으며 미사용 문제들은 다른 곳에서 사용될 수 있으므로 관련 정보를 지웠습니다. 사용하고자 하실 경우 파일 > 사본 만들기를 누르면 수정 가능한 사본을 만들어 사용해 주세요.

다른 글

2019 서강대학교 프로그래밍 대회를 개최했습니다

제목이 곧 내용, 올해 서강대학교 교내대회를 개최했습니다. 제가 출제와 운영을 총괄했습니다! 진짜 구데기컵 2018(…)을 제외하면 제 첫 출제였고, UCPC 2018에 풍선 스탭으로 참여한 걸 제외하면 첫 운영이었습니다. 대회를 준비하고 진행하면서 느낀 점들을 적어보려 합니다.

어떤 걸 먼저 해야 하지

서강대학교의 경우 2005년부터 매년, ICPC Korea Regional에서 교내 랭킹 1~2위의 팀이 대회 운영과 출제를 해왔습니다. 대회는 보통 11월 말이고 ICPC 본선은 11월 초에 진행되기 때문에 보통 2~3주 정도의 준비 기간이 주어집니다. 아니 대회 운영하려면 뭐가 필요한지도 모르는데 2주만에 대회 준비를 어떻게 해요??

근데 사람 일이 다 그렇듯이 놀랍게도 대회 날짜가 다가오면 준비를 하게 되어 있더라고요. 학교에서 ICPC 본선에 3팀이 출전했는데, ‘그래도 우리 팀이 그 중에서 적어도 2위는 하겠지?’ 라는 행복회로를 돌리면서 김칫국 109 + 7사발 마시고 미리 대회 개최를 준비했습니다.

대회를 열기 위해 필요한 것들은 대략 다음과 같습니다.

  • 문제. 문제 푸려고 여는 대회인데 문제가 없으면 안 되죠.
    • 출제진. 애초에 출제진이 없으면 문제가 나올 수가 없죠.
    • 검수진. 물론 출제진이 검수해도 괜찮습니다.
  • 시간과 공간. 언제 어디서 개최할지 결정해야 합니다.
  • 참가자. 이건 제가 어쩔 수가 없고..
  • 포스터, 풍선, 간식 같은 거

이 중에 제가 그 시점에 할 수 있었던 건 문제 만들기였습니다. Redshift가 본선 교내 1~2등 안에 들면 세 명 모두 출제를 해야 했기에, 일단은 팀 내에서 문제를 뭐 낼지 어렴풋이 생각해 보기로 했습니다. 대충 이런 문제 아이디어가 나왔습니다.

  • 7-세그먼트 디스플레이 (shiftpsh 아이디어)
    • 개인적으로 좋은 문제라고 생각했어서 제네레이터까지 만들어 뒀습니다.
  • 올솔브 방지용 graph isomorphism 문제 (shiftpsh 아이디어)
    • Tree isomorphism 문제로 약화되어 출제되었습니다. 이거 오렌지 이상에선 웰노운이라더라고요. 왜 내가 웰노운이 아니라고 생각했던 건 다 웰노운이지??
  • 최단 경로 문제인데, 길이의 곱이 최단이 되어야 하기 때문에 간선 가중치에 전부 로그를 씌워 구하는 문제 (lvalue 아이디어)
    • 방콕 리저널 예비소집일에 나온 아이디어였는데, 다음날 본대회 F번?으로 실제로 나와버렸기 때문에 표절 의혹을 받을까봐 실제 대회에는 못 냈습니다.
    • 이 아이디어 덕분에 대회 당시 F번을 두번째로 빨리 푼 팀이 우리 팀이었는데, 역설적이게도 대회를 말아먹는 계기가 되었습니다. 이건 다른 포스트에 후술.

다행히도 Seoul Regional에서 교내 1등을 하는 데 성공했기 때문에 대회 운영에 참여할 수 있게 되었고, 이제 아까 언급한 ‘대회 운영에 필요한 사항’ 4개 전부를 고려해야 하는 상황이 되었습니다.

문제

각자 내고 싶은 문제들은 있겠지만, 실제로 모두가 각자 내고 싶은 문제만 낸다면 프로그래밍 대회가 아니라 빡구현 코딩테스트가 될 수도 있고, 고인물 자료구조 파티가 될 수도 있고, 계산수학 경시대회가 될 수도 있겠다고 생각했습니다. 그래서 아래와 같은 원칙을 두고 대회 문제들의 전체적인 틀을 정했습니다.

  • 출제되는 문제들의 주제는 균형적이어야 합니다.
    • 12문제 중 DP가 5문제고 그러면 좀.. (ICPC Seoul 예선 출제자님 듣고 계신가요)
  • 모든 문제를 푸는 사람은 없어야 하고 하나도 못 푸는 사람이 있어서는 안 됩니다.
    • ICPC 출제 기조라고 들었습니다.

개인적으로는 tree isomorphism 문제를 너무 내고 싶었기 때문에 디비전 당 8문제, 총 16문제를 내기로 정했습니다. 지금 생각해보면 그러지 말거나 아니면 디비전끼리 겹치는 문제를 내게 하거나 했어야 했는데 아무튼 그렇게 정했습니다.

구데기컵에서 문제 정리를 위한 스프레드시트를 팠던 기억이 있어서 저도 그렇게 했습니다.

쉬운그래프문제하나만더있으면좋겠다

20문제를 낸 후, 각각 solved.ac 기준 예상 난이도와 사용 알고리즘/자료구조를 적고 8개 문제씩 Champion/Master에 각각 배정해나가면서, 대회가 너무 어려워질 것 같아서 많이 등장한 주제의 문제 중 4문제를 뺐습니다. 그리고 동그라미를 하나씩 채워나가는 방향으로 문제를 준비했습니다.

예상 난이도를 정하는 것에 장점과 단점이 있었는데요,

  • 장점은 문제를 배정하기가 쉬웠다는 점이었고,
  • 단점은 문제 난이도를 잘못 예상해서 Master 디비전 스코어보드가 망했다는 점이었습니다.
    • 출제자 생각과 참가자 생각은 많이 다르다는 걸 깨달았고, 조금 더 참가자 입장에서 문제 난이도를 생각해 보려고 노력해야겠다고 느꼈습니다.

문제들을 배정하고 나서는 스테이트먼트와 정해 – 데이터와 테스트 – 제한 순서대로 문제를 만들었습니다.

스테이트먼트

참가자 입장에서 스테이트먼트는 명료할수록 좋습니다. 러시아의 모 사이트에서 열리는 대회에는 스테이트먼트가 애매하거나 이상한 경우가 종종 있었는데, 이로 인해 스트레스를 받은 경험이 있었기 때문에, 참가자가 문제를 푸는 데 방해가 되지 않도록 스테이트먼트를 구성하려고 노력했습니다. 출제 의도가 스테이트먼트를 길게 해서 일부러 문제풀이를 지연시키고자 하는 게 아니라면 쓸데없는 이야기는 줄이고 문법상의 오류나 비문은 최대한 없애고, 문장은 짧게 구성하도록 하고. 사실 글쓰기의 기본이죠.

스테이트먼트 원고는 각자 작성하고 Stack에 옮기면서 수정했습니다

아래는 카드 놓기의 스테이트먼트 원고와 최종본을 비교해 둔 것입니다.

첫번째 줄에는 N(1<=N<=1000000)이 주어진다.
두번째 줄에는 길이가 N인 수열 A가 주어진다.
Ai가 1이면 i번째로 카드를 내릴 때 1번 기술을 썼다는 뜻이다.
Ai가 2이면 i번째로 카드를 내릴 때 2번 기술을 썼다는 뜻이다.
Ai가 3이면 i번째로 카드를 내릴 때 3번 기술을 썼다는 뜻이다.
Ai는 1,2,3중 하나임이 보장된다.
An은 항상 1임이 보장된다.
첫 번째 줄에는 N (1 ≤ N ≤ 106)이 주어진다.
두 번째 줄에는 길이가 N인 수열 A가 주어진다. Aix이면, i번째로 카드를 내려놓을 때 x번 기술을 썼다는 뜻이다. Ai는 1, 2, 3 중 하나이며, An은 항상 1이다.

위와 아래 중 어떤 글이 더 이해하기 쉬운가요? (아래라고 해주세요)

  • 1000000은 한 눈에 봤을 때 정확히 얼마인지 가늠하기 어렵기 때문에, 1,000,000 또는 106으로 고쳐야 합니다.
  • <=은 정확한 표현이 아니기 때문에 ≤으로 고칩니다. 변수명은 일반적인 글과 구분하기 쉽게 하기 위해 기울임꼴으로 씁니다. 기울임꼴로 하는 편이 실제 수식에서 등장하는 문자들의 모양과 비슷하기도 하고요.
  • 쉼표로 나열된 항목들은 띄어쓰기로 구분해 줍니다(1,2,3 → 1, 2, 3).
  • 같은 의미의 글이 여러 번 반복되는 경우 간단하게 줄일 수 있는지 생각해 봅니다.

스테이트먼트를 그냥 읽어보면 모르겠지만, 계속 긴장 상태일 참가자 분들의 입장에서 편하게 읽힐 수 있도록 이렇게 나름대로 세심하게 편집하는 작업을 거쳤습니다.

대농부 김상혁
평행우주

또한 글만 적혀 있으면 문제를 이해하는 데 어려움이 있을 수도 있기 때문에 몇몇 문제에는 적절한 위치에 삽화들을 그려서 삽입했습니다. 다행히도 제가 그래픽 디자인을 할 줄 알았기 때문에 삽화는 제가 전부 그렸습니다.

정해

출제자의 정해가 틀리면 안 됩니다. 최근 열렸던 학교 대회 중에 출제자가 잘못된 풀이를 작성한 경우가 종종 있었고, 서강대학교만 해도 2017년에 출제자가 정해를 잘못 작성했던 적이 있었습니다. 특히 대회 준비 중에 열린 타 대학교 대회에서 이런 상황이 발생했기 때문에 각별히 신경써서 검수했습니다.

이건 어쩔 수 없지

학과에서는 외부 검수자를 초빙하지 말라고 했지만 2주 안에 16문제를 출제해야 하는데 출제 경험이 적은 6명이 오류를 안 내는 게 이상한 상황이었고, 결정적으로 스타트링크에서 검수자 초빙을 말 그대로 강력하게 권장했기 때문에 제 단독 판단으로 검수자를 초빙하기로 했습니다. 여러 대회에 검수자로 참가했던 분들이었기에 문제 보안에 대해서는 믿을 수 있었으며, 개인적으로는 잘못된 문제를 만들지 않는 것이 더 중요하다고 생각했기 때문입니다.

아니나다를까 색깔 하노이 탑 문제에서 출제자의 정해가 잘못되었음이 외부 검수자에 의해 발견되어 일찍 수정할 수 있었습니다. 검수자 분들께서는 후술할 데이터와 시간 제한에 대한 검증도 진행해 주셨습니다. 외부 검수자 분들께서 안 계셨다면 이번 대회도 문제 오류가 있는 대회가 될 뻔 했는데, 참 다행이라고 생각합니다. 이 글을 빌어 감사하다는 말씀을 다시 한 번 전해드리고 싶습니다.

데이터와 테스트

저는 Polygon을 이용해 데이터를 만들었습니다. Polygon은 Codeforces에서 프로그래밍 문제 제작을 도와주는 목적으로 만든 플랫폼입니다. 다음과 같은 것들이 가능합니다.

  • 데이터 생성 및 관리
  • 입출력 형식 검증
  • 출력 가능한 스테이트먼트 PDF 제작

특히 입력 형식의 무결성은 상당히 중요하기 때문에 Polygon을 사용합니다. 예를 들어 평행우주는 입력이 다음 조건을 만족함이 보장되어야 합니다.

  • 입력으로 들어오는 각각의 그래프는 연결되어 있어야 하며 트리여야 합니다. 노드가 s개라면 노드 번호는 0, 1, 2, …, s − 1로 주어져야만 합니다.
  • 입력으로 들어오는 트리의 개수는 106개 이하여야 합니다. 각 트리의 노드의 개수는 30개 이하여야 합니다. 또한 모든 트리의 노드 개수의 합도 106개 이하여야 합니다.
  • 당연하겠지만, 입력의 각 줄마다 맨 앞이나 맨 뒤에 공백 문자가 있어서는 안 되고, 공백이 두 개 들어가 있다거나, 맨 마지막 줄에 줄바꿈이 없다거나 하는 경우도 안됩니다. C/C++로는 어찌저찌 잘 풀릴지도 모르지만 Java와 Python에서 제대로 풀리지 않을 수 있기 때문입니다.

testlib.h는 위와 같은 무결성 체커를 간단하게 짤 수 있도록 해 줍니다. 또한 Polygon은 이렇게 짠 무결성 체커를 바탕으로 데이터를 제작할 때 모든 데이터에 대해 생성과 동시에 자동으로 무결성 체크를 해 주기 때문에 다른 더 중요한 것들에 집중할 수 있게 해 줍니다.

Polygon에 등록되어 있는 서강 프로그래밍 대회 문제들

testlib.h는 데이터 생성기를 제작할 때도 사용할 수 있습니다. 안타깝게도 다른 출제자 분들께서는 Polygon 사용 경험이 없었고, 출제 시간도 2주로 상당히 촉박해서 급한 대로 testlib.h를 쓰지 않는 제네레이터를 만들었습니다. 실제로 도중에 입력 조건에 맞지 않는 데이터가 업로드되었는데, 무결성 체커가 없어서 찾아내기 어려웠습니다. 다행히도 대회 직전에 찾아서 삭제했습니다.

하지만 Polygon 자체도 문제 제작자가 짠 코드에 의존하기 때문에, 대부분의 실수를 잡아낼 수 있다고 하더라도 잡아내기 어려운 실수들도 있습니다. 가령 평행우주의 경우는 날 새가면서 정신없이 문제를 만들다 보니 제가 10만과 106을 헷갈렸나 봅니다. 문제에는 별의 수와 별자리의 수가 106을 넘지 않는다고 되어 있습니다만 실제로는 각각이 105을 넘지 않는 약한 데이터만을 준비했던 사실을 시상식 때가 되어서야 깨달았습니다.

데이터 자체는 무결했으니 문제나 데이터의 오류는 아니었지만, 의도하지 않은 풀이가 통과할 수도 있었던 상황이었습니다. 대회 당시 맞은 사람이 없었어서 다행이었을까요? 곧 데이터를 추가할 예정입니다.

제한

시간 제한과 메모리 제한

의도한 풀이는 통과하고, 의도하지 않은 풀이는 통과하지 않도록 제한을 잘 설정해야 합니다. 그런데 이게 은근 어려운 게,

  • 언어마다 실행 시간에 차이가 있습니다.
    • Python에서 최적의 솔루션이 동작하는 시간이 C++에서 나이브한 솔루션이 동작하는 시간보다 느릴 수도 있습니다.
  • 같은 언어의 같은 풀이라도 입력 방식에 따라 실행 시간에 많은 차이가 생깁니다.
    • 느린 입력 방식 기준으로 시간 제한을 설정하면, 빠른 입력 방식을 사용했지만 느린 알고리즘을 사용한 코드가 시간 안에 통과하는 상황이 생길 수도 있습니다.

solved.ac는 어떤 방식으로 정렬을 해도 괜찮은 문제이지만, 원래는 인덱스 소트를 이용해 O(n)으로 정렬해야만 하는 문제로 기획되었습니다. 그래서 기존에는 제한이 n ≤ 107이었습니다. 하지만 C++에서 빠른 입력을 쓰고 std::sort를 사용한 코드가 500ms 좀 넘게 돈 반면, Java에서 인덱스 소트를 이용한 코드가 800ms가 나오길래, 그냥 포기하고 쉽게 바꿨습니다.

작년 대회와 다르게 이번 대회에서는 Python을 사용할 수 있도록 했지만 정작 모든 문제가 Python으로 풀릴 것이라고 보장하지는 않았습니다. 대회 규칙에는 ‘출제진이 모든 문제를 C++과 Java 혹은 Kotlin으로 풀었음이 보장됩니다’라고 적었고, 실제로 C++과 Java 혹은 Kotlin으로 모든 문제를 검증했으나 Python으로는 풀리지 않는 문제도 있었습니다. Python은 현저히 느리기 때문에 Python 기준으로 시간 제한을 잡으면 C++ 나이브 코드가 통과할 수도 있기 때문이었습니다. 이는 ICPC World Finals 규칙과도 같습니다.

메모리 제한은 전부 1024MB로 설정했습니다. 여러 테스트를 돌려 보면서 틀린 코드가 맞거나 맞은 코드가 틀리는 등의 상황이 발생하면 제한을 조절하거나 데이터를 보강하는 등의 작업을 진행하면서 문제를 완성시켜 나갔습니다.

완성된 시트

그렇게 시트를 전부 동그라미로 만든 후에는 한 숨 돌릴 수 있었습니다.

운영

문제를 다 만들어갈 때쯤에는 대회 운영에 대한 것도 생각해야 했습니다. 다행히도 학과에서 다년간 대회 운영을 도와주고 계셨기 때문에 이런 것들은 별 고민 없이 해결되었습니다.

대회 진행 전

  • 장소. 실습실은 학교가 관리하고 있기 때문에 대여도 학과에서 처리해 주셨습니다.
  • 풍선. 역시 학과에서 지원해 주셨습니다.
    • 헬륨 풍선이 생각보다 비쌌습니다. 하나에 1,500원이었는데, 대회 끝나고 못 나눠준 풍선은 다 터뜨려야 한다고 생각하니 좀 안타까웠습니다.
  • 간식. 이것도 학과에서 지원해 주셨습니다.

포스터는 학과에서 인쇄만 해 주기 때문에 제가 만들어야 했습니다. 팀노트에 있던 디닉 코드를 가져와서 3시간동안 간단히 만들었습니다.

애프터 이펙트로 간단하게 배경을 만들고
포토샵으로 글씨를 얹었습니다

학내 이곳저곳에 포스터를 붙이고, 참가자는 학교 커뮤니티에 게시글을 올려 모집했습니다. 총 91분께서 참가 신청을 해 주셨습니다. 안타깝게도 당일에 안/못 오신 분들이 많아서 실제 대회 당일에는 약 70분 가량 참여해주셨습니다.

이미지
문제지

문제지도 만들었습니다. 문제지는 LATEX로 타입세팅해 대회 전날에 인쇄했습니다. 학과사무실에서 인쇄해 제본과 운반을 전부 수작업으로 했는데, 대회 운영 중 가장 힘들었던 일이 아니었을까 싶습니다.

대회 당일

이미지
데스크

대회 당일 운영은 순조로웠습니다. 다만 실습실에 PyCharm과 IntelliJ를 설치하느라 시간이 오래 걸렸는데, 전날에 미리 설치해 뒀다면 좋았겠다 싶었습니다. 실습실이어서 학생들이 작성한 코드가 남아 있었고 이들을 전부 지우기 위해 현장에서 배치 파일(.bat)을 급조해 모든 컴퓨터에서 돌렸습니다.

이미지
이 많은 풍선들 중 단 하나만이 참가자의 손에 들어갔다는 슬픈 소식

풍선을 나눠주려면 자리표가 있어야 편한데 이 사실을 간과했습니다. 자리표도 현장에서 가나다순으로 급조했습니다. 이런저런 일들로 인해 대회 초반에 풍선이 늦게 나가는 일이 있었습니다.

Champion 디비전은 별 일이 없었지만 Master 디비전 스코어보드는 꽤 오랫동안 많은 사람들이 1솔브에서 머물러 있었습니다. B번 문제의 난이도를 잘못 생각했음을 직감했습니다. 다음날 진행된 Open Contest에서도 B번 문제가 많이 풀리지 않았습니다. 심지어 ainta님은 A~P를 전부 푼 후 마지막에 B를 푸셨을 정도.

많은 사람들이 겹받침이 등장할 때 도깨비불 현상이 일어난다는 걸 간과한 듯했고, 대회가 시작한 후 꽤 지나서 공지사항으로 추가 테스트 케이스를 제공했습니다. 이 테스트 케이스 덕분에 B를 맞게 된 분들이 몇 분 계셨지만 애초에 Master B번으로 낼 만한 수준의 문제가 아니었다는 걸 생각하지 못했던 건 아쉬움으로 남습니다. 초보자에게 문자열 처리는 생각보다 어려운 주제인가 봅니다.

대회 운영진은 참가자의 소스코드를 전부 읽어볼 수 있기 때문에, 채점 현황에서 여러 코드를 읽어봤습니다. 혹시 맞는 코드인데 틀린 건 아닌지, 틀린 코드인데 맞은 건 아닌지 등을 확인하기 위해서입니다. 코드를 확인하다 보니 cout << fixed를 하지 않아 문제를 아깝게 틀린 경우도 있었습니다. 안타까웠지만 어쩔 수 없었습니다.. 다행히도 틀린 코드가 통과하거나 맞은 코드가 통과하지 않는 경우는 없었습니다.

Master는 A, B, D, G, H의 5문제가, Champion은 A, B, C, D, F의 5문제가 각각 풀렸습니다. Champion 쪽은 제가 예상한 대로였으나 Master에서 문제가 많이 풀리지 않아 아쉬웠습니다. 과연 모두 재밌게 즐길 수 있을 만한 대회였을까요? Champion은 그랬던 것 같습니다. 안타깝게도 Master는 난이도 예상을 너무 잘못했던 것 같습니다.


이후 오픈 콘테스트도 순조롭게 진행되었고, 문제 오류는 딱히 없었기 때문에 바로 문제들을 공개했습니다. 제가 출제해 제일 어려운 문제로 기획했던 평행우주가 문제 공개 후 (고인물들에게) 나름대로의 인기를 끌고 있어 뿌듯합니다. 그렇다고 내년 ICPC Seoul Regional에 tree isomorphism이 나오는 걸 보고 싶진 않은데요.. 뭐 여하튼.

대회 운영과 문제 출제가 생각보다 어려운 것임을 깨닫게 해 준 계기가 되었습니다. 좋은 대회를 여는 건 정말 힘들다는 것도요. 생각해야 될 게 정말 많았습니다. 제가 했던 고민들이 대회를 여시려고 하시는 분들께 도움이 되었으면 좋겠습니다.

내년엔 아마도 회사에 가게 되기 때문에, 대회 출제는 3년 후에나 다시 하게 될 것 같습니다. 그 때는 난이도 조절에 조금 더 신경을 쓰고 싶습니다. 같이 출제해 주신 서강대학교 학우님들, 검수를 도와주신 분들과 참가자 분들께 모두 감사드립니다.