派遣で働くエンジニアのスキルアップを応援するサイト

PRODUCED BY RECRUIT

エンジニアへの挑戦状 プログラム修正問題 #01

f:id:itstaffing:20220208090604p:plain

あなたのプログラマとしての力を測る問題です。
非プログラマにはわからない。
プログラマなら、言語問わずわかるはず。
さて、あなたは解けますか?

所要時間:3~5分
コツがわかれば、1分足らずで解けるかも!?

リクルートスタッフィング

【問題】

新入社員にプログラミングを教えていて、「月末日を取得する関数」を作成するように指示したところ、以下のソースコードが提出されました。なお、「is_leap_year」という関数は、うるう年を判定する関数として、すでに用意されているものとします。

int last_day(int year, int month) {
    if (is_leap_year(year)) {
        if ((month < 1) || (month > 12)) {
            return -1;
        }
        if (month == 2) {
            return 29;
        } else if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
            return 30;
        } else {
            return 31;
        }
    } else {
        if ((month < 1) || (month > 12)) {
            return -1;
        }
        if (month == 2) {
            return 28;
        } else if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
            return 30;
        } else {
            return 31;
        }
    }
}

得られる結果は問題ないのですが、保守性の観点から、実行結果を変えずにこのソースコードを修正したいと思います。
以下のうち、循環的複雑度がもっとも小さくなるソースコードを選んでください。

【選択肢1】

int last_day(int year, int month) {
    if ((month < 1) || (month > 12)) {
        return -1;
    }
    if (month == 2) {
        if (is_leap_year(year)) {
            return 29;
        } else {
            return 28;
        }
    } else if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
        return 30;
    } else {
        return 31;
    }
}

【選択肢2】

int last_day(int year, int month) {
    if ((month < 1) || (month > 12)) {
        return -1;
    }
    int day = 28;
    switch (month) {
        case 2:
            if (is_leap_year(year)) {
                day = 29;
            }
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        default:
            day = 31;
    }
    return day;
}

【選択肢3】

int last_day(int year, int month) {
    if ((month < 1) || (month > 12)) {
        return -1;
    }
    int days[] = {
        31, 28, 31, 30, 31, 30,
        31, 31, 30, 31, 30, 31
    };
    int day = days[month - 1];
    if ((month == 2) && (is_leap_year(year))) {
        day = 29;
    }
    return day;
}

難なく解けましたか?
時間がかかった方や歯が立たなかった方はこれを機に「ソフトウェアメトリクス」について学んでみましょう。
正解とその解説は こちらから。

【出題者】
増井 敏克さん
増井技術士事務所代表。技術士(情報工学部門)。情報処理技術者試験にも多数合格。ビジネス数学検定1級。「ビジネス」×「数学」×「IT」を組み合わせ、コンピューターを「正しく」「効率よく」使うためのスキルアップ支援や、各種ソフトウェアの開発、データ分析などを行う。著書に『プログラマを育てる脳トレパズル 遊んでおぼえるPythonプログラミング&アルゴリズム』『もっとプログラマ脳を鍛える数学パズル アルゴリズムが脳にしみ込む70問』『プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問』『図解まるわかり アルゴリズムのしくみ』(以上、翔泳社)などがある。