Skip to content

Instantly share code, notes, and snippets.

@gmansilla
Created September 11, 2017 21:09
Show Gist options
  • Select an option

  • Save gmansilla/06d1f9c1b08e8a64ee2ff88b13f56a26 to your computer and use it in GitHub Desktop.

Select an option

Save gmansilla/06d1f9c1b08e8a64ee2ff88b13f56a26 to your computer and use it in GitHub Desktop.
Farm Animals version2
<?php
namespace App;
/**
* Interface iGenericUtilities to be implemented by any Concrete Utility Class
* @package App
*/
interface iGenericUtilities {
public function saveToFile($filename, $data);
public function generateSerialNumbers($start, $end, $limit);
}
/**
* Base Class Animal
* @package App
*/
class Animal
{
protected $serialNumber;
public function getSerialNumber()
{
return $this->serialNumber;
}
public function setSerialNumber($serialNumber)
{
$this->serialNumber = $serialNumber;
}
}
/**
* Class Goat
* @package App
*/
class Goat extends Animal
{
}
/**
* Class Sheep
* @package App
*/
class Sheep extends Animal
{
}
/**
* Class AnimalFactory for creating Animal objects
* @package App
*/
class AnimalFactory
{
/**
* Creates an Animal Object. An exception will be thrown if object cannot be created
* @param $animal
* @return Goat|Sheep
* @throws \Exception
*/
public static function create($animal)
{
switch ($animal) {
case 'goat':
return new Goat();
case 'sheep':
return new Sheep();
default:
throw new \Exception("cant create object of class $animal");
}
}
}
/**
* Class Utilities: generic utilities.
* @package App
*/
class Utilities implements iGenericUtilities
{
/**
* Saves given data in a given file
* @param $filename
* @param $data
*/
public function saveToFile($filename, $data)
{
file_put_contents($filename, $data);
}
/**
* Generates $limit unique prime numbers between $start and $end. The result is returned in an array
* @param $start
* @param $end
* @param $limit
* @return array
*/
public function generateSerialNumbers($start, $end, $limit)
{
$uniqueNumbers = [];
do {
$randomNumber = rand($start, $end); //generate random number
if (!$this->isPrime($randomNumber) || in_array($randomNumber, $uniqueNumbers)) {
//if its not prime number or unique then try again
continue;
}
$uniqueNumbers[] = $randomNumber;
} while (count($uniqueNumbers) < $limit);
return $uniqueNumbers; //return an array of unique prime numbers
}
/**
* Checks if a given number is Even.
* @param $number
* @return bool
*/
public function isEven($number)
{
if ($number % 2 == 0) {
return true;
}
return false;
}
/**
* Checks if a given number is prime
* @param $prime
* @return bool
*/
private function isPrime($prime)
{
for ($i = 2; $i < $prime; $i++) {
if ($prime % $i == 0) {
return false;
}
}
return true;
}
}
class App
{
protected $utilities; //property to be used for dependency injection. It'll hold a object of a Utility class.
protected $animalsIds; //this property is meant to save animals ids, ['goat'] => [1,3,5,7], ['sheep'] => [3,5,7]
/**
* App constructor.
* I'm casting the first argument so that in the future we can inject a new Utility Class and at the same time make
* sure this dependency complies with the contract defined in the iGenericUtilities interface.
*
* @param iGenericUtilities $utilities
*/
public function __construct(iGenericUtilities $utilities)
{
$this->utilities = $utilities; //dependency injection of an Utility class
}
/**
* Main method
* @param array $animals
*/
public function run($animals = [])
{
foreach ($animals as $animal) {
$dataForFile = "";
$uniqueSerialNumbers = $this->utilities->generateSerialNumbers(0, 10000, 100);
foreach ($uniqueSerialNumbers as $uniqueSerialNumber) {
$currentAnimal = AnimalFactory::create($animal); //instantiate animal
$currentAnimal->setSerialNumber($uniqueSerialNumber); //set serial number to animal
$dataForFile .= $uniqueSerialNumber . " \n"; //prepares data to be saved in file
$this->animalsIds[$animal][] = $uniqueSerialNumber; //keeping track of ids used.
}
$this->utilities->saveToFile($animal . '.txt', $dataForFile); //here so we write to disk once per animal
}
$this->findSoulMates();
$this->getFacts();
}
/**
* Find duplicates ids between animals.
*/
private function findSoulMates()
{
$soulMates = call_user_func_array('array_intersect', $this->animalsIds);
$ids = "";
foreach ($soulMates as $soulMate) {
$ids .= $soulMate . " \n";
}
$this->utilities->saveToFile('soulmates.txt', $ids);
}
/**
* Prints facts (count of even/odd numbers and sum) about animals ids
*/
private function getFacts()
{
$facts = [];
foreach ($this->animalsIds as $animal => $ids) {
foreach ($ids as $id) {
$facts[$animal]['sum'] += $id;
$lastDigit = substr($id, -1);
$facts[$animal]['lastDigit'.$lastDigit]++;
}
echo "</br>" . "The sum of $animal ids is " . $facts[$animal]['sum'] . " </br>";
for ($i = 0; $i <=9; $i ++) {
if ($facts[$animal]['lastDigit'.$i]) {
echo "$animal had " . $facts[$animal]['lastDigit'.$i] . " times the number $i as the last digit in their serial numbers </br>";
}
}
}
}
}
try {
$utilities = new Utilities();
$app = new App($utilities);
$app->run(['goat', 'sheep']);
} catch (\Exception $e) {
echo "Exception found " . $e->getMessage();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment