こんにちは。倉内です。
paizaが提供しているプログラミングスキルチェックは、問題の難易度がS・A・B・C・Dの5段階に分かれており、ご自分のプログラミングスキルを測ることができます。
ただ、プログラミング学習を始めたばかりの人や、競技プログラミングの形式で問題を解いたことがない人にとってはちょっとハードルが高く感じるかもしれません。
そこで今回は初心者がプログラミング問題を解けるようになるための学習法について、実際にPHP初心者の私が動画講座で学習しながらお伝えします! プログラミング入門講座を探している人はぜひ参考にしてください。
スキルチェック問題を眺めてみよう
現在のキャンペーン問題はCランクですが、方針としては難易度のもっとも低いDランク問題を解けるようになってからCランク問題に挑戦することにします。
スキルチェックの本問題は解答・解説は公開できないルールなので、今回はレベルアップ問題集(練習問題と思ってください)の「スキルチェック見本問題」でDランク・Cランク相当の問題を眺めてから取りかかります。
なお、レベルアップ問題集の問題は制限時間はなく、問題内容を確認したあと調べたり人に聞いたりしても大丈夫ですのでどんどん練習に活用していきましょう!
プログラミング問題を解くための学習の進め方
私はC#とPythonはかじったことがあるので、今回は1度も触れたことがないPHPを学習して問題を解くことを目標にしたいと思います。
PHP入門編を受講しながらDランク相当問題に挑戦
paizaラーニングで提供している「PHP入門編」は全10レッスンあり以下のような内容になっています。
1: PHPをはじめよう
2: 条件によって処理を変えてみよう
3: ループ処理を学ぶ
4: 配列の基礎、explodeを学ぶ
5: 連想配列、foreach、ソートを学ぶ
6: 多次元配列を理解しよう
7: 関数を理解しよう
8: クラスを理解しよう
9: さらにクラスを理解しよう
10: 例外処理を理解しよう
他の言語の入門編も内容は大体似ているので、自分がやりたい言語に置き換えて見てみてください。プログラミング言語入門講座一覧はこちら
さてPHP入門編ですが、各レッスン配下にチャプターが6~12あるためすべて受講しようと思うとなかなかのボリュームですね。ただ、さっきスキルチェック見本問題を見た感じレッスン4あたりまで受講したらいけそうな気がします。
むしろ「Dランク問題はレッスン1(演算子での計算ができるようになるところまで)だけ受講したら解けるのでは…?」と思ったので、とりあえずレッスン1のチャプター8まで受講してから「掛け算」と「足し算」にチャレンジしてみました。
掛け算
・入力される値
入力は以下のフォーマットで与えられます。a
b
・期待する出力
aとbを掛け算した数値を出力して下さい。
・条件
すべてのテストケースにおいて、以下の条件をみたします。0 ≦ a ≦ 100
0 ≦ b ≦ 100
掛け算はどの言語でも同じく「*」の記号を使って数値を掛ければよいのと、出力は「echo hogehoge」でできると学びました。
たとえば、a=2, b=3と仮定すると以下で掛け算ができ、結果は「6」と出力されます。
<?php $a = 2; $b = 3; echo $a*$b; ?>
しかし…… 実際はa, bは固定値ではなく、与えられる値のためこのままでは正解になりません。外部から値が与えられることを「標準入力」と呼ぶのですが、頻繁に使うので習得しておきましょう。
(補足1)標準入力:1行ずつ処理
与えられた値を1行ずつ変数に入れるには以下のfgets関数を使います。trimで不要な前後の空白スペースを削除します。うしろの括弧内の「STDIN」は「standard input(=標準入力)」を意味しています。
ちなみに「PHP入門編3: ループ処理を学ぶ」のチャプター1、2で標準入力を解説しているため先に受講してしまってもよいかもしれません。
<?php $a = trim(fgets(STDIN)); $b = trim(fgets(STDIN)); echo $a*$b; ?>
「掛け算」の解答ページで、このコードを提出するとテストケースがすべて通り100点となります。
同様に「足し算」もクリアしてしまいましょう。「+」で数値を足せばいいのは分かりますが、今度は数値の与えられ方がさっきとちょっと違います。
足し算
・入力される値
入力は以下のフォーマットで与えられます。a b
・期待する出力
aとbを足した数を出力して下さい。
・条件
すべてのテストケースにおいて、以下の条件をみたします。0 ≦ a ≦ 100
0 ≦ b ≦ 100
(補足2)標準入力:1行にスペース区切りで複数の値
1行に複数の値が与えられたときはexplode関数で分割する処理を書く必要があります。今回は半角スペースですが、カンマなどで区切られている場合もこの処理が使えます。(" " の部分を "," にすればよい)
<?php list($a, $b) = explode(" ", trim(fgets(STDIN))); echo $a+$b; ?>
explode関数は配列と合わせて「PHP入門編4:配列の基礎、explodeを学ぶ」の講座で学ぶことができます。標準入力を受け取る以外でも利用シーンが多いため、あとで学習しておいたほうがいい内容だと思います。
「足し算」の解答ページで、上記のコードを提出するとテストケースがすべて通り100点となります。
一番小さい値
・入力される値
入力は以下のフォーマットで与えられます。n_1
n_2
n_3
n_4
n_51 行目から 5 行目に正の整数 n_1, n_2, n_3, n_4, n_5 が与えられます。
・期待する出力
n_1, n_2, n_3, n_4, n_5 のうち最も小さい数字を出力して下さい。
・条件
すべてのテストケースにおいて、以下の条件をみたします。・1 ≦ n_1, n_2, n_3, n_4, n_5 ≦ 100
解法はいくつかあると思いますが、今回は与えられた値の1つ目と2つ目を比べて小さい値を残して、それをさらに次の値と比べる…という方法で解こうと思います。
「もし1つ目のほうが小さかったら残す、もし2つ目のほうが…」という条件で処理を分ける必要があるので「PHP入門編2: 条件によって処理を変えてみよう」を受講しましょう。
ここまで学習した内容で解くと以下のようなプログラムになりました。これでも提出すると100点がもらえます。
<?php // 今回は与えられる値は5つ固定なので予め5つ入れておく $n1 = trim(fgets(STDIN)); $n2 = trim(fgets(STDIN)); $n3 = trim(fgets(STDIN)); $n4 = trim(fgets(STDIN)); $n5 = trim(fgets(STDIN)); // 最小値を入れるための変数 // 初期値はn1としておく $min = $n1; // 残りを比較する if($n2 < $min){ $min = $n2; } if($n3 < $min){ $min = $n3; } if($n4 < $min){ $min = $n4; } if($n5 < $min){ $min = $n5; } // 最小値を出力 echo $min; ?>
間違いではないですが、もうちょっとスマートに解きたいですよね…。そこで比較処理が何度も出てくるので、これをスッキリさせるために「PHP入門編3: ループ処理を学ぶ」を学習します。
また、5つの値を異なる変数に入れたままだとループ処理での比較がやりづらいので、「PHP入門編4:配列の基礎、explodeを学ぶ」も受講して配列に入れる処理も習得したいと思います。
ループ処理を使ってこのように書くことができました。提出するとスコアは100点です。
<?php // 今回は与えられる値は5つ固定なので予め5つ入れておく $n1 = trim(fgets(STDIN)); $n2 = trim(fgets(STDIN)); $n3 = trim(fgets(STDIN)); $n4 = trim(fgets(STDIN)); $n5 = trim(fgets(STDIN)); // 5つの値を配列に入れる $num_list = array($n1, $n2, $n3, $n4, $n5); // 最小値を入れるための変数 // 初期値はn1としておく $min = $n1; // 配列の先頭から順番に比較してminより小さかったら更新 for($i = 0; $i < 5; $i++){ if($num_list[$i] < $min){ $min = $num_list[$i]; } } // 最小値を出力 echo $min; ?>
(補足3)標準入力:複数行の入力
さきほどの解答では入力値を1つずつ受け取り変数に格納しましたが、ループ文を使って複数行受け取るための処理も習得しておきましょう。
配列への値の追加の処理はレッスン4のチャプター「03:配列の基本操作2」で学習します。
<?php // 値を入れるための配列を用意する $num_list = []; // ループ文を使って複数行の値を受け取る $n = 5; for($i = 0; $i < $n; $i++){ $num_list[] = rtrim(fgets(STDIN)); } // 最小値を入れるための変数 // 初期値は1つ目の値としておく $min = $num_list[0]; // 配列の先頭から順番に比較してminより小さかったら更新 for($i = 0; $i < $n; $i++){ if($num_list[$i] < $min){ $min = $num_list[$i]; } } // 最小値を出力 echo $min; ?>
冗長な部分がだいぶ解消されました。プログラミング学習を始めたばかりの方にとっては少し難しく感じるかもしれませんが、if文とfor文の書き方は問題をたくさん解くと自然に身につくと思います。
数の並び替え
・入力される値
入力は以下のフォーマットで与えられます。n (数字の総数)
a_1
a_2
a_3
...
a_i
...
a_n
・期待する出力
入力された正の整数a_iを小さい順に改行区切りで出力してください。
・条件
すべてのテストケースにおいて、以下の条件をみたします。1 ≦ n ≦ 100
1 ≦ i ≦ nについて、1 ≦ a_i ≦ 1000
さきほどの問題と似ていますが、一番小さい値を出せばいいのではなく、昇順にソートした結果を順番に出力する必要があります。また、出力結果は改行が必要です。
Dランク相当の中ではやや難しいほうかもしれません。
<?php // ソート対象の値が何個与えられるか $n = (int)trim(fgets(STDIN)); // ループ文を使って複数行の値を受け取る for($i = 0; $i < $n; $i++){ $num_list[] = rtrim(fgets(STDIN)); } // 単純ソートする // n回分繰り返す for($i = 0; $i < $n; $i++){ // n個-1回繰り返す for($k = 1; $k < $n; $k++){ // 隣同士比較して昇順じゃなかったら入れ替える // 入れ替え時の退避先としてtempを使用 if($num_list[$k-1] > $num_list[$k]){ $temp = $num_list[$k]; $num_list[$k] = $num_list[$k-1]; $num_list[$k-1] = $temp; } } } for($i = 0; $i < $n; $i++){ echo $num_list[$i]."\n"; } ?>
このプログラムでも提出でスコアは100点獲得できますが、PHPにはソートの関数があるためそれを使ってみましょう。
ちなみにソートは、「PHP入門編5:連想配列、foreach、ソートを学ぶ」で学習できます。
<?php // ソート対象の値が何個与えられるか $n = (int)trim(fgets(STDIN)); // ループ文を使って複数行の値を受け取る for($i = 0; $i < $n; $i++){ $num_list[] = rtrim(fgets(STDIN)); } // sort関数を使う sort($num_list); for($i = 0; $i < $n; $i++){ echo $num_list[$i]."\n"; } ?>
さっき苦労して書いた条件文はなんだったのか…と思いますよね。
こんなふうによく使う処理は関数が用意されていることが多いので、一度使える関数がないか調べてから取り掛かってみるのもよいでしょう。(ただ、自分でソートの処理を書けるか(理解しているか)も大事なので最初のうちは自力で書くのも勉強になります。)
文字の一致
・入力される値
入力は以下のフォーマットで与えられます。a
b1 行目に文字列 a
2 行目に文字列 b
・期待する出力
文字列 a と文字列 b が一致していれば "OK" 、異なっていれば "NG" と出力してください。
・条件
すべてのテストケースにおいて、以下の条件をみたします。・1 ≦ 文字列 a の長さ ≦ 100
・1 ≦ 文字列 b の長さ ≦ 100
今まで数値を扱ってきましたが、基本的には文字列も同じように処理します。文字列が一致しているかは「==」で見ることができます。
<?php $a = trim(fgets(STDIN)); $b = trim(fgets(STDIN)); if($a == $b){ echo "OK"; } else { echo "NG"; } ?>
Cランク相当問題に挑戦
ここまで標準入力の習得とPHP入門編をレッスン4(ソートの関数を使う場合はレッスン5)まで受講して、Dランク相当の問題を5問解きました。
Cランク問題はDランクで使った処理を複数組み合わせて解きます。問題文と条件が少し複雑になりますが、じっくり読み解けば大丈夫です。
単語のカウント
・入力される値
半角スペースで区切られた長さNの文字列(例)red green blue blue green blue
・期待する出力
単語、半角スペース、出現回数の順で1行に1単語で出現したすべての単語を、列に出現する順に出力してください。
・条件
全てのテストケースにおいて以下の条件を満たします。1 ≦ N ≦ 1,000
<?php // 単語を区切って配列に格納する $words = []; $words = explode(" ", trim(fgets(STDIN))); // 配列に単語がある分チェックする while($words){ // 数える単語をcount_wordに、数をcount_numに入れる $count_word = $words[0]; $count_num = 0; // count_wordがwords配列の中に何個あるか数える for($i=0; $i < count($words); $i++){ if($words[$i] == $count_word){ $count_num++; } } // 指定されたフォーマットで単語と数を出力する echo $count_word." ".$count_num."\n"; // 1度数えた単語は数えたくないので // 数え終わった単語を除いた新しい配列を作成する $new_words = []; for($j=0; $j < count($words); $j++){ if($words[$j] != $count_word){ $new_words[] = $words[$j]; } } // 新しい配列をwordsにする $words = $new_words; } ?>
この問題は「スキルチェック入門編3:単語のカウント (Cランク)」で詳しく解説しているので合わせてごらんください。(動画内ではPython3で解答)
Fizz Buzz
・入力される値
入力は以下のフォーマットで与えられます。N
N は1以上N以下の整数です。
・期待する出力
1からNまでの整数を1から順に表示してください。ただし、表示しようとしている数値が、
・3の倍数かつ5の倍数のときには、"Fizz Buzz"
・3の倍数のときには、"Fizz"
・5の倍数のときには、"Buzz"を数値の代わりに表示してください。
・条件
すべてのテストケースにおいて、以下の条件をみたします。・1 ≦ N ≦ 100
・N は整数
倍数かどうかは割り算のあまりでみることにしましょう。for文とif文を組み合わせた以下のようなコードになりました。提出するとスコア100点を獲得できます。
<?php // 与えられる数字の個数 $N = (int)trim(fgets(STDIN)); // 1からN個分判定する for($i=1; $i < $N+1; $i++){ // 3で割ってあまり0 if($i % 3 == 0){ // かつ5で割ってあまり0 if($i % 5 == 0){ echo "Fizz Buzz"."\n"; // 5では割り切れない } else { echo "Fizz"."\n"; } } // 3では割り切れないが5で割ってあまり0 elseif($i % 5 == 0){ echo "Buzz"."\n"; } // 3でも5でも割り切れない場合そのまま数字を出力 else { echo $i."\n"; } } ?>
「Fizz Buzz」については「アルゴリズム入門編: FizzBuzzとフィボナッチ数を学ぶ」で詳しく解説していますのでぜひチェックしてみてください。
PHPで初めてコーディングしましたが、動画講座を受講し、課題をこなしてからスキルチェック問題(練習問題)をやったおかげで基礎文法はだいぶ身につきました。今週のキャンペーン問題はPHPで解いてみようかなと思います。
また、PHPを選んだ理由が「WebアプリケーションフレームワークのLaravelのおかげでPHP人気が上がってきていて気になっていた」というのもあったので、paizaラーニングのLaravelの講座ものちほど手を出したいと思います。
まとめ
初めてPHPを学習し、練習問題ではありますがDランク問題とCランク問題を解いてみました。
同じランクでもさまざまな問題があるので、できるだけ引き出しを増やすために入門編のレッスン10まで受講していただけるとさらに理解が深まると思います。
今回使えそうな関数がないか調べてみたように、スキルチェック本問題もご自分で調べて解くのは問題ありませんので、「こうやりたいけど実装方法が分からん…」というのは「こうやりたい」を調べて解いてみてください。
Amazonギフト券が当たるキャンペーンは今日から3週目がスタートです。Cランク問題ですのでぜひキャンペーン問題にチャレンジしてみてください!なお、正解できなくても抽選対象にはなりますので挑戦だけでもOKです。
「paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。
詳しくはこちら
そしてpaizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。
詳しくはこちら