AtCoder Programming Guide for beginners(APG4b)をPHPで解く 1章

#1.00 はじめに
文字列の出力
PHP7(7.0.15)でAtCorderを解く場合、文字列の出力に改行も必要であるため、以下のコードでは、「WA」となる。

```
<?php
  echo "Hello, world!";
  ?>
```

「AC」にするには、```\n```を入れる。

```
<?php
  echo "Hello, world!\n";
  ?>
```

#1.01　出力とコメント
出力　```echo "(出力したいこと)";```
コメント 文頭に```#```、```//```　もしくは、コメントしたい範囲を```/*  */```で囲む。

##EX.1

```
<?php
  #hoge
  //hoge
  /*
  hoge
  */
  echo "こんにちは\n";
  echo "AtCoder\n";
  ?>
```

#1.02 プログラムの書き方とエラー
**コンパイルエラー** : 文法のエラー。プログラムは実行されない。
**実行時エラー** : 内容のエラー。プログラムは強制終了される。
**論理エラー** : プログラムは正しく動いているように見えてしまう。

**エラーの直し方**
行してエラーや出力を確認→プログラムを修正→実行してエラーや出力を確認→... を繰り返す。

##Ex.2

```
<?php
  echo "いつも2525\n";
  echo "AtCoderくん\n";
  ?>
```

#1.03 四則演算と優先順位

##四則演算
|演算子|計算内容|
|:----|----:|
|```+```|足し算|
|```-```|引き算|
|```*```|掛け算|
|```/```|割り算|
|```%```|割った余り|


##演算子の優先順位
|優先順位|高い|低い|
|:----|----|----:|
|演算子|```* / %```|```+``````-``` |

##注意
割り算はできるだけ後ろの方で行うようにしたほうが正しい結果になる。
```3 / 0```や```3 % 0```のように```0```で割ることはできない。（実行時エラー）
```0 / 3```や```0 % 3```のように割られる数が```0```の場合は問題なく計算できる。

##Ex.3

```
<?php
  echo (100*(100+1))/2;
  echo "\n";
  ?>
```

#1.04 変数と型

|型||
|:--|--:|
|boolean|論理型|
|integer|整数|
|float（または、double）|浮動小数点数|
|string|文字列|
|array|配列|
|resource|リソース|
|NULL|ヌル型|


##宣言
`$name`

##代入
`$name = 10`


##読み込み
```
echo $name;     //10
echo $name + 2; //10 + 2 → 12
echo $name * 3; //10 * 3 → 30
```

##Ex.4
```
<?php
  $seconds = 365 * 24 * 60 * 60;
  echo $seconds;
  echo "\n";
  echo $seconds * 2;
  echo "\n";
  echo $seconds * 5;
  echo "\n";
  echo $seconds * 10;
  echo "\n";
  ?>
```

#1.05 実行順序と入力
##入力
入力例
`1 2 3`

fgets()

```
$line = fgets(STDIN);
echo $line; //1 2 3
```

fscanf()

```
fscanf(STDIN, "%d %d %d", $a, $b, $c);
echo $a; //1
echo $b; //2
echo $c; //3
```

##Ex.5
```
<?php
  fscanf(STDIN,"%d %d", $a, $b);
  echo $a + $b;
  echo "\n";
  ?>
```

#1.06 if文・比較演算子・論理演算子

##if文

**if文**を使うと「ある条件が正しい時だけ処理をする」というプログラムが書ける
**else句**を使うと「条件式が正しくなかった時」の処理を書ける

##比較演算子

|演算子|意味|
|:--|:--|
|```x == y```|xとyは等しい|
|```x != y```|xとyは等しくない|
|```x > y```|xはyより大きい|
|```x < y```|xはyより小さい|
|```x >= y```|xはy以上|
|```x <= y```|xはy以下|

##論理演算子

|演算子|意味|真になる時|
|:--|:--|:--|
|```!(条件式)```|条件式の結果の反転|条件式が偽|
|```条件式1 && 条件式2```|条件式1が真かつ条件式2が真|条件式1と条件式2のどちらも真|
|```条件式1｜｜条件式2```|条件式1が真または条件式2が真|条件式1と条件式2の少なくとも片方が真|

##Ex.6

###floor関数

`floor(数値)`
float型の小数点以下の切り捨て。



```php
<?php
  fscanf(STDIN,"%d %s %d", $a, $op, $b);
  if ($op == "+") {
    echo $a + $b;
  } else if ($op == "-") {
	echo $a - $b;
  } else if ($op == "*") {
    echo $a * $b;
  } else if ($op == "/" && $b != 0) {
    echo floor($a / $b);
  } else {
    echo "error";
  }
  echo "\n";
?>
```

###ceil関数

`ceil(数値)`
float型の小数点以下の切り上げ。

###round関数

`round(数値[,桁数])`
float型の任意の桁数以下を四捨五入。
桁数を指定しなければ、小数点以下を四捨五入。

#1.07 条件式の結果とbool型

##条件式の結果

条件式の「計算結果」が真の時は`1`を返し、偽の時は何も返さない。

```php
<?php
  echo 5 == 5;
  echo "\n";
  echo 5 > 10;
  echo "\n";
  echo 5 < 10;
  echo "\n";
?>
```

標準出力⬇️

```php
1

1
```

条件式の部分に直接`0`や`1`を書ける。

```php
<?php
  if (1) { //true でも可
    echo "hello";
  }
  if (0) { //false でも可
    echo "world!";
  }
  echo "\n";
?>
```

標準出力⬇️

```php
hello
```

##Ex.7

```php
<?php
  // 変数$a,$b,$cにtrueまたはfalseを代入してAtCoderと出力されるようにする。
  $a = true; 
  $b = false;
  $c = true;

  // ここから先は変更しないこと
  #phpに対応するように変更します。
  if ($a) {
    echo "At";
  }
  else {
    echo "Yo";
  }

  if (!$a && $b) {
    echo "Bo";
  }
  else if (!$b || $c) {
    echo "Co";
  }

  if ($a && $b && $c) {
    echo "foo!";
  }
  else if (true && false) {
    echo "yeah!";
  }
  else if (!$a || $c) {
    echo "der";
  }

  echo "\n";
?>
```

#1.08 変数のスコープ

* `{ }`で囲われた部分のところを**ブロック**という
* 変数が使える範囲のことを**スコープ**という
* 変数のスコープは「変数が宣言されてからそのブロックが終わるまで
* スコープが重なっている場合は最も内側のブロックで宣言された変数が選ばれる

##Ex.8

```php
<?php
  fscanf(STDIN,"%d", $p);
  if ($p == 1) {
    fscanf(STDIN,"%d", $price);
  }
  if ($p == 2) {
    fscanf(STDIN,"%s", $text);
    fscanf(STDIN,"%d", $price);
    echo $text."!\n";
  }
  fscanf(STDIN,"%d", $N);
  echo $price * $N;
  echo "\n";
?>
```

#1.09 複合代入演算子

`x = x + (1 + 2)`と`x += 1 + 2`は、一緒の意味。
他にも`-=`、`*=`、`/=`、`%=`がある。

`x = x + 1`は`x++`または`++x`と書くことができる。
「1増やす操作」を**インクリメント**と言う。

`x = x - 1`は`x--`または`--x`と書くことができる。
「1減らす操作」を**デクリメント**と言う。

プログラムを短く書くための記法を**シンタックスシュガー**と言う。

##Ex.9

```php
<?php
  fscanf(STDIN,"%d %d %d", $x, $a, $b);
  $x++;
  echo $x."\n";
  $x *= $a + $b;
  echo $x."\n";
  $x *= $x;
  echo $x."\n";
  $x--;
  echo $x."\n";
?>
```

#1.10 while文

* **while文**を使うと繰り返し処理ができる
* 条件式が真の時処理を繰り返す

ループする回数を指定する場合、カウンタ変数をインクリメントもしくはデクリメントして、条件式が偽になるようにする必要がある。

## Ex.10

```php
<?php
  fscanf(STDIN,"%d %d", $A, $B);

  $count = 0;
  echo "A:";
  while ($count < $A) {
    echo "]";
    $count++;
  }
  echo "\n";

  $count = 0;
  echo "B:";
  while ($count < $B) {
    echo "]";
    $count++;
  }
  echo "\n";
?>
```

#1.11 for文・break・continue

for文は、「初期化」→「条件式」→「処理」→「更新」→「条件式」→「処理」→...という順で実行され、条件式が真のとき繰り返し続ける。

```php
for (初期化; 条件式; 更新) {
  処理
}
```

**break**を使うとループを途中で抜けられる。
**continue**を使うと後の処理を飛ばして次のループへ行ける。

