ミニマルなプログラムを書く練習
たとえば、ジャンケンのプログラム(の一部)を書くとします。
「player」「computer」が「グー=1、チョキ=2、パー=3」の手を持ち、
「judge」が「引き分け=0、playerの勝ち=1、負け=2」と判定する仕様です。
C++
1#include <iostream>
2
3using namespace std;
4
5int main() {
6
7 int player = 1;
8 int computer = 2;
9 int judge = 0;
10
11 if(player == 1 && computer == 1){
12 judge = 0;
13 }else if(player == 2 && computer == 2){
14 judge = 0;
15 }else if(player == 3 && computer == 3){
16 judge = 0;
17 }else if(player == 1 && computer == 2){
18 judge = 1;
19 }else if(player == 2 && computer == 3){
20 judge = 1;
21 }else if(player == 3 && computer == 1){
22 judge = 1;
23 }else if(player == 2 && computer == 1){
24 judge = 2;
25 }else if(player == 3 && computer == 2){
26 judge = 2;
27 }else if(player == 1 && computer == 3){
28 judge = 2;
29 }
30
31 std::cout << judge;
32
33 return 0;
34}
一番素直に書くと上のようになります。
可能な手の組み合わせの九通りを網羅しています。
switch文で書くとかいろいろ改善点はありますが、
ここでそれより、もっと短く書く方法があります。
c++
1if(p == c){
2 j = 0;
3}else if((p== 1&&c ==2)||(p==2&&c==3)||(p==3&&c==1))
4{
5 j = 1;
6}else{
7 j = 2;
8}
(判定部以外は同様の処理なので省略)
if文を工夫すると、あいこ、勝ち、負けの3パターンにできます。
しかし、さらに短くもできます。
c++
1((p==1&&c==2)||(p==2&&c==3)||(p==3&&c==1))?(j=1):(j=2);
2(p==c)&&(j=0);
三項演算子と短絡評価で二行まで縮まりました。
ruby
1(((p==1&&c==2)||(p==2&&c==3)||(p==3&&c==1))&&(j=1))||(p==c)&&(j=0)||(j=2)
Rubyのように値を評価して返す仕様の言語だと、一行で書けます。
(C++の仕様には詳しくないので、c++でも書き方があるかもしれませんが)
今見てきたような冗長さを省いて短縮していく道のりが、
「ミニマルなプログラムを書く練習」のひとつだと思います。
ただし、注意点があります。
ひとつは、現代のプログラミングは、
冗長さの短縮よりも可読性を重視する方向に進んでます。
『リーダブルコード』でも、行数を短くするよりも、
読んで理解するのにかかる時間を短くせよ、と言っていたと思います。
ですから、これは詰め将棋的にあえてする練習であって、
本番のプログラムでは読みやすさが大事ですから、
短さにこだわり過ぎた書き方はしない方がいいです。
今回の例だと、「あいこ、勝ち、負けの3パターン」
くらいまでが個人的な許容範囲でしょうか。
もうひとつ、「ミニマル」といっても、
コードゴルフ的に行数を減らすだけではないでしょう。
たとえば、『The ThoughtWorks Anthology』の
「オブジェクト指向エクササイズ」のように、
スモールオブジェクトに分解していく書き方も
一種のミニマリズムだと思います。