takenoko03の日記

PHP言語で仕事する

PHP 問題:紙の張り合わせ

-新しく学んだこと-

・print_r( )

・for繰り返し

 

問題:

折り紙を連結して 1 枚の大きな紙の垂れ幕を作ることにしました。

各折り紙は 1 辺の長さが D cm 、すなわち縦 D cm × 横 D cm の正方形です。これらの折り紙を、左右に長く伸びた直線を基準に貼り付けていきます。ただし、各折り紙について、いずれか 1 辺がちょうど直線に重なるようにします。
また、 1 枚目を貼り付けたあと、 2 枚目以降は以下のルールに従って順に貼り付けていきます。

・1 つ前に貼り付けた折り紙の右辺からみて、 1 cm 以上 D/2 cm 以下だけ重なるように貼り付ける。(下図に例を示しています。)

上記のルールを守って作られたある垂れ幕について、基準の直線を平面座標の x 軸とみなして、2 枚目以降の各折り紙における 1 つ前の折り紙への重なり具合が与えられます。
1 枚になった垂れ幕部分の面積を計算してください。
例えば、入力例 1 では以下のように計算できます。

入力例1

3 4  枚数 1辺の長さ

2    重なる長さ1

1    重なる長さ2

 

出力 36

 

プログラミングの前にフローチャートを作ります。

プログラムに直すと

3行目:垂れ幕の面積用の箱$mensekiを用意します。

4行目:重なっていない長さ用の箱$kasaneを用意します。

5行目:垂れ幕横の長さ用の箱$yokoを用意します。

6行目:入力が終わるまで{ }内の処理を繰り返します。

7行目:入力を配列$stdin_arrayに入れます。

$stdin_array[0]=3 4

$stdin_array[1]=2

$stdin_array[2]=1

となります。

9行目:配列$kamiを用意します。今回は、$stdin_array[0]=3 4を3と4に分けるために用意しました。

10行目:中身が無くなるまで繰り返し、$valueの箱に$stdin_arrayの数字を入れます。

11行目:$valueの中身に空白があれば区切り、$kamiの箱へ入れます。

$kami[0]=3

$kami[1]=4

$kami[2]=2

$kami[3]=1

となります。

13行目:$yokoの箱に$kami[1]の数字を入れます。

14行目:$countの箱に2を入れ、$countの数字が$kami[1]の数字以下である間は{ }の処理を繰り返します。繰り返す毎に$countの数字に1加算します。

15行目:重なっていない長さ=1辺の長さ-重なる長さ

16行目:垂れ幕横の長さ=垂れ幕横の長さ+重なっていない長さ

18行目:垂れ幕の面積=一辺の長さ×横の長さ

19行目:垂れ幕の面積を出力する。

 

・print_r(表示したい式や値)

情報をわかりやすく表示したい時に使います。

筆者は、11行目で配列の内容が上手くいっているかを確認するために

12行目にprint_r($kami);を追記しました。確認後は消しています。

 

・for(初期化式;条件式;変化式){ }

初期化式は、for分の処理が開始される時に1度だけ実行されます。条件に使う変数などを初期化する式が入ります。

条件式は、繰り返すかどうかの判断する式が入ります。

変化式は、繰り返しが1回行われる毎に、変数などを変化させたい時に使います。

PHP 問題:渋滞情報

-新しく学んだこと-

・複数行の標準入力

・foreachで繰り返し

・文字列の結合

 

問題:

ある道路の車の数と、各車の車間距離が与えられるので、車間距離が M メートル以下の場合を渋滞と定義したとき、渋滞の区間が合計で何メートルあるか求めてください。

 

入力は以下のルールがあります。

X Y

M-1

M-2

・・・

M-[N-1]

1行目には、車の数Xと渋滞になる距離が半角スペースで区切られます。

2行目からは、先頭から数えてM番目とM+1番目の車間間隔を表します。

 

入力例1

5 10

5

6

25

4

答え

15

 

プログラミングの前に動きのイメージをします。

プログラムに直すと

4行目:カウントを用意します。今回は、車間距離が入力の2行目から始まるので2を入れています。

5行目:車間距離の合計用の箱を用意します。

6行目:入力が終わるまで{}内の命令を繰り返します。

7行目:入力を$num_arrayに入れます。

$num_array[0] = 5 10

$num_array[1] = 5

$num_array[2] = 6

$num_array[3] = 25

$num_array[4] = 4

となります。

9行目:$each_valueという箱を用意します。今回は、$num_array[0] = 5 10を、5と10に分けるために用意しました。

