【100点満点】プログラミングスクール卒業生向けにコーディングテストを考えてみた【Ruby】

## はじめに

[yuki](https://twitter.com/yuki82511988)と申します。DMMWEBCAMP にお世話になって、今は WEB エンジニアとして勤務しつつ、自分で仲間を集めてサービス開発したり、プログラミングの家庭教師したり毎日エンジニアライフをエンジョイしています。

未経験から目指している方向けのサポートやエラー質問なども引き受けておりますので、気になった方は DM へお願いします。

今回は、とあるところで「プログラミングスクールの卒業生に、コーディングテストをするとしたらどんなものを出すか？」という問を出されたので、当時（６ヶ月前位）の自分の回答を記したいと思います。

今なら**ソート**を聞きたいなとか色々あるんですが、当時の思い出として共有します。
Rubyを学習して、ちょうど卒業した位の方は是非挑戦してみてください。自分も作った当時、同じ卒業生でした。

## 問題
100点満点採点です。

```
【問題文】
あなたはプログラミング勉強中の生徒で、日々沢山の勉強をしています。
今日は今月の初日と仮定します。
頑張り屋さんのあなたは、今月のプログラミングの勉強の仕方にルールを設けることにしました。
条件を厳守した上で、以下の問題に答えなさい。

【条件】
・90分以内にコードを書いて提出すること
・インターネットやこれまで学習したノートなどを見ないで解くこと
・問題文の通り、今日は*2020年の11月1日*と仮定して解き進めること
※この記事を読んだ月に合わせていただいて結構です。

・加点方式のため、わからない場合も出来る限りコードを書いてみること
※その際、分からなかった部分をコメントとして記入すること

【問題】
（１）今月の最終日を日付オブジェクトを利用して出力しなさい。
　　　※但し、require 'date'と記載すると利用できるようになる。

（２）あなたは学習をする間、毎日問題を１問必ず解くことに決めました。
　　　また、日付に４がつく日は２問、素数の日は３問を解くことにしました。
　　　初日から学習を開始した場合、今月は合計何問の問題を解くことができるでしょう。
　　　※但し、Primeクラスの利用は不可とする

（３）今月のカレンダーを次のような形式で出力してください。
https://drive.google.com/file/d/1_Km62H6c1WTzv1rWz4NfnwgVXDBC9r2c/view?usp=sharing
```

### 解答と解説と評価基準

```ruby:answer.rb
# 100点中60点以上が合格

# (1)の解答例
require 'date'
year = Date.today.year
month = Date.today.mon
lastday = Date.new(year, month , -1).day 
puts "(1)答え："+"#{lastday}"

=begin
    (1)評価規準 満点【10点】
      ※yearとmonthが求められず、最終日を 2020 5 と直接入力していても減点しない
      ※但し、同点の候補者がいた場合.yearや.monなど再利用性のあるコードを書いている者を評価する
    1.Date.newができている【5点】
    2.答えが28,29,30,31のいずれかで、今月の最終日と対応している【5点】
=end

# (2)の解答例
# 解いた問題の個数の初期化をしています。
count = 0

# 素数判定のメソッドです。#1で呼び出します。
def prime?(num)
  return false if num == 1 
  (2..num).each do |i|
    if num % i == 0 && num == i
      return true
    elsif num % i == 0
      return false
    end
  end
end

# 初日から最終日まで繰り返し処理を行います。
(1..lastday).to_a.each do |date|
    # 日にちに4という数字が含まれていた場合の処理です。
  if date.to_s.split("").include?("4")
    count += 2
    #1 日にちが素数だった場合の処理です。
  elsif prime?(date)
    count += 3
  else
    count += 1
  end
end
puts "(2)答え："+"#{count}"

=begin
(2)評価規準 満点【30点】
    1.素数の判定コードが書けている【10点】
      ※素数を全て書き出している場合は【5点】
    2.4のつく日を判定するコードが書けている(全て書き出しも可）【5点】
    3.繰り返しを使って毎日、1問を解くコードが書けている【5点】
    4.加点をさせる変数の初期化や加算ができている【5点】
    5.解答があっている【5点】
=end

# (3)の問題について
puts "(3)答え：\n" 
week = ["Su","Mo","Tu","We","Th","Fr","Sa"]
puts week.join(" ") 

# 各月の初日の曜日を数値化させています。
day = Date.new(year,month,1).wday
# 曜日 + 1桁の日にちの半角スペース分 = 3半角スペース分を乗算して初週の右寄せをしています。
print "   " * day

(1..lastday).each do |date|
  print date.to_s.rjust(2) + " "
  day += 1
  if day % 7 == 0
    puts "\n"
  end
end

if day % 7 != 0
  print "\n"
end

=begin
(3)評価規準 満点【50点】
    1.一行目の曜日の出力ができている 【10点】
    2.日にちの出力ができている【5点】
    3.工夫して各日の間に半角スペースを入れて出力ができている【5点】
      ※"1 ","2 "のように手入力している場合は【5点】
    4.７日区切りにできている【10点】
      ※繰り返しや改行を使わずに、putsを多用している場合は【5点】
    5.1桁の日にちを出力する場合、先頭にスペースを入れることができている【5点】
    6.第1週を右寄せにできている【5点】
    7.最終週を左寄せにできている【5点】
    8.解答が合っている【5点】
=end

=begin
(その他)満点【10点】
    解答コードの見やすさ、読む人への配慮、処理の方法、導き出そうとした過程などの観点から
    評価理由とともに、採点者が最大10点まで加点をしてください。
=end
```

## まとめ
懐かしいなぁと思いました。何でこのような問題にしたか、想いみたいなのも当然あったのですが、だいぶ経ったので忘れてしまいました。
コーディングテストのいい悪いはともかく、当時を振り返りつつ、今ならどんなテストを作るか考えてみたいです。

解けたら是非ご連絡ください( ◞´•௰•`)◞