アジの開きを閉じる。

競プロ(AtCoder)中心のブログ

【精進支援ツール】AtCoder Editorial Problemsを開発しました

AtCoderの問題を解説の筆者から検索することができるWebアプリ「AtCoder Editorial Problems」を開発しました!

開発リポジトリ: AtCoderEditorialProblems(GitHub)

これは使用した技術や工夫の記録です.

AtCoder Editorial ProblemsのTOPページ.

目次

AtCoder Editorial Problems(AEP)とは?

AEPは,AtCoderの問題を解説の筆者から検索することができるWebアプリです.
PDFで解説を配布していた昔のコンテストを除き,ABC/ARCのすべての公式/ユーザー解説を検索することができます!

「この人の解説は自分に合っているな~」と思ったときに超便利です.

開発中のあれこれ

Writer(問題を書いた人)に得意不得意がある人は一度は思ったことがあると思います.

「苦手Writerの対策をしたいな~~~~」

って.

これが開発のきっかけでした.
それまではWriter経験のある人が自身のブログにまとめる程度で,まとまって情報を入手できる場所がありませんでした.

なので作ることにしました.
ちょうど「一度はWebアプリを作ってみたいけど題材が無い状態」だったので,自分の学習のためにももってこいのアイデアでした.

公式解説の筆者がその問題のWriterだと思っていたので(たぶん多くの人がそう思っている),当初はそのように定義したWriterから問題検索できるように開発していました.
しかし目標だった年内リリースの期限直前!! 12/30に,

  • 公式に公表されていない「問題ごとのWriter」を決めつけてサービス提供するのはどうなのか.
  • おっと,Writerが解説も書いているとは限らないぞ.
  • はたまた1問題1Writerとも限らないぞ.

などの懸念があり,急遽「Writerから問題検索できる」から「解説の筆者から問題検索できる」に変更しました.(リリース直前にサービス内容変更ができるのも個人開発の良くない醍醐味?)
流石に変更に合わせてシステムを全改修するのは間に合わないので,一旦公式の筆者だけ検索できる状態のままリリースし,4日でPDF以外のすべての解説を検索できるようにしました.

結果としてやりたかったことがそのまま形になった訳ではないですが,解説の好みも人によってはあると思うし,自分もあるので,これはこれで「確かにあると便利なサービス」だったのではないかなと思います.

ちなみに検索結果で公式解説なのかユーザー解説なのかが分かるので,当初描いていた「Writerからの問題検索」という使い方もできます.しめしめ.

開発で大切にしたこと

下手にいろいろな技術に手を出さない

高度な技術や便利なライブラリに下手に触れませんでした. 理由としては,

  • 開発は「自分の学習のため」でもあり基礎を学びたかったから.
  • 高度な技術はそれなりに学習コストが高いから.
  • 初めての技術が多すぎると脳がパンクするから.
  • 初めての技術をいろいろ採用しすぎて,「結局なにもわからなかった」となるのは避けたかったから.
  • よく分からない技術をよく分からないままに使用するのは嫌だったから.(セキュリティ的にもこわい)

です.
具体的にはAWSやReact,Next.jsの基本的な使い方の習得に集中したかったので,便利なライブラリとかIaCとかは採用しませんでした.

あえて泥臭い実装をすることで,いざ高度な技術や便利な技術を学んだときのインパクトが強く,そのときの学習効果も高いと思っています.

また,例えばDBだと本音はDynamo DBを使ってみたかったのですが,やるならDB設計からちゃんと学びたくそれはそれで学習に時間がかかるので,使用経験のあるPosgreSQLを採用しました.

年内リリース

「個人開発のコツは期限を決めること!!」(らしい)

7月にTwitterで期限を宣言しました.

この時点ではReactは知っていたもののNext.jsは名前も聞いたことが無く,AWSも「なんかAPI Gateway+Lambdaで簡単にAPIがつくれるらしい」程度でした.

別に期限を決めなくても開発はするのですが,決めた理由は以下の通りです.

  • 割と誰でも思いつき,かつ開発も難しくはないであろう単純なサービスだったので,誰かに先を越される可能性が高いと感じたため.
  • 長期間作り込んでリリースしたもののウケなかったら悲しいため.
  • 早めにニーズを確認したかったため.

平日は仕事にエネルギーを費やしていたので,土日に開発を進めていました.

結果,12/31 19:05にリリースすることができました!
ギリギリになったのは思っていたよりもデプロイに手間取ったためです.

年末恒例の紅と白に分かれて歌合戦する某番組が始まる前で良かった!

採用した技術

採用しなかった技術

今後リファクタリングや学習の一環で採用する可能性はあります.

  • Chakra UI
    • Ant Designと両方使ってみた結果,理想のUIを実現するには使いにくいと感じたため.
    • 検索機能付きSelectが公式には無かったため.非公式で誰かがGitHubに上げていたが理想のUIではなかった.
  • Dynamo DB
    • 先述の通り,期限に対して学習コストが高いため.
  • 独自ドメイン
    • 最初は独自ドメインに憧れていたが時間的に今後も個人開発を行っていくとは限らないため.取得はいろいろ開発するようになってからでも遅くはない.
    • このアプリ特有のドメイン取得もチラついたが,サ終後に手放したドメインが悪意を持ったユーザに利用され,Twitterやこの記事で宣伝時に貼ったURLやブックマークからアクセスしたら変なサイトが開いて困る人が出るかもしれないと考えたため.
    • そんなときにちょうど変なドメイン取るな!!!.netを見かけ,強く決意したため.
  • GitHub Actionsによるデプロイ
    • 期限まで時間が無かったため妥協.

こだわりポイント

  • UX
    • 動きのある派手な画面よりシンプルで使いやすいのが一番.
    • 提示する情報や機能も最低限に.
      • 例えばAGCの問題を収集しても良いが,ほとんどのユーザにとっては不必要なタブが生まれる.選択時に認知負荷を少しでも低減させるために無駄なタブは削ぎ落とした.
  • 問題や解説の筆者の情報は自前のDBに保存
    • 検索の度に外部へリクエストをすると,本サービスを踏み台にしたDDoS攻撃になりうるため.
    • 外部へのリクエストは1秒おきに投げるようにしている.
  • Sliderによるdiffフィルター
    • 大発明では!?
    • 数値で範囲指定する方法など考えたが,色でフィルタリングできるSliderが直感的で良いと感じた.
    • Sliderを少しでも動かす度に範囲内の色を再レンダリングしているため,よく見ると少しガタつくのが惜しい.

最後に

自分でイチから考えて,好きなサービスを開発するのって楽しい!!
特に「ここはこうした方がユーザーは使いやすいんじゃないか」とユーザー指向で作っていくのが楽しかったです.

また,規模や出来にかかわらず自力で一つサービス開発した経験って,結構大きいと思いました.1年前の自分には全く考えられません.

これは自分への教訓ですが,どんなに汚い実装だと自分で思っていてもどんどん実装していくのが良いです.
自分は変数名一つでも考え込むので,後々相当悪い影響が想像できる場合でない限りは「一旦これでいいや」として先に進み,「DB構築できた」とか「API作ってブラウザから叩けた」とかどんどん実績解除していくのがモチベにも繋がって良いと思いました.

この記事が,誰か(読み返している未来の自分もだぞ)の開発のきっかけになれば嬉しいです.

次は何作ろうかなー.

ここまで読んでいただきありがとうございました!