##Ex.11

###マイナスの値を切り捨てる時
floor関数は、値が小さくなる方向で小数点を切り捨てるため、`floor(-2.3)`は`-3`と返される。

引数がマイナスの値の場合、整数にキャストした時と結果が異なる。
`floor(-2.9)` → `-3`
`(int)-2.9` → `-2`



```php
<?php
  fscanf(STDIN,"%d", $N);
  fscanf(STDIN,"%d", $A);

  for ($i=1; $i<=$N; $i++) {
    fscanf(STDIN,"%s %d", $op, $B);
    if ($op == "+") {
      $A += $B;
      echo "{$i}:{$A}"."\n";
    } else if ($op == "-") {
      $A -= $B;
      echo "{$i}:{$A}"."\n";
    } else if ($op == "*") {
      $A *= $B;
      echo "{$i}:{$A}"."\n";
    } else if ($op == "/" && $B != 0) {
      $A /= $B;
      $A = (int)$A;
      echo "{$i}:{$A}"."\n";
    } else {
      echo "error\n";
      break;
    }
  }
?>
```

#1.12 文字列と文字

`$str = 'abc'`とすると、
`strlen($str)`でstringのバイト数(ここでは`3`)を返す。
`$str[i]`で`i`文字目にアクセスできる。`i`は**添え字**といい、0から始まる。

##Ex.12

```php:Ex.12
<?php
  fscanf(STDIN,"%s", $S);
  $len = strlen($S);
  $a = 1;
  for ($i=1; $i<$len; $i++) {
    if ($i % 2 == 1) {
      $op = $S[$i];
    } else {
      if ($op == "-") {
        $a -= 1;
      } else {
        $a += 1;
      }
    }
  } 
  echo $a."\n";
?>
```

# 1.13配列

`array()`で配列を作ることができる。

```php

<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

// PHP 5.4 以降ではこのようにも書けます
$array = [
    "foo" => "bar",
    "bar" => "foo",
];
?>
```
```php
<?php
$array = array("foo", "bar", "hello", "world");
?>
```

`$array[i]`でi番目の要素へアクセスできる。
`count[$array]`で配列の要素数を取得できる。

## Ex.13

`explode()`
文字列を区切り文字で分割した結果を配列として返す。

```php
$line = fgets(STDIN);
// 半角スペースを区切りとして、配列に格納
$arr = explode(" ", $line);
echo $arr[0]; // 1
echo $arr[1]; // 2
echo $arr[2]; // 3
```

`array_sum()`
配列の合計値を返す。

`abs()`
絶対値を返す。

```php:Ex.13
<?php
  $N = fgets(STDIN);
  $line = fgets(STDIN);
  $arr = explode(" ", $line);
  $mean = array_sum($arr)/$N;
  for ($i=0; $i<$N; $i++) {
    echo abs((int)$mean-$arr[$i])."\n";
  }
?>
```

#1.14 STLの関数

## min関数
`min(a, b)`
`a`と`b`の2つの引数のうち、小さい方の値が取得できる。

## max関数
`max(a, b)`
`a`と`b`の2つの引数のうち、大きい方の値が取得できる。

## swap関数
`swap(a, b)`
`a`と`b`の2つの引数の値を交換する。

##array_reverse関数
`array_reverse($array)`
配列の要素の並びを逆にする。

##sort関数
`asort($array)`
配列の要素を小さい順に並び替えられる。

`arsort($array)`
配列の要素を大きい順に並び替えられる。


## Ex.14

```php:Ex.14
<?php
  fscanf(STDIN,"%d %d %d", $arr[0], $arr[1], $arr[2]);
  echo max($arr) - min($arr)."\n";
?>
```

#1.15 関数

```php
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "関数の例\n";
    return $retval; //戻り値
}

foo(); //実行
?>
```

## Ex.15
```php:Ex.15
<?php
  function output($sum_a, $sum_b, $sum_c){
    echo $sum_a * $sum_b * $sum_c."\n";
  }

  function input(){
    $line = fgets(STDIN);
    $arr = explode(" ", $line);
    return $arr;
  }
  
  function main(){
    $N = fgets(STDIN);
    
    $A = input();
    $B = input();
    $C = input();
    
    $sum_A = array_sum($A);
    $sum_B = array_sum($B);
    $sum_C = array_sum($C);
    
    output($sum_A, $sum_B, $sum_C);
  }

 main();
?>
```