AtCoder見てたらテクいコードが読めるようになった話

# 無職ワイ、競プロ[^1]に興味を持つ
ワイ「[ちょくだい](https://twitter.com/chokudai)はんがいっつも楽しそうに競プロの事をつぶやいとるから、ワイも**AtCoder**やりたくなってきたで。」
ワイ「[**AtCoderJobs**](https://jobs.atcoder.jp/)いうサイトもあって、AtCoderでの評価をもとに就活もできるらしいしな」
ワイ「**35歳無職**のワイにはピッタリや」

# AtCoderとは
**AtCoder**
https://atcoder.jp/
競技プログラミングのオンラインコンテストに参加できるサイトやで。
自分のランクを上げていって、就活にも活かせるみたいやで。

# 凄い人が多そう
ワイ「ゆーてもワイのような**ザコーダー**がいきなりコンテストに参加するんは精神的ハードルが高いで」
ワイ「とりあえず**AtCoder**のサイト覗いてみよか」

# AtCoderを覗いてみる
ワイ「なになに、コンテストはリアルタイムでしか参加できひんけど、過去問にはいつでも挑戦できるんか」
ワイ「どれどれ」

> **問題文**
> シカのAtCoDeerくんは二つの正整数 a, b を見つけました。 
> a と b の積が偶数か奇数か判定してください。
> ※[ABC086A - Product](https://beta.atcoder.jp/contests/abs/tasks/abc086_a)より引用

ワイ「なるほどな」
ワイ「**シカくんが整数 a と b を見つけた**んやな」
ワイ「それを偶数か奇数か**判定せなあかん**」
ワイ「**ようある場面**や」
ワイ「**森の中かなんかで**見つけたんやろな」

ワイ「・・・でも**積**ってなんやねん」
ワイ「いきなりそんな**専門用語**を使われても」
ワイ「なになに、積ってのは**a**と**b**を掛けた数って意味か」

> **出力**
> 積が奇数なら **Odd** と、 偶数なら **Even** と出力せよ。
> ※[ABC086A - Product](https://beta.atcoder.jp/contests/abs/tasks/abc086_a)より引用

ワイ「この問題ならワイでも解けそうやで」

# 解いてみる
ワイ「おお、ページの下の方にテキストエディタみたいなんがあるで」
ワイ「これを使ってコードを書いて問題に答えるんやな」
ワイ「ほな言語は**JavaScript**を選択、と」
ワイ「コードの雛形を[このページ](https://beta.atcoder.jp/contests/abs/tasks/practice_1#JavaScript(Node.js))からコピペして・・・」
ワイ「余分なとこは消して、と」

```javascript
"use strict";
function Main (input) {
  // 引数 input に「3 5」みたいな文字列が入ってくるので、それを元に問題を解いていく。

}

//標準入力から文字列を受け取ってMain関数を実行
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
```
ワイ「おっしゃ、準備完了や」
ワイ「**input**いう引数に"3 5"みたいな文字列が入ってくるから」
ワイ「その文字列を分割して整数**a**と**b**として使えばええんや」
ワイ「それを掛け算して・・・」
ワイ「その結果が**偶数か奇数か**で条件分岐すればええねやな」
ワイ「それなら、こうや！」

```javascript
"use strict";
function Main (input) {
  // 入力された文字列を半角スペース区切りで分割
  const split = input.split(" ");

  const a = split[0]; // 1つ目の数字を a とする
  const b = split[1]; // 2つ目の数字を b とする
  
  let result; // 結果を入れる用の変数
  
  if (a * b % 2 === 0) {
    // aとbの積を2で割って、余りがなければ偶数
    result = "Even";
  } else {
    // じゃなきゃ奇数やで
    result = "Odd";
  }
  
  console.log(result);
}
//標準入力から文字を受け取ってメイン関数を実行
Main(require("fs").readFileSync("/dev/stdin", "utf8"));

```

ワイ「たぶんできたで」
ワイ「**提出**っと」
ワイ「どや！」

> **結果**
> AC (正解)

ワイ「おっしゃ！JavaScript **完全に理解した**で！」

# 人の回答を見てみる
ワイ「なんや、[**このページ**](https://beta.atcoder.jp/contests/abs/submissions?f.Language=3017&f.Status=AC&f.Task=abc086_a&f.User=&orderBy=time_consumption)で他の人らの回答も見れるやないか」
ワイ「けど、いうても今みたいな簡単な問題・・・」
ワイ「**誰が解いても一緒**やろ」
ワイ「**偶数ならEven**、**奇数ならOdd**、ただそれだけやで」

# ぜんぜんちがった
ワイ「なんや、他の人らの回答一覧を**コードの長さ**や**実行時間順**でソートしたりもできるやん」
ワイ「ほえぇ、この問題でもこんなに**コードの長さに差が出る**んかいな」
ワイ「ちょっと、短く書いてる人のコード見てみよか」

```javascript
function m(i) {
  console.log(["Even","Odd"][i.split(" ").map((e)=>parseInt(e)).reduce((p,n)=>p*n)%2]);
}
m(require("fs").readFileSync("/dev/stdin", "utf8"));
```
※[提出 #3148680](https://beta.atcoder.jp/contests/abs/submissions/3148680)より引用

ワイ「みじかっ！」
ワイ「処理部分、**1行やないか**」
ワイ「何をしとんねん」
ワイ「全然読まれへんわ」
ワイ「こわいこわいこわい」

# 今後のために
ワイ「再就職した時に、同僚がこんなコード書いてたら全く読めへんから仕事にならへんで」
ワイ「この機会にこのコード読めるようにしとこ・・・」

ワイ「ええと・・・まずは」

```javascript
["Even","Odd"]
```

ワイ「**Even**と**Odd**の配列を作っとんな」
ワイ「その後に」

```javascript
[i.split(" ").map((e)=>parseInt(e)).reduce((p,n)=>p*n)%2]
```
ワイ「と続くわけやな」
ワイ「ようは↑この部分が **0** か **1** になって」

```javascript
["Even","Odd"][0] // つまり "Even"
```

ワイ「もしくは」

```javascript
["Even","Odd"][1] // つまり "Odd"
```

ワイ「を出力してんねやな」
ワイ「**カッコええコード**書きはんな〜・・・」

ワイ「ほんで、具体的にどうやって **0** か **1** に変換しとんねん」
ワイ「まずは」

```javascript
i.split(" ")
```

ワイ「入力内容( i )を**半角スペース区切りで分割**( split )して配列にして・・・」

```javascript
.map((e)=>parseInt(e))
```

ワイ「その配列を**map**メソッドと**parseInt**で全て**文字列から整数に**変換してるんか・・・」
ワイ「そして・・・」

```javascript
.reduce((p,n)=>p*n)
```

ワイ「その配列の要素全てを掛け合わせた数を**reduce**メソッドで求めてんのんか」

```javascript
%2
```

ワイ「ほんで最後に**2で割った余りを求める**と・・・」
ワイ「**0** か **1** になんねんな」

ワイ「ほえ〜」
ワイ「かっこええ・・・」

ワイ「入力文字列を分割して、数値にして、掛け合わせて、2で割った余りを求めて・・・って1行で出来んねんなあ」

ワイ「でも、よう考えたら**map**と**parseInt**(整数への変換)要らんやろ」
ワイ「文字列同士を**足し算**すんのは<b> "3" + "5" = "35"</b>みたいになって危険やけど」
ワイ「掛け算なら大丈夫やで」
ワイ「**念の為**か・・・？」

ワイ「**あれ？**」

ワイ「・・・このコード・・・」

ワイ「2ヶ月前に**ワイが書いたコード**やないか！！！」
ワイ「そういえば無職になりたてのころ、AtCoderはんに登録してテクい書き方を真似したりしとったわ・・・」
ワイ「なんでワイは**退化**してんねん」
ワイ「アホやでワイ」

# 逆に一番コードが長い人の解答を見てみる

ワイ「なんや、一番コードが長い解答、**200行超え**やん」
ワイ「偶数か奇数か求めるのに**200行**て」
ワイ「一体どんな処理をしてんねん」
ワイ「・・・読んでみたけど全く意味分からへんわ」

ワイ「むしろさっきのメッチャ短いコードのほうがよっぽど読みやすいわ・・・」
ワイ「変わったコード書く人もおんねんなぁ・・・」

# まとめ
ワイ「こんな簡単な問題でも、こんなに色んな書き方ができんねんな〜」
ワイ「1つの問題に対する、**色んなユーザ**の膨大な**解法や書き方**を読むことが出来て」
ワイ「これが一番コードリーディングの勉強になるかもしれへん」
ワイ「コンテストに参加すらしてへんのにメチャクチャ勉強になったわ・・・」

ワイ「せや、ワイの作った**なもなきくらすた**いうサイトで」
ワイ「[**AtCoder で 人のコードをただ読む** くらすた](https://namonaki-cluster.herokuapp.com/clusters/42)」
ワイ「いうクラスタでも作って、**AtCoder友達**でも**募集**しよか」
ワイ「そんでその子らに近づいて」
ワイ「**その子らの会社に入れてもらう**で！！！！！」
ワイ「完璧な作戦やで」

# スペシャルサンクス
ワイ「ちょくだいはん、問題や解答の引用を許可してくれてありがとうやで〜」

※ワイはAtCoderはんの回し者とちゃうで。ただの**無職**やで。

# ワイシリーズは
ほかにもたくさんあるから読んでってや〜！

[^1]: 「競技プログラミング」の略。