Skip to content

Instantly share code, notes, and snippets.

@zanbaldwin
Last active September 13, 2017 09:50
Show Gist options
  • Save zanbaldwin/87a9c39d832b713bdfc31fc61773e72e to your computer and use it in GitHub Desktop.
Save zanbaldwin/87a9c39d832b713bdfc31fc61773e72e to your computer and use it in GitHub Desktop.
Customisable FizzBuzz implementation in PHP.
<?php
$fizzbuzz = new \FizzBuzz\Application;
$fizzbuzz->addDefinition(new \FizzBuzz\Definition('Fizz', 3));
$fizzbuzz->addDefinition(new \FizzBuzz\Definition('Buzz', 5));
$fizzbuzz->run(1, 100);
<?php
namespace FizzBuzz;
class Definition
{
private $name;
private $divisor;
public function __construct(string $name, int $divisor)
{
$this->name = $name;
$this->divisor = $divisor;
}
public function getName(): string
{
return $this->name;
}
public function getDivisor(): int
{
return $this->divisor;
}
}
class Application {
const SEPARATOR = ', ';
private $definitions = [];
public function addDefinition(Definition $definition)
{
$conflicts = array_filter($this->definitions, function (Definition $existing) use ($definition) {
return $existing->getName() === $definition->getName()
|| $existing->getDivisor() === $definition->getDivisor();
});
if (count($conflicts) > 0) {
throw new \RuntimeException('Definition conflict!');
}
$this->definitions[] = $definition;
}
public function run(int $from = 0, int $to = 100)
{
for ($i = $from; $i <= $to; $i++) {
$mask = $this->calculateBitmaskForInteger($i);
echo $mask === 0
? $i
: $this->calculateWords($mask);
echo PHP_EOL;
}
}
private function calculateBitmaskForInteger(int $number): int
{
$bitmask = 0;
foreach (array_values($this->definitions) as $shift => $definition) {
if ($number % $definition->getDivisor() === 0) {
$bitmask = $bitmask | (1 << $shift);
}
}
return $bitmask;
}
private function calculateWords(int $mask): string
{
$words = [];
foreach ($this->definitions as $shift => $definition) {
if ($mask & (1 << $shift)) {
$words[] = $definition->getName();
}
}
return implode(static::SEPARATOR, $words);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment