PHP

合格者0だったコーディング採用試験をやる

 

fizzbuzzみたいな。

FizzBuzzのコマンドラインアプリをつくる問題なのだが、

// 直接問題は載せれない

出力するとこうなるようにする

$ php fizzbuzz.php 7:fizz 8:buzz 20
20

 

$ php fizzbuzz.php 4:fizz 5:buzz 20
fizzbuzz

 

$ php fizzbuzz.php 6:fizz 3:buzz 5:piyo 20
piyo

 

$ php fizzbuzz.php 2:fizz 4:buzz 5:piyo 20
fizzbuzzpiyo

 

fizzbuzz $ php fizzbuzz.php 4:fizz 3:buzz 5:piyo 2000
fizzpiyo

fizzbuzz $ php fizzbuzz.php 4:fizz 3:buzz 5:piyo 2001
割られる数が大きすぎます

 

$ php fizzbuzz.php 4:fizz 3:fizzodd 5:fizz1 10:boss 12:boss2 4:fizz 3:fizzodd 5:fizz1 10:boss 12:boss2 4:fizz 3:fizzodd 5:fizz1 10:boss 12:boss2 4:fizz 3:fizzodd 5:fizz1 10:boss 12:boss2 4:fizz 3:fizzodd 5:fizz1 10:boss 12:boss2 2000
データ数が多すぎます

 

fizzbuzz $ php fizzbuzz.php 4:abcdefghijklmn 3:buzz 5:piyo 2000
文字数が多すぎます

 

fizzbuzz $ php fizzbuzz.php 4:fizz 3:buzz 1:fizz2  5:buzz 2000
重複した文字列が偶数配列にあります

fizzbuzz $ php fizzbuzz.php 4:fizz 3:buzz 1:fizz  5:buzz2 2000
重複した文字列が奇数配列にあります

 

 

作ったった

  • PHP7.4

PHP7.3以下では動かないので注意

 

fizzbuzz.php

<?php

$app = new FizzBuzz($argv);
$app->execute();

class FizzBuzz
{
    const INT_INDEX = 0;
    const STRING_INDEX = 1;
    const LIMIT_DATA_COUNT = 20;
    const LIMIT_STRLEN = 11;
    const LIMIT_INT_TARGET_VALUE = 2000;

    private Array $data;
    private Int $intTarget; // 割られる数

    public function __construct($argv)
    {
        array_splice($argv, 0, 1);                 // コマンドで与えられた配列からファイル名を抜く
        $arrayLastIndex = count($argv) - 1;
        $this->intTarget = $argv[$arrayLastIndex];
        array_splice($argv, $arrayLastIndex, 1);   // 割られる数を配列から抜く

        foreach ($argv as $key => $val) {
            $tmp = explode(':', $val);
            $this->data['int'][] = $tmp[self::INT_INDEX];
            $this->data['string'][] = $tmp[self::STRING_INDEX];
        }
    }

    public function execute()
    {
        $error = self::validate();
        if (isset($error)) {
            return print $error;
        }

        $resultString = "";
        $max = count($this->data['int']);
        for ($i = 0; $i < $max; $i++) {
            // 割り切れる値の文字列を連結
            if ($this->intTarget % $this->data['int'][$i] === 0) {
                $resultString .= $this->data['string'][$i];
            }
        }

        return !empty($resultString) ? print $resultString : print $this->intTarget;
    }

    private function validate()
    {
        // データ数チェック
        if (count($this->data['int']) > self::LIMIT_DATA_COUNT) {
            return 'データ数が多すぎます';
        }

        $oddArray = array();
        $evenArray = array();
        $oddArray = array_map('current', array_chunk($this->data['string'], 2));                   // 奇数配列
        $evenArray = array_map('current', array_chunk(array_slice($this->data['string'], 1), 2) ); // 偶数配列

        // 偶数データの文字数チェック
        foreach ($evenArray as $key => $val) {
            if (strlen($val) > self::LIMIT_STRLEN) {
                return '文字数が多すぎます';
            }
        }
        // 割られる数が2000以下であるかチェック
        if ($this->intTarget > self::LIMIT_INT_TARGET_VALUE) {
            return '割られる数が大きすぎます';
        }
        // 奇数・偶数列でそれぞれで文字列が一意である
        $oddValueCount = array_count_values($oddArray);
        $oddMax = max($oddValueCount);
        $evenValueCount = array_count_values($evenArray);
        $evenMax = max($evenValueCount);
        if ($oddMax !==1) {
            return '重複した文字列が奇数配列にあります';
        }
        if ($evenMax !== 1) {
            return '重複した文字列が偶数配列にあります';
        }
    }
}

 

 

 

ポイント① 引数の受け取り方

 

$ php fizzbuzz.php 引数

こういう形で実行すると、

PHPファイルで引数を$argv変数で受け取ることができる。

 

ポイント② 奇数配列

  • $evenArray = array_map(‘current’, array_chunk($data[‘string’], 2));

array_map(‘関数’,  配列)

array_mapは配列要素1つずつに、関数の処理をループさせて与える関数

array_chunk(配列, 分割単位数)

<?php

$array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

$arrayChunk2 = array_chunk($array, 2);
var_dump($arrayChunk2);

a, c, , e, gの配列を取得を目指す。

結果

array(4) {
  [0]=>
  array(2) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
  }
  [1]=>
  array(2) {
    [0]=>
    string(1) "c"
    [1]=>
    string(1) "d"
  }
  [2]=>
  array(2) {
    [0]=>
    string(1) "e"
    [1]=>
    string(1) "f"
  }
  [3]=>
  array(1) {
    [0]=>
    string(1) "g"
  }
}

 

<?php

$array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

$array = array_map('current', array_chunk($array, 2));
var_dump($array);

 

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "c"
  [2]=>
  string(1) "e"
  [3]=>
  string(1) "g"
}

奇数配列ができた

 

ポイント③ 偶数配列

b, d, fの配列取得を目指す。

<?php

$array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

$array = array_slice($array, 1);
var_dump($array);
array(6) {
  [0]=>
  string(1) "b"
  [1]=>
  string(1) "c"
  [2]=>
  string(1) "d"
  [3]=>
  string(1) "e"
  [4]=>
  string(1) "f"
  [5]=>
  string(1) "g"
}

array_sliceでaを削いだ。

 

<?php

$array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

$array = array_chunk(array_slice($array, 1), 2);
var_dump($array);
array(3) {
  [0]=>
  array(2) {
    [0]=>
    string(1) "b"
    [1]=>
    string(1) "c"
  }
  [1]=>
  array(2) {
    [0]=>
    string(1) "d"
    [1]=>
    string(1) "e"
  }
  [2]=>
  array(2) {
    [0]=>
    string(1) "f"
    [1]=>
    string(1) "g"
  }
}

 

array_mapでcurrent()を配列に適用する

<?php

$array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

$array = array_map('current', array_chunk(array_slice($array, 1), 2));
var_dump($array);
array(3) {
  [0]=>
  string(1) "b"
  [1]=>
  string(1) "d"
  [2]=>
  string(1) "f"
}

偶数配列が取れた!

 

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)