こんなズンドコきよしは嫌だ

# ズンドコキヨシとは
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから<br>「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ！」って出力した後終了って関数作ったら満点で単位貰ってた</p>&mdash; てくも (@kumiromilk) <a href="https://twitter.com/kumiromilk/status/707437861881180160?ref_src=twsrc%5Etfw">2016年3月9日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

# 実装例

```php
<?php
$a = [];
while (true) {
    $a[] = $zd = ['ズン', 'ドコ'][mt_rand(0, 1)];
    $a = array_slice($a, -5);
    echo $zd, PHP_EOL;
    if ($a[0] === 'ズン'
        && $a[1] === 'ズン'
        && $a[2] === 'ズン'
        && $a[3] === 'ズン'
        && $a[4] === 'ドコ') {
        echo 'キ・ヨ・シ！', PHP_EOL;
        break;
    }
}
```

---

# こんなズンドコキヨシは嫌だ
- gotoでループを実現している

```php
<?php
$zundoko = '';
zundoko:
    $zundoko .= $zd = ['ズン', 'ドコ'][mt_rand(0, 1)];
    echo $zd, PHP_EOL;
    if (mb_substr($zundoko, -10) === 'ズンズンズンズンドコ') {
        die('キ・ヨ・シ！' . PHP_EOL);
    }
    goto zundoko;
```

---

# こんなズンドコキヨシは嫌だ
- 変数とか甘え

```php
<?php
ob_start();
while (true) {
    echo ['ズン', 'ドコ'][mt_rand(0, 1)];
    if (mb_substr(ob_get_contents(), -10) === 'ズンズンズンズンドコ') {
        break;
    }
}
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer, 'キ・ヨ・シ！', PHP_EOL;
```

---

# こんなズンドコキヨシは嫌だ
- `__toString()` に実装されている
    - 変数、クラス名は全て日本語
    - `ズン`, `ドコ`, `キ・ヨ・シ！`は定義せず変数名やクラス名から取得する
    - 無名関数の即時呼び出しのジェネレータでループ

```php
<?php
class ズンドコキ・ヨ・シ！
{
    public function __toString()
    {
        $ズンズンズンズンドコ = null;
        foreach ((function($ズンドコ) {
            loop: yield $ズンドコ[mt_rand(0, 1)];
            goto loop;
        })(str_split(__CLASS__, 6)) as $どっちか) {
            echo $どっちか, PHP_EOL;
            $ズンズンズンズンドコ .= $どっちか;
            if (strstr($ズンズンズンズンドコ, key(get_defined_vars()))) {
                return mb_substr(__CLASS__, -6) . PHP_EOL;
            }
        }
    }
}

echo new ズンドコキ・ヨ・シ！();
```

---

# こんなズンドコキヨシは嫌だ
- ズン, ドコの出力がクラスの `__get()` 内
- バッファした標準出力を用いて比較
- クラス変数の名前とクラス名を用いてズン, ドコを出力

```php
<?php
class ズンドコキ・ヨ・シ！
{
    private $_0_2;
    private $_2_2;

    public function __get($name)
    {
        list(, $offset, $limit) = explode('_', $name);
        echo mb_substr(__CLASS__, $offset, $limit), PHP_EOL;
    }
}

ob_start();
$ズンズンズンズンドコ = new ズンドコキ・ヨ・シ！();
start:
    ((function($zundoko) {
        $zd = (new ReflectionClass(get_class($zundoko)))->getProperties()[mt_rand(0, 1)]->getName();
        $zundoko->$zd;
    })($ズンズンズンズンドコ));
    if (strstr(ob_get_contents(), key(array_reverse(get_defined_vars())))) {
        echo mb_substr(get_class($ズンズンズンズンドコ), -6), PHP_EOL;
        ob_end_flush();
        exit();
    }
goto start;
```

---

# こんなズンドコキヨシは嫌だ
- スクリプトが配置されたディレクトリ名が `./ズン/ドコ/キ・ヨ・シ！/` の時のみ `ズンドコ`
  - `./ｽﾝ/ｽｰﾝ/ｲｪｰｽﾝｽﾝｽﾝ/` なら `ｽﾝｽﾝｽﾝｽｰﾝ`

```php
<?php
$z = basename(dirname($d = dirname($k = dirname(__FILE__))));
$d = basename($d);
$k = basename($k);

$zdk = '';
$zzzd = $z . $z . $z . $z . $d;
foreach((function () use ($z, $d) {
    loop: yield [$z, $d][mt_rand(0, 1)];
    goto loop;
})() as $zd) {
    $zdk .= $zd;
    if (mb_substr($zdk, -mb_strlen($zzzd)) === $zzzd) {
        $zdk .= $k;
        break;
    }
}
echo $zdk, PHP_EOL;
```

---

# こんなピコ太郎も嫌だ
- Iteratorで実装してある

```php
<?php
class PPAP implements Iterator
{
    public $ppap = [
        'ペン',
        'パイナッポー',
        'アッポー',
        'ペーン',
    ];

    public function current()
    {
        shuffle($this->ppap);                                                                                                                                   
        return array_shift($this->ppap); 
    }

    public function key()
    {
    }

    public function next()
    {
    }

    public function rewind()
    {
        $this->ppap = [
            'ペン',
            'パイナッポー',
            'アッポー',
            'ペーン',
        ];
    }

    public function valid()
    {
        return count($this->ppap);
    }
}

$ppap = new PPAP();
loop:
$result = '';
foreach ($ppap as $p) {
    $result .= $p;
}
echo $result, PHP_EOL;
if ($result !== 'ペンパイナッポーアッポーペーン') {
    $ppap->rewind();
    goto loop;
}
echo '＼(^o^)／ﾋﾟｺ!', PHP_EOL;
```

--- 

# こんなピコ太郎も嫌だ
- `require __FILE__` で無限ループを実現している

```php
<?php
$result = '';
foreach ((function () {
    $ppap = [
        'ペン',
        'パイナッポー',
        'アッポー',
        'ペーン',
    ];
    shuffle($ppap);

    foreach ($ppap as $p) {
        yield $p;
    }
})() as $p) {
    $result .= $p;
}

echo $result, PHP_EOL;
if ($result !== 'ペンパイナッポーアッポーペーン') {
    require __FILE__;
} else {
    echo '＼(^o^)／ﾋﾟｺ!', PHP_EOL;
}
```

---

# こんなピコ太郎も嫌だ
- `system(__FILE__)` で無限ループを実現している

```php
#!/usr/local/bin/php
<?php
$result = '';
foreach ((function () {
    $ppap = [
        'ペン',
        'パイナッポー',
        'アッポー',
        'ペーン',
    ];

    $f = function ($ppap) {
        $rand = array_rand($ppap);
        $p = $ppap[$rand];
        unset($ppap[$rand]);
        $ppap = array_values($ppap);
        return [$p, $ppap];
    };

    $count = count($ppap);  
    for ($i = 0;$i < $count;$i++) {
        list($p, $ppap) = $f($ppap);
        yield $p;
    }
})() as $p) {
    $result .= $p;
}

echo $result, PHP_EOL;
if ($result !== 'ペンパイナッポーアッポーペーン') {
    system(__FILE__);
} else {
    echo '＼(^o^)／ﾋﾟｺ!', PHP_EOL;
}
```

---

# こんなFizzBuzzはもっと嫌だ
- 1~100を `__LINE__` で表現

```php
<?php ($f = function($i) {echo $i % 15 !== 0 ? $i % 5 !== 0 ? $i % 3 !== 0 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;})(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
$f(__LINE__);
```

---

# こんなFizzBuzzはもっと嫌だ
- 数字とか甘え

```php
<?php

$fizz = __LINE__;

$buzz = __LINE__;









$fizzBuzz = __LINE__;
($f = function($i) use($fizz, $buzz, $fizzBuzz) {echo !empty($i % $fizzBuzz) ? !empty($i % $buzz) ? !empty($i % $fizz) ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz', PHP_EOL;})(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
$f(__LINE__ - $fizzBuzz);
```

---

# こんなFizzBuzzはもっと嫌だ
- メソッドの呼び出しの改行に意味がある

```php
<?php
fizzBuzz(
    __LINE__,

    __LINE__,









    __LINE__,




















































































    __LINE__
);

function fizzBuzz($f, $b, $fb, $range) {
    foreach (range(strlen(PHP_EOL), $range) as $i) {
        if ($i % $fb === strlen(__CLASS__)) {
            echo 'FizzBuzz', PHP_EOL;
        } elseif ($i % $f === strlen(__CLASS__)) {
            echo 'Fizz', PHP_EOL;
        } elseif ($i % $b === strlen(__CLASS__)) {
            echo 'Buzz', PHP_EOL;
        } else {
            echo $i, PHP_EOL;
        }
    }
}
```

--- 

# こんなGetWild!はほんとやだ
- 無名クラス即時実行の中でnull合体演算子使って引数がnullだったら無名クラス定義をして `private $and` に値を代入しようとした際 `__set` が呼ばれて `Get Wild And` してたら `Tough`
- 解けない愛のパズルができました

```php
<?php
(new class
{
    public function __construct($obj = null)
    {
        $obj = $obj ?? new class
        {
            private $get;
            private $wild;
            private $and;
            private $tough;

            public function __set($k, $v)
            {
                echo ucfirst($v) . PHP_EOL;
                $this->$k = $v;
                if ($k === 'and'
                    && $v === 'and'
                    && $this->get === 'get'
                    && $this->wild === 'wild'
                )
                {
                    echo 'Tough' . PHP_EOL;
                    exit();
                }
            }

            public function getWild()
            {
                return get_object_vars($this);
            }
        };

        $vars = $obj->getWild();
        foreach ($vars as $k => $v) {
            $obj->$k = array_rand($vars);
        }
        self::__construct($obj);
    }
});
```

---

# Special Thanks
- @tadsan
    - [call_user_func 縛りでズンドコ](https://qiita.com/shinderuman@github/items/7c432e8cb7719d35342a#comment-f7e009e47291f62ea3d8)
    - [もっと嫌な FizzBuzz](https://qiita.com/shinderuman@github/items/e2e6f9b10ff33fed56aa#comment-39732714a26556ccd5a2)
- @uzulla 
    - [同僚に殴られる系のズンドコキヨシ\.php](https://qiita.com/uzulla/items/dabe815ff9d793535d86)
- @ProjectICKX 
    - [こんなFizzBuzzも嫌だ](https://qiita.com/ProjectICKX/items/d8b2b478f1b4eed403c4)


---

# Happy Hacking!!  (\\( ⁰⊖⁰)/)