LoginSignup
14
12

More than 1 year has passed since last update.

時代はPHP8だしFizzBuzz書いた

Posted at

眠れない夜ってFizzBuzzを書きたくなりますよね。いままでさんざんFizzBuzzを書いてきましたが僕はまだ書き足りないです。

今回はきしださんが今年の1月に書いたらしいFizzBuzzをさっき知って「うむ、これこそ2021年のFizzBuzzだ」と思ったので、臆面もなくぱくることにいたししました。

今回のFizzBuzzのコンセプトは以下の通りです。

  • 元コードの魂を受け継ぎ、オブジェクト指向は時代に合ってないのでnewを使わない
  • 元コードの魂は受け継がず、シンプルではなく凝ったことをしており、エレガントではない
  • 元コードの魂は受け継がず、動く

また、判定方法は概ねきしださんのコードから拝借していますがループ方法は異っています。

PHPコード

このコードに実用的な要素はありません

<?php

class FizzBuzz
{
    public static function __callStatic(string $n, array $args): void
    {
        echo match ($n % 3) {
            0 => match ($n % 5) {
                0 => self::fizz_buzz($n),
                default => self::fizz($n),
            },
            default => match ($n % 5) {
                0 => self::buzz($n),
                default => ($p = strval($n - 1) and self::{$p}()) ?: $n,
            },
        }, PHP_EOL;
    }

    public static function fizz(int $n): string
    {
        // fizzの直後にfizzが来ることはない
        if ($n % 5 == 0) {
            return self::buzz($n - 1);
        }

        $_ = fn($n): string => $n;
        self::{$_($n-1)}();

        return ucfirst(__FUNCTION__);
    }

    public static function buzz(int $n): string
    {
        // buzzの直後にbuzzが来ることはない
        if ($n % 3 == 0) {
            echo self::fizz($p), PHP_EOL;
        }

        $_ = fn($n): string => $n;
        self::{$_($n-1)}();

        return ucfirst(__FUNCTION__);
    }

    public static function fizz_buzz(int $n): string
    {
        $_ = fn($n): string => $n;

        // fizzbuzzの直後はnのみ
        self::{$_($n-1)}();

        return implode(array_map('ucfirst', explode('_', __FUNCTION__)));
    }
}

FizzBuzz::{'100'}();

解説

  • PHPは数字名のメソッド定義はできませんが、数字名のメソッド呼び出しは可能です
  • __callStatic()メソッドのオーバーロードと呼ばれるマジックメソッドです
  • 再帰を停止させるために、ぱっと見でわかりにくい書き方をしてます
  • ちなみにPHPにTCO(末尾呼び出し最適化)はありません

私からは以上です。この下は旧作FizzBuzzへのリンクです。

いままでのFizzBuzz

かなりまじめなFizzBuzz

PHP7時代のFizzBuzz

まじめじゃないFizzBuzz

とにかくFizzBuzz

14
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12