10行目:中身が無くなるまで繰り返し、$valueの箱に$num_arrayの数字を移します。

11行目:$valueの中身に空白があれば区切り、$each_valueの箱へ入れます。

$each_value[0] = 5

$each_value[1] = 10

$each_value[2] = 5

$each_value[3] = 6

$each_value[4] = 25

$each_value[5] = 4

となります。

13行目:カウント(~番目の車)が車の数より小さい間は、{}内の命令を繰り返します。

14行目:車両間隔が渋滞距離以下かを判断します。

15行目:車両間隔が渋滞距離以下ならば、合計に車両間隔を加算していきます。

17行目:カウントに+1していきます。次の$each_value[]を参照するため。

 

・複数行の標準入力

まず、入力された数字を1行ごとに分けてから、空白が有るなら区切り、1種類の箱に結合していきます。

今回は、1行目の数字が空白で区切られていること、複数行の入力があることから、

6行目~12行目の命令をしています。

 

・foreach(要素を取り出す配列,取り出した要素を格納する変数)

配列の要素の数だけ命令を繰り返します。

今回は、$num_arrayの数字を$each_valueの箱に入れています。

 

・array_merge(最初の配列名,追加する配列1,追加する配列2,,,)

最初の配列の後に、追加する配列を連ねていきます。

今回は、$each_valueという空の箱に$value(入力された数字が入っている箱)内の数字を連ねていきます。

PHP 問題:プレゼント企画

-新しく学んだこと-

・標準入力の空白区切り

・条件式 AかつB

・繰り返し

 

問題:

あなたは、プレゼント企画を実施しました。

プレゼントはAとBの2種類があります。

 

当選者は以下の条件に従って、選ばれます。

・Xの倍数番目はプレゼントA

・Yの倍数番目はプレゼントB

 

応募者毎に当選情報を出力してください。プレゼントAとBの両方当選した人はAB,Aだけ当選した人はA,Bだけ当選した人はB,どちらも当選してない人はNを表示してください。

 

入力例1

5 2 4

答え

N

A

N

AB

 

プログラミングの前に動きのイメージをします。

プログラムに直すと

3行目:必要の無い行です。プレゼントの種類を入れるつもりでした。

4行目:応募者の~番目を入れるための箱を用意しました。

5行目:入力された数字を$numに入れます。

6行目:$numを対象に空白で区切り、$array[0~2]それぞれに数字を入れます。

$array[0]は、応募者。$array[1]は、Xの倍数。$array[2]は、Yの倍数です。

7行目:応募者の番目が応募者数より小さい間は、8~19行目の命令を続けます。

8行目:番目の数字に+1します。(最初は1番目となります)

9行目:Xで割り切れる かつ Yで割り切れる番目なのかを判断します。

10行目:9行目の条件に合えば”AB”を表示します。

12行目:9行目の条件に合わず、Xで割り切れる番目なのかを判断します。

13行目:12行目の条件に合えば”A”を表示します。

15行目:9行目の条件に合わず、Yで割り切れる番目なのかを判断します。

16行目:15行目の条件に合えば”B”を表示します。

18行目:9、12、15行目の条件に合わなければ、”N”を表示します。

 

・explode(区切り文字,対象)

対象の文字列を区切り文字で分割します。

今回は、5 2 4の文字列を対象に空白(” ”)を区切り文字としています。

 

・条件式 &&

条件式を組み合わせたい場合につかいます。

今回は、A && B AかつBである場合を使っています。

他には

A || B AもしくはB当てはまる。

A xor B AかBのどちらか1つだけが当てはまる。

などがあります。

 

・while(条件式){}

条件式に合うあいだは、{}内の命令を繰り返します。

今回は、応募者の番目が応募者数より小さいあいだは を条件式にしています。

PHP 問題:文字の装飾

-新しく学んだこと-

・文字数のカウント

・文字列の埋め方

・複数行の表示

 

問題:入力された文字列の周囲を”+”で枠のように囲んで表示させてください。

 

入力例1 Paiza

答え +++++++

   +Paiza+

   +++++++

 

プログラミングの前に動きのイメージをします。

プログラムに直すと

3行目:全体用の箱を用意します。

4行目:”+”の行が入る箱を用意します。

5行目:文字数のカウント用の箱を用意します。

6行目:入力された文字を$mojiに受け取ります。

7行目:文字数を$kazuに入れます。

8行目:文字数+2を上限に”+”を$kazariに入れます。

9行目:文字数+2を上限として、$mojiの両脇へ”+”を加えて、$mojikazariに入れます。

