AtCoder の練習記録用リポジトリ。
このリポジトリは、AtCoder の問題を通してコーディング基礎力を上げるための学習用プロジェクトです。
主な目的は以下です。
- TypeScript / PHP / Python / C++ の基礎文法に慣れる
- 標準入力・標準出力の扱いに慣れる
- 配列、文字列、Map、Set、sort、ループ、条件分岐などの基本処理を練習する
- 同じ問題を複数言語で解き、言語ごとの差分を理解する
- 解法メモを
README.mdに残し、後から復習しやすくする - VS Code 上でコードを書き、ローカルでサンプルテストできる環境を作る
提出は、現状では CLI 提出が不安定な場合があるため、基本的にブラウザ提出を前提とする。
このリポジトリでは、言語ごとではなく、問題ごとにディレクトリを分ける。
例えば ABC086A - Product の場合は、以下のように配置する。
contests/abs/abc086-a/
├── README.md
├── main.ts
├── main.php
├── main.py
├── main.cpp
└── test/この構成にすることで、同じ問題を TypeScript / PHP / Python / C++ で比較しやすくする。
atcoder-practice/
├── README.md
├── package.json
├── tsconfig.json
├── .gitignore
├── contests/
│ └── abs/
│ ├── practice-a/
│ │ ├── README.md
│ │ ├── main.ts
│ │ ├── main.php
│ │ ├── main.py
│ │ ├── main.cpp
│ │ └── test/
│ ├── abc086-a/
│ │ ├── README.md
│ │ ├── main.ts
│ │ ├── main.php
│ │ ├── main.py
│ │ ├── main.cpp
│ │ └── test/
│ └── ...
└── notes/
├── standard-input.md
├── array.md
├── string.md
└── map-set.md| パス | 役割 |
|---|---|
contests/ |
AtCoder の問題をまとめる |
contests/abs/ |
AtCoder Beginners Selection の問題をまとめる |
contests/abs/abc086-a/ |
個別問題の解答・メモを置く |
main.ts |
TypeScript 解答 |
main.php |
PHP 解答 |
main.py |
Python 解答 |
main.cpp |
C++ 解答 |
test/ |
oj download で取得したサンプル入力・出力 |
README.md |
問題ごとの解法メモ |
notes/ |
標準入力、配列、文字列などの学習メモ |
主に以下を使う。
Node.js
TypeScript
tsx
PHP
Python
C++
online-judge-toolsonline-judge-tools の oj コマンドは、主に以下に使う。
サンプル取得
ローカルテストCLI提出は環境やAtCoder側の仕様変更で不安定な場合があるため、基本的にはブラウザ提出を使う。
cd atcoder-practice例:ABC086A - Product
cd contests/abs/abc086-aoj download https://atcoder.jp/contests/abs/tasks/abc086_aoj test -c "npx tsx main.ts"oj test -c "php main.php"oj test -c "python3 main.py"g++ -std=c++20 -O2 main.cpp -o main.out && oj test -c "./main.out"git status
git add .
git commit -m "Solve ABC086A"
git push現状では、提出はブラウザから行う。
手順:
1. VS Code でコードを書く
2. oj test でサンプルを確認する
3. AtCoder の提出画面を開く
4. 言語を選ぶ
5. main.ts / main.php / main.py / main.cpp の中身を貼る
6. 提出する
7. ACしたら GitHub に保存するAtCoder では、問題ごとに標準入力から値を受け取り、標準出力に答えを出す。
例えば、以下のような入力が与えられる。
3 4この入力を受け取り、答えを出力する。
EvenTypeScript / Node.js では、fs.readFileSync(0, "utf8") を使って標準入力を読み取る。
import * as fs from "fs";
const input = fs.readFileSync(0, "utf8").trim().split(/\s+/).map(Number);意味:
fs.readFileSync(0, "utf8")
→ 標準入力を文字列としてまとめて読む
trim()
→ 前後の空白や改行を削除する
split(/\s+/)
→ 空白・改行・タブで分割する
map(Number)
→ 文字列を数値に変換するimport * as fs from "fs";
const input = fs.readFileSync(0, "utf8").trim().split(/\s+/).map(Number);
const [a, b] = input;console.log("Even");変数を出力する場合:
const answer = 10;
console.log(answer);TypeScript / Node.js では process.exit(0) を使う。
console.log("Yes");
process.exit(0);例:
for (let i = 0; i < 10; i++) {
if (i === 5) {
console.log(i);
process.exit(0);
}
}process.exit(0) は正常終了を意味する。
PHP では stream_get_contents(STDIN) を使って標準入力をまとめて読む。
<?php
$input = trim(stream_get_contents(STDIN));
$tokens = preg_split('/\s+/', $input);意味:
stream_get_contents(STDIN)
→ 標準入力を文字列としてまとめて読む
trim()
→ 前後の空白や改行を削除する
preg_split('/\s+/', $input)
→ 空白・改行・タブで分割する<?php
$input = trim(stream_get_contents(STDIN));
[$a, $b] = array_map('intval', preg_split('/\s+/', $input));<?php
echo 'Even' . PHP_EOL;PHP_EOL は改行を表す定数。
AtCoder の Linux 環境では、実質的に "\n" と同じ。
echo "Even\n";でもよい。
PHP では exit; を使う。
<?php
echo 'Yes' . PHP_EOL;
exit;例:
<?php
for ($i = 0; $i < 10; $i++) {
if ($i === 5) {
echo $i . PHP_EOL;
exit;
}
}exit; により、その時点でプログラムを終了する。
Python では sys.stdin.read() を使うと、標準入力をまとめて読める。
import sys
tokens = sys.stdin.read().strip().split()意味:
sys.stdin.read()
→ 標準入力を文字列としてまとめて読む
strip()
→ 前後の空白や改行を削除する
split()
→ 空白・改行・タブで分割するimport sys
tokens = sys.stdin.read().strip().split()
a, b = map(int, tokens)1行入力だけなら、以下でもよい。
a, b = map(int, input().split())ただし、AtCoder では複数行入力に対応しやすい sys.stdin.read() の形もよく使う。
print("Even")変数を出力する場合:
answer = 10
print(answer)Python では sys.exit() を使う。
import sys
print("Yes")
sys.exit()例:
import sys
for i in range(10):
if i == 5:
print(i)
sys.exit()sys.exit() を使う場合は、先頭で import sys する。
C++ では cin を使う。
#include <iostream>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
return 0;
}#include <iostream>
using namespace std;
int main() {
cout << "Even" << endl;
return 0;
}endl は改行を出す。
AtCoder では以下のように "\n" を使ってもよい。
cout << "Even\n";"\n" の方が軽いので、競プロではこちらもよく使う。
C++ では return 0; を使って main 関数を終了する。
#include <iostream>
using namespace std;
int main() {
cout << "Yes" << endl;
return 0;
}ループの途中で答えが出た場合:
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < 10; i++) {
if (i == 5) {
cout << i << endl;
return 0;
}
}
return 0;
}return 0; は正常終了を意味する。
AtCoder の多くのC++解答では、以下が使われる。
#include <bits/stdc++.h>
using namespace std;ただし、bits/stdc++.h は GCC 用の非標準ヘッダー。
Mac標準の Apple Clang では使えない場合がある。
Macでも通しやすい基本形は以下。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
using namespace std;import * as fs from "fs";
const input = fs.readFileSync(0, "utf8").trim().split(/\s+/).map(Number);
// 処理を書く
console.log("answer");<?php
$input = trim(stream_get_contents(STDIN));
$tokens = preg_split('/\s+/', $input);
// 処理を書く
echo 'answer' . PHP_EOL;import sys
tokens = sys.stdin.read().strip().split()
# 処理を書く
print("answer")#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
int main() {
// 処理を書く
cout << "answer" << endl;
return 0;
}各問題ディレクトリには、以下の形式で README.md を置く。
# 問題名
## URL
https://atcoder.jp/contests/xxx/tasks/xxx
## 問題の要約
## 方針
## 計算量
## 実装メモ
### TypeScript
### PHP
### Python
### C++
## 詰まった点
## 学んだこと最初は高度なアルゴリズムより、以下を優先する。
標準入力
標準出力
if
for
while
配列
文字列
sort
Set
Map
全探索最初から答えのコードを出してもらうのではなく、以下の使い方を優先する。
1. まず自分で解く
2. 詰まったらヒントだけもらう
3. 自分のコードを貼って間違いを指摘してもらう
4. AC後に解法を説明してもらう
5. README.md に自分の言葉でまとめるVS Codeでコードを書く
↓
oj test でサンプル確認
↓
ブラウザで提出
↓
ACしたら README.md を書く
↓
GitHubにcommit / pushCLI提出は便利だが、AtCoder側の仕様変更や online-judge-tools 側の問題で不安定になる場合がある。
そのため、当面は提出のみブラウザで行う。