<?php
declare(strict_types=1);
stream_wrapper_register('fizzbuzz', FizzBuzzStreamWrapper::class);
require 'fizzbuzz://22';
final class FizzBuzzStreamWrapper
{
private int $counter = 1;
private int $length = 15;
/** @var resource */
public $context;
public function stream_open(string $path, $mode, $options, &$opened_path): bool
{
preg_match('#([\d]+$)#', $path, $matches);
$this->length = filter_var(
$matches[1] ?? '',
FILTER_VALIDATE_INT,
['options' => ['default' => 15]]
);
return true;
}
public function stream_read($count): string|false
{
if ($this->counter > $this->length) {
return false;
}
$fizzbuzz = match (true) {
$this->counter % 15 === 0 => 'FizzBuzz',
$this->counter % 5 === 0 => 'Buzz',
$this->counter % 3 === 0 => 'Fizz',
default => (string)$this->counter
};
$contents = '';
if ($this->counter === 1) {
$contents = '<?php ' . PHP_EOL;
}
$contents .= "echo '{$fizzbuzz}' . PHP_EOL;";
$this->counter++;
return $contents;
}
public function stream_close(): bool
{
return true;
}
public function stream_eof(): bool
{
return $this->counter ===$this->length;
}
public function stream_stat(): array|false
{
return ['size' => 0];
// return ['size' => $this->getSize()];
}
public function stream_set_option(int $option, int $arg1, int $arg2)
{
return false;
}
private function getSize()
{
$ret = strlen("<?php \n") + $this->length * 18;
$range = range(1, $this->length);
$numbers = array_filter($range, fn ($n) => ($n % 3 !== 0 && $n % 5 !== 0));
$ret += strlen(implode('', $numbers));
$fizzOrBuzzs = array_filter($range, fn ($n) => ($n % 15 !== 0) && ($n % 3 === 0 || $n % 5 === 0));
$ret += strlen('fizz') * count($fizzOrBuzzs);
$fizzbuzzs = array_filter($range, fn ($n) => ($n % 15 === 0));
$ret += strlen('fizzbuzz') * count($fizzbuzzs);
return $ret;
}
}
preferences:
24.73 ms | 409 KiB | 5 Q