10行目:<<< EOMからEOM; までの命令を$zenに入れます。

14行目:$zenを出力します。

 

・mb_strlen(対象)

対象内の文字を数えます。英数字・ひらがな区別無く1文字は1つとして数えます。

 

・str_pad(埋めたい文字列,合計で何文字にするか,埋める文字,どこを埋めるか)

入力例1では、Paizaを埋めたい文字列、文字列+2を上限として、”+”を埋める文字、両埋めとしています。

右埋め:STR_PAD_RIGHT

左埋め:STR_PAD_LEFT

両埋め:STR_PAD_BOTH

 

・= <<< EOM ~ EOM;

ヒアドキュメントといわれます。

<<<がヒアドキュメントの合図で、この次に書いた文字が再び現れるまですべて=に設定された箱(変数)へ入れます。ここに入力された通りに表示したい時、複数行を表示したい時に役立ちます。

PHP 問題:奇数か偶数か

-新しく学んだこと-

・条件文if

 

問題:

入力される整数が奇数であれば「odd」と出力し、偶数であれば「even」と出力されるようにしてください。

 

入力例1 4 答え even

入力例2 5 答え odd

入力例3 2 答え even

出力最終行の末尾に改行を入れ、余計な文字、空白を含んではいけません

 

プログラミングの前に動きのイメージします。

プログラムに直すと

3行目:入力された整数を$kazuの箱に入れます。

4行目:条件文ifを用いて、($kazu割る余り2の答えが0ならば)5行目の命令を行います。

5行目:「even」を出力します。「."\n"」の部分は文章終わりに改行すると命令しています。

7行目:elseを用いて($kazu割る余り2の答えが0でなければ)8行目の命令を行います。

8行目:「odd」を出力します。

 

・if(条件){}

()内の条件に当てはまれば、{}内の命令を行います。

elseはifの条件に当てはまらなければ、{}内の命令を行います。

PHP 問題:身長の差

-新しく学んだこと-

・出力に改行を含ませる

 

問題

A君の身長(a)とB君の身長(b)の差を求めてください。

A君の身長はB君の身長以上に高いものとする。

 

入力例1 a=180 答え 30

     b=150

 

入力例2 a=201 答え 200

     b=1

出力最終行の末尾に改行を入れ、余計な文字、空白を含んではいけません

 

プログラミングの前に動きのイメージします。

プログラムにすると

3行目:$shincho(身長差)の箱を用意します。

4行目:入力が続く限り以下の命令を繰り返します。

 1行目入力されると、1つ目の箱$stdin_array[0]に文字列を入れます。

 2行目が入力されると、2つ目の箱$stdin_array[1]に文字列を入れます。

 3行目が~3つ目の箱に入れます。というように行動します。

7行目:2人の身長差を、$stdin_array[0](A君の身長) 引く $stdin_array[1](B君の身長)で計算します。

8行目:$shinchoを表示します。「."\n"」の部分は、文字列の最後に改行するために付けています。

 

・出力に改行を含ませる

「."\n"」の部分です。ここで重要なのは「" "」で囲む事で、この記号が無いと命令に認識されません。

以上で、問題を終わります。

PHP 問題:分けて余った数

-新しく学んだこと-

・条件付き

・入力の改行くぎり

・割り算の余り

 

問題

y個のお菓子をx人で分けて、余った個数を求めてください。

分ける人数Xとお菓子の個数yは、改行くぎりで入力されます。

 

入力例1 x=5  答え 2

     y=17

 

入力例2 x=2  答え 0

     y=4

 

プログラミングの前に動きをイメージします。

プログラムにすると

3行目:余り用の箱を用意します。

4行目:while()は、入力があるかぎりは、以下の命令を繰り返します。

 1行目入力されると、1つ目の箱$stdin_array[0]に文字列を入れます。

 2行目が入力されると、2つ目の箱$stdin_array[1]に文字列を入れます。

 3行目が~3つ目の箱に入れます。というように行動します。

7行目:$stdin_array[1](お菓子の個数)を$stdin_array[0](人数)で割った余りを$nokoriに入れます。「%」が割る余りの計算を表します。

8行目:$nokoriを表示します。

 

・条件文while()

今回の標準入力は、改行でくぎられた2つの数字になります。

このように縦一列になったデータには、上記のwhile文が使えます。

イメージでは$hito=$stdin_array[0] $okasi=$stdin_array[1]で分類しています。

プログラムの世界では、1つ目の箱は「0」から数え始めます。

以上で、問題を終わります。