意外と難問なのよ!?(question:1146195011)

 キチョーが会社の一番若いエンジニアに出題する練習問題なら、これは結構な含蓄を入れた出題文かも知れない。

計算する

 出題文中の「計算する」は素直に“文意の通りに解釈”させるものとして、「C言語で作成されたプログラムに実行時に計算させよ」の意味の筈だ。
 その意味では、2番の後半の答案と3番以外は全く計算していないと言えるので、キチョーが出題者で出題者の意図に沿って採点するなら100点満点中50点は減点するだろう。
 2番/3番にしても、普通の最適化で計算されなくなる可能性が充分に高そうなので、10点くらいは減点するかも知れない。
 確実に計算させるには、やはり足し算,引き算,…の関数を作るべきかと思われる。


int Tashizan( int a, int b )
{// aとbとの和を戻す
return a + b;
}

int main( void )
{
int r;
// 和の計算をする
r = Tashizan( 15, 3 );

 上記ではmain()関数のほうは、模範解答例にはなっていない。
 模範解答を示す場合はTashizan()関数をstaticにしたい感じもするトコロであるが、そうすると関数間の最適化が発動したときには計算されなくなるかも知れないし勝手にインライン化されるかも知れない*1ので敢えてグローバル関数にしておく。

表示する

 出題文中の「ディスプレイに表示する」は、キチョーが出題するなら「標準出力に表示する」と綴る。オリジナルの出題は多分その意味でよい筈だが、そうではないかも知れぬ。
 例えば10問も20問も「標準出力に表示する」と出題した後に「ディスプレイに表示する」が1問だけ混じっていたら、それは矢張り他ならぬディスプレイへ出力せねばならないだろう。
 他ならぬディスプレイが出題の意図の場合は、出題者とその生徒の住んでいる環境によって模範解答が変わるだろう。
 Windowsのダイアログをポップアップさせるのが良いかも知れないし、cprintf()のようなものを使うのが正解かも知れない。場合によっては「標準エラー出力に表示する」ことが出題文中の「ディスプレイに表示する」にぴったりかも知れない。

そのほかの採点ポイント

 「出題文をよく読め」と言うことと「意図を汲み取れ」と言うことは重要なポイントであって、「タイトル」とは何かを如何に良く考えたか?は、加点減点の対象にしたい。
 その意味だと5番の回答者さんの「3に対して15との計算は行ってません」はポイントが高い。キチョーが出題者なら、答案にこれを添え書いた者へは加点するだろう。
 交換法則が通じる和と積は兎も角、差/商/剰余の対象を「15と3の」と説明して良かったものか?
 会社の一番若いエンジニアにこれを出題した時に期待される態度は、答案を作る前に「仕様確認」をして来ることだったろう。
 出題文が完璧である必要も理由もない。意図を汲み取るコトと確認をすると言うコトとは、すぐにもいつでも訓練が必要な事柄なのだから。*2
 他の採点ポイントとして、関数の分け方のセンスも問えるだろうし、#defineの使い方(及びこの問題でそれを使うかどうか)のセンスも問えるだろう。
 以上のような観点で、模範解答を作ってみる。


#include

// ----------------------------------------
// 各種計算関数
// ----------------------------------------
int TashizanCore( int a, int b )
{// aとbとの和を戻す
return a + b;
}

int HikizanCore( int a, int b )
{// aとbとの差を戻す
return a - b;
}

int KakezanCore( int a, int b )
{// aとbとの積を戻す
return a * b;
}

int WarizanCore( int a, int b )
{// aとbとの商を戻す
return a / b;
}

int JouyozanCore( int a, int b )
{// aとbとの剰余を戻す
return a % b;
}

// ----------------------------------------
// 各種計算をして結果を表示
// ----------------------------------------
int Tashizan( int a, int b )
{// aとbとの和を計算して表示
fprintf( stderr, "和:%d\n", TashizanCore( a, b ) );
}

int Hikizan( int a, int b )
{// aとbとの差を計算して表示
fprintf( stderr, "差:%d\n", HikizanCore( a, b ) );
}

int Kakezan( int a, int b )
{// aとbとの積を計算して表示
fprintf( stderr, "積:%d\n", KakezanCore( a, b ) );
}

int Warizan( int a, int b )
{// aとbとの商を計算して表示
fprintf( stderr, "商:%d\n", WarizanCore( a, b ) );
}

int Jouyozan( int a, int b )
{// aとbとの剰余を計算して表示
fprintf( stderr, "剰余:%d\n", JouyozanCore( a, b ) );
}

// ----------------------------------------
// 全体を制御する部分
// ----------------------------------------
void Main( int a, int b )
{// 練習問題○○の回答プログラムの本来の仕事

// 和を計算して表示
Tashizan( a, b );

// 差を計算して表示
Hikizan( a, b );

// 積を計算して表示
Kakezan( a, b );

if( 0 != b )
{// 割り算系が計算可能な場合
// 商を計算して表示
Warizan( a, b );

// 剰余を計算して表示
Jouyozan( a, b );
}
}

int main( void )
{// 練習問題○○の回答プログラム

// プログラムの自己紹介(標準出力へ)
printf( "和、差、積、商、剰余の計算プログラム" );

// 本来の仕事をする
Main( 15, 3 );

// 正常終了する
return 0;
}

 こんなに長くなるのか?書き殴った状態なので、エラーが混じっているかも知れない。

*1:関数間の最適化はそれを誇る製品があるが、関数のインライン化はC言語では普通は勝手には行なわれない

*2:オリジナルの出題がコンピュータの専門会社の要員の訓練のための出題だったかどうかは知らない

昨日実家に行って来た

 1つには、現住まいのアパートの更新がもうすぐなので、保証人の判子をお願いしに。
 その他に新しい電話を買ったこと、来週旅行へ行くことの報告、それと10月までに実家が引っ越すことになるとのことなので未引き上げの荷物の分量などを確認しに。

お土産を失くしてしまった

 母に持たされたお土産を、多分東横線に置き忘れてしまった。
 手提げの紙袋*1に入れたまま、中身が何かも全く知らないまま失くしてしまった。
 これは実は母の予言通り。
 お酒が入った状況で帰ったらきっと失くすだろうと、普段キチョーが手持ちしているショルダーバッグのほうに詰め込んでくれようとしたのを「入らないよ」と断った結果だけに、非常にバツが悪い。
 お母さん、ごめんなさい。
 これを伝えるために朝(10:53頃)母に電話したのだが不在の様子(留守電)だった、明日にも又電話してみよう。

お父さんと飲みに行った

 妹にも一緒に行こうとさんざん誘ったのだが、1度行かないよと決めたら気持ちを変えやしない。キチョーの妹だしね。
 引っ越し先に家を新しく建てるとか。父が車でその場所を案内してくれた。母もまだ知らないと言っていた場所を教わっていいのか?*2
 ブログに詳しい場所を書くのは無用心な気がするので、ぼかして書くが、最近のライダー主人公の自宅近辺・都心のど真ん中。それも大通りに面した場所。父曰く「横チョに入ったような変なトコロなら、3分の1くらいに安かったけれど」とのこと。流石はキチョーの父親と言うか何と言うか…。
 「1,000円や2,000円の買い物の3分の1じゃないでしょう、お父さん!?」このキチョーが思わず言ってしまった。
 そんなトコロを案内して貰ってから、目当ての串特急へ。GW中の土曜日、そもそも開いているお店が殆どない訳であるが、前日も開いていた(そこに飲みに行った)とは父の談。
 …「本日貸切」とのこと。
 「新橋に行くか」と父、3秒後にはタクシーに乗っていたと言う展開。流石は…(以下略)。

*1:手提げの紙袋は、実家からの荷物をあわよくば一部持ち帰ろうかと、実家近くのコンビニで調達したもの

*2:それをブログに書いて良いのか?⇒もう一人の群馬の妹は、もしや読んでいる気がする