第一部 最初に
最近、趣味でプログラミングを始めたり小学生から授業に取り入れたりと、やけにプログラミングに注目が集まっていますね。
そののせいか、自分で学習したい人、お子さんにプログラミングを学習させたい人が増えてきたと感じています。
今回お話しする「Paizaのスキルチェック」は、実力チェックだけでなくスキル上達にもたいへん重宝するのですが、問題文の中に訳の分からない言葉が出てくるので、PHPをある程度勉強した人でも戸惑うことが多いのではないかと思い、それを解りやすく説明する記事を書こうと思いました。
とはいえ、パイザの問題は門外不出と固く決められているので深くは語れませんが、自力で問題が解けるように触りだけお話ししたいと思います。
パイザ問題の出し方について
パイザのスキルチェックとは、パイザがあなたにプログラミングの問題を出題して、その問題が解けるかどうかであなたの実力を判定するというものです。
学校の場合は問題の出題者は先生ですが、パイザの場合はパイザという会社の中で問題を作っている人になります。
パイザの中の人はあなたに問題を出すのですが、
学校のテストのように、
足し算をしましょう
① 1+3=
のような出し方はしません。
実際の問題は引用できませんが、私がパイザ風に問題を作るとザックリこんな感じになります。
ある数字が入力されます。
その数字に3を足して出力してください。
はい、ちょっと何を言ってるかわからないですよね。
でもパイザの問題はいつもこんな感じなのです。
それを解説していきます。
ある数字(文字)とは
ある数字とは出題者があなたに与える数字です。
ほとんどの問題で、パイザはあなたにある数字を与えてくるのです。
後述しますが、与えられるものは文字の場合もあります。
問題文には「入力されます」と何やら難しそうに書いてありますが、あなたに与えるものとご理解ください。
問題を図で表現するとこんな感じですね。
この与えられる数字があなたが解く課題というわけではありません。
ある数字に「3を足す」プログラムを書くのが課題です。
ともかく、その「与えられる数字」とやらをプログラム上で取得する方法をご紹介します。
与えられる数字を取得する
それでは「与えられる数字」を取得する方法をご紹介します。
算数の問題では「1+3=」と初めから書いてくれているのが普通ですが、プログラミングは一から全部自分で書かなければなりません。
与えられる数字を受け取るには下記のように書きます。
fgets(STDIN);
何やら不明な英語ですが、天の神様に数字をおくれとお願いする合言葉だと思ってください。
パイザではPHP言語を選ぶと最初からこの合言葉が表示されているので、一字一句覚える必要は無いと思います。
PHPの場合は文の最後に;(セミコロン)を付けるのをお忘れなく。
問題を解きます
次に問題を解いていきます。
私のサンプル問題はこうでした。
ある数字が入力されます。
その数字に3を足して出力してください。
それをプログラムにするとこうなります。
fgets(STDIN) + 3;
確かに3を足していますよね。
書き方としてはこれでいいのですが、最後に先生に解答する工程が残っています。
それを「出力」といいますので、次でお話しします。
出力とは
出力とはあなたが解答を提出する合言葉です。
パイザ(PHP言語)の場合はechoという命令を使います。
つまりこの問題の正解はこうなります。
echo fgets(STDIN) + 3;
- fgets(STDIN)である数字とやらを取得する
- 問題の指示通り3を足す
- echoを使って解答する
とりあえずこの流れだけ覚えておいてください。
本来、echo命令は(画面上に)文字列を出力するという意味です。
ちょっとここで整理
もし仮に、神様から与えられるある数字が「5」だったとしましょう。
fgets(STDIN)の値は5となります。
echo 5 + 3;
それに3を足すと8になります。
つまりechoで先生に解答する数字が8であれば正解です。
しかし、それなら最初からこう書いても正解ではないかと思うかもしれません。
echo 8;
これはダメです。
ある数字が「5」だったとすると言いましたが、数字の中身は何が来るかわかりません。
そもそも、3を足せというプログラムを書いていません。
そうです、これはプログラミングの問題ですから、プログラムで答えましょう。
fgets(STDIN)で受け取った数字に3を足すプログラムを書けば、ある数字が1であろうと100であろうと必ず正解になります。
3を足すというあなたが書いたプログラムが正しければ正解です。
なんとなく理解できましたでしょうか。
ちょっと難しいですね、第二部で問題を解く場面があるので、解いた後にもう一度読み返してみましょう。
与えられるものは文字のこともある
何度も何度も「与えられる数字」と言いましたが、問題によっては文字の場合もあります。
さらに、与えられる数字や文字が、複数の場合もあります。
これからあなたは、この数字もしくは文字を使って難関なパイザ問題を解きつづけることになるのです・・・。
第一部 完
第二部 とりあえず1問やりましょう
一部の最後でも言いましたが、「ある数字」とは私が作ったテスト問題の話です。
パイザの場合は数字だけでなく文字の場合もあります。
また、複数の値が渡される場合もありますので、重ねてお伝えしておきます。
それを理解しやすいように、とりあえず1問解いてみてください。
一番最初の問題としてのおすすめは、「D172イヴの日付」です。
第一部でお話しした内容とクリスマスイブがクリスマスの前日だということを知っていれば瞬殺のはずです。
・・・・・・。
はい、うまく解けましたでしょうか。
そして、「与えられるもの(入力)」と「解答(出力)」の意味がなんとなく理解できたでしょうか。
よく解らないという方は、もういちど第一部を読んでみてください。
第三部 いろんな入力
あとはPHPで勉強したIF文やFOR文などを駆使して問題をガンガン解いていけばいいのですが、困ったことにこれだけでは難しいところがあります。
それは(あなたに)渡される入力の値が複雑なケースがあるからです。
それを説明していきます。
入力の値が複数の場合
出題者から与えられる数字や文字である「入力」が複数の場合があると言いました。
下記のような感じです。問題の中には入力が2行渡されるものが出てきます。
入力例 1
10
5
とりあえず下記のようにすれば1行目の10は取り出せます。
echo fgets(STDIN); //10が表示される
次の5はどうやって取り出せばいいのでしょう。
これはごく簡単な話で、もう一度fgets(STDIN)を使えばいいだけです。
echo fgets(STDIN); //10が表示される
echo fgets(STDIN); //5が表示される
解りやすく言うと、下記図のようにテープをちぎる感じと思ってください。
入力が2行ある場合は2回、3行ある場合は3回fgets(STDIN)を実行してください。
ただし、入力が2行しかない場合に、fgets(STDIN)を3回しても3回目は何も取得できません。
入力の値がスペース区切りの場合
お次は入力が下記のようにスペースで区切られている場合についての例です。
入力例 1
10 5
なんでスペースで区切られてるの?と思うかもしれませんが、これはプログラミングでデータを扱うときによくある話なのです。
例えばこういう例です。
入力例 1
1 孫悟空 そんごくう 男
2 矢吹丈 やぶきじょう 男
3 八神月 やがみらいと 男
これは1行に番号、名前、ふりがな、性別が書いてあるのですが、ここにスペースが無ければ「1孫悟空そんごくう男」という意味不明な文字の塊になってしまいます。
「1孫悟空そんごくう男」ならなんとなく想像できるかもしれませんが、さきほどのように10と5の場合は105になるので、「105」なのか、「1」と「05」なのか、「10」と「5」なのかがわかりません。
スペースで区切ることによって、複数のデータとして扱えるということです。
プログラミングの世界では、スペースのほかにカンマ(,)で区切る場合もあります。
パイザの問題は入力値(与えられた値)をこねくり回して解答する問題がほとんどなので、まずは10と5に分割しなければなりません。
では、これを分割するにはどうすればいいのかというと、explodeという関数を使います。
$input = fgets(STDIN);
$array = explode(" ",$input);
$a = $array[0]; //$aに10が入る
$b = $array[1]; //$bに5が入る
explodeとは、文字列を指定した区切り文字で分割して配列に代入する命令です。
explodeの構文は、explode(区切り文字,文字列)
になります。
区切り文字とは今回の場合はスペースなので、explode(" ",文字列)
としています。
もし区切り文字がスラッシュならexplode("/",文字列)
になります。
文字列はfgets(STDIN)を直接入れてもいいのですが、一旦$inputという変数に代入しています。
後は分割された10と5が入った、$aと$bを足すなり引くなり、煮るなり焼くなりご自由に料理してください。
尚、代入や配列や変数に関してはPHPの教材に載っていることなので、説明は割愛させていただきます。
むしろパイザの問題で腕試しをしようと思うのなら、最低限の勉強は済ませてから取り掛かったほうがよろしいかと思います。
第四部 注意点
やっている上での注意点についてです。
基本的にそういうトラブルも問題の範疇として自分達で解決するべきかもしれませんが、ちょっとあんまりなので書いておきます。
どうせそこらへんを漏らしたとしても、パイザ問題はまだまだ奥が深いので大丈夫でしょう。
渡される入力値の型は必ず文字列型です
入力値で渡される値の「型」についての注意点です。
型に関しての説明も割愛させていただき、解っているものとしてお話しさせていただきます。
いきなりですが、fgets(STDIN)で取得した型は必ず文字列型です。
以前唐突に気付いてしまったのですが、10という整数が単体で渡ってきたとき、その数字にたいしてIF文で比較したのです。
ザックリこんな感じです。
$input = fgets(STDIN);
if ($input === 10) {
echo "OK";
}else{
echo "NG";
}
するとなぜかNGが表示されてしまいました。
そうです、どう考えても10にしか見えない数字、それは文字だったのです。
型を柔軟に対応してくれるPHPゆえに、四則演算をする場合は何ともありませんが、IF文では厳密判定の===でドツボにはまりました。
おそらくどの言語でも同じだと思いますが、型が厳密なC#言語では型変換なので大変だったのを記憶しています。
その対応を含めての問題なのでしょうが、いくらなんでもあんまりかなと思いました。
(むしろ常に型を意識することが大事なのかなと思わせられました)
隠れたブランクに注意
渡された文字を一見すると「abcde」に見えるのですが、実は「abcde」で無かったということがあります。
ちょっと何を言っているのかわからないと思いますが、お話ししておきます。
よくよく調べてみると、その「abcde」という文字、実は「abcde 」だったのです。
そう、半角スペースがケツについていたのです。
ゆえに下記のようなIF文でNGになるのです。おそロシア・・。
$input = fgets(STDIN);
if ($input === "abcde") {
echo "OK";
}else{
echo "NG";
}
どうやって調べたのかというと、strlen()という関数で調べました。
このstrlen()という関数で囲った文字列の文字数を取得できるのです。
下記のように試してみると、5が返ってくるのかと思いきや、6が返ってきました。
$input = fgets(STDIN); //abcde
echo strlen($input); //5だと思ったら結果は6でした
わかるかボケー!(怒)
こういうときはtrim()関数を使います。使い方はこれまた関数で対象物を囲うだけ。
$input = trim(fgets(STDIN));
これで文字列の前後にもしスペースがあったとしても除去してくれます。
基本的に文字が渡ってくる場合はtrim、いやむしろ全部にtrimをつけるクセをつけたほうがいいかもです。
尚、具体的にどの問題とは口が裂けても言えません。実際の文字は「abcde」ではありませんのでご承知おきください。
また、文字型やブランクのクセはfgetsの特徴のようです。
第五部 関数について
注意点も解ったと思いますので、後はガシガシ解いていくだけなのですが、最後に1つだけ大事なことをお伝えしておきます。
プログラミング言語には「関数」というものがあります。
上記でも何度か出てきましたが、関数とは「便利な箱のようなもの」です。
その箱の中に入れれば、箱特有の何やらわけのわからん処理をグチャグチャやってくれます。
第四部でお話ししたstrlenという箱は、箱の中に文字を入れた文字数を調べてくれるというものでした。
第三部でお話ししたexplodeという箱は、箱の中に区切り文字を入れたら、区切り文字ごと配列に放り込んでくれるというものでした。
この関数という箱は、他にもさまざまな箱があります。
特定の文字を置き換えるもの、並び替えをするもの、合計の計算をしてくれるものなどなど、それはもう数えきれないほどあります。
この関数で大切なことは、関数の使い方や存在を知らないと使えないということです。
(上底+下底)×高さ÷2という公式を知らずに台形の面積を求められますか?
まず無理だと思いますが、それと同じです。
関数の存在、公式の存在を知ってさえいれば、この問題はこの関数とあの関数を組み合わせれば解けるな・・・など思いつくはずです。
使い方を知っていれば、後は用法容量に沿って正しくお使いいただくだけ、何回でも使えるスペシャルアイテム、それが関数です。
それらよく使う主要な関数群は、PHPを学習していく上で身につくと思いますが、もちろん知らない時に問題に直面するシーンも出てきます。
そういうときは迷わずググりましょう。
問題を開始するとカウントダウンが始まりますが、その途中でも迷わずググりましょう。
関数を知らなければ解けないとは言えないまでも、関数を使わないとかなり苦労する場面が多いはずです。
その点、よく覚えておいてください。
尚、所詮関数の仕組みも中身はプログラムなので、最悪自分で考えることでなんとかなる場合もあります。
ちなみに下記はstrlen関数を自力で書いた場合の例です。
$input = 'paiza';
$count = 0;
while($input[$count]){
$count++;
}
echo $count;
while文で1文字づつ調べて存在をカウントしています。
記事は以上です。
皆様、Paizaのスキルチェック、上位ランカー目指して頑張ってください!
コメント