はじめに
- プログラミング初学者にAtCoderを紹介し
- 突き当たった壁を百本ノックでこなす
AtCoder 概要
競技プログラミング大手
- C++, Python, Rust, Java, C#, JavaScript, Ruby, Elixirなどいろんな言語で参加できる
-
Algorithm ContestとHeuristic Contestの2種類
-
Algorithm Contest
- AtCoder Beginners Selection: まず第一にこれをこなす
-
AtCoder Daily Training: 過去問に取り組む(本戦と同じく時間制限あり)
- AtCoder Daily Training EASY: 灰色(Rating1から399)
- AtCoder Daily Training MEDIUM: 主に茶色・緑色(Rating400から1199)
- AtCoder Daily Training HARD: 主に水色と青色(Rating1200から1999)
- AtCoder Daily Training ALL: 主に水色と青色(Rating1200から1999)
- 本戦
- AtCoder Beginner Contest: 初心者~中級者向け/土曜日夜9時から/毎週
- AtCoder Regular Contest: 中級者~上級者向け/日曜日夜9時から/ 月1回ほど
- AtCoder Grand Contest: 上級者~世界ランカー向け/日曜日夜9時から/年6回ほど
- Heuristic Contest
-
Algorithm Contest
壁No.1: 入力データをプログラムに取り込めない
- 障害: 標準入力を理解していない
- 回答: 初学者時点で理解できないので呪文として覚える
- ポイント
- 「標準入力」という言葉を習得する
- わからないときに調べる手段が必要: Google、ChatGPT、Perplexityなど
同期式
function main(input) {
const lines = input.split("\n"); // 入力
// コードを入れる
console.log(lines); // 出力
}
main(require("fs").readFileSync("/dev/stdin", "utf8"));
非同期式
process.stdin.resume();
process.stdin.setEncoding('utf8');
var lines = [];
var reader = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
reader.on('line', (line) => {
// ここで入力を処理する
lines.push(line);
});
reader.on('close', () => {
// ここで出力する
console.log(lines);
});
壁No.2: テキストファイルを行単位に分けたり、文字列を分割することができない
- 障害: 基本的なデータ変換のうち、文字列=>配列の変換がわからない
- 回答: 文字列操作の基本
- ポイント
- 改行文字が"\n"であること、"\r?\n"であることは後回しでよい
- 公式を紹介: String - JavaScript | MDN
壁No.3: 足し算したつもりで+は連結
- 現象:
console.log(a+b+c) => 123
- 障害: 数値データと文字列データの区別がついていない
- 回答: 文字列データを数値データに変換する
let a = parseInt(lines[0])
let a = lines[0] - 0
- ポイント: 数値 + 文字列 または 文字列 + 数値は、「+」は連結の意味になり数値は文字列化される
壁No.4: + 連結のつもりで空白もれ
- 現象:
console.log(a+b+c+s) => 6test
- 障害: 文字列連結と標準出力様式の混同
- 回答: 文字列連結するなら、明示的に" "空白文字をいれる。そうでなければ、文字列中の変数展開を行うかconsole.logの引数を分ける
console.log(a+b+c +" "+ s)
console.log("%i %s", a+b+c, s)
console.log(`${a+b+c} ${s}`)
console.log(a+b+c, s)
- ポイント:
壁No.5: 条件を立式できない
- 現象: 演算子は理解できても、立式に至れない
- 障害: 立式のための日本語の読み取り方が確立していない
- 回答: 「AがBであるならばC」=「if(A == B) C」
- ポイント:
- 比較演算子のうち、等号 == は、日本語としては「である」
- 不等号 != は、日本語としては「でない」
壁No.6: 文字列中の1文字1文字へのアクセス方法を知らない
- 現象: 文字列を対象とした繰り返し処理が書けない
- 障害: 文字列も配列と同じ構造である認識がなく、文字列の要素への参照方法が、配列要素への参照方法と一緒である認識がない
- 回答: 配列arrのi番目の要素がarr[i]であるように、文字列sssのi番目の文字はsss[i]
壁No.7: 整数の各桁の数値を求められない
- 現象: 与えられた数値の十の位だけを求めるところ、100で割ると答えてしまう
- 障害: 切り捨て、剰余などの組み合わせに思い至らない
- 回答: 一度、10で割って求めた商を10で割った余りが十の位
- 百の位なら、100で割って求めた商を10で割った余り
どうも、Aの次にB、Bの次にCをするといった順序でなく、一度の処理で解が得られる式を想像したようである
壁No.8: constで宣言された変数を再度宣言してしまう
- 現象: Uncaught SyntaxError: Identifier 'found' has already been declared って何ですか?
- 障害: 専門用語からエラーの意味がわからない
- 回答: すでに、宣言されているconst変数を再度、変数宣言しようとしたから
syntax、indentifier、declareは、いずれも専門用語。ちゃんと理解しようとするなら、コンパイラの単位が必要。
- 順次、改稿していきます