fork(1) download
  1. <?php
  2.  
  3.  
  4.  
  5.  
  6. class PrettyPrinter
  7. {
  8. private $head = [
  9. "col0" => "№",
  10. "col1" => "департамент",
  11. "col2" => "Σрабов",
  12. "col3" => "Σтугриков",
  13. "col4" => "Σкофе",
  14. "col5" => "Σстраниц",
  15. "col6" => "тугриков/страниц"
  16. ];
  17. private $foot = [
  18. "col0" => " ",
  19. "col1" => "Итого",
  20. "col2" => NULL,
  21. "col3" => NULL,
  22. "col4" => NULL,
  23. "col5" => NULL,
  24. "col6" => NULL
  25. ];
  26. private $trail = [];
  27. private $padder;
  28.  
  29. private $prettyData = [];
  30. private $printableResult;
  31.  
  32. public function __construct(array $departments)
  33. {
  34. $this->setPadder();
  35. $this->setHeadTrials();
  36. $inputArr= [];
  37. foreach($departments as $department) {
  38. $input["col1"] = $department->getDepName();
  39. $input["col2"] = $department->getEmployeesNum();
  40. $input["col3"] = $department->getTotalSalary();
  41. $input["col4"] = $department->getTotalCoffee();
  42. $input["col5"] = $department->getTotalPages();
  43. $input["col6"] = number_format($department->getSalaryPagesRatio(), 3);
  44.  
  45. array_push($inputArr, $input);
  46. }
  47. $enum = range(1, count($inputArr));
  48. for($i = 0; $i < count($inputArr); $i++) {
  49. $inputArr[$i] = array_merge(["№" => $enum[$i]], $inputArr[$i]);
  50. $this->fillPrettyData($inputArr[$i]);
  51. }
  52.  
  53. $this->setPrintableHeader();
  54. $this->initFooter($inputArr);
  55. $this->setPrintableFoot();
  56. foreach($this->prettyData as $row) {
  57. $this->setPrintableResult($row);
  58. }
  59. }
  60.  
  61. private function setPrintableHeader()
  62. {
  63. foreach(array_values($this->head) as $header) {
  64. $this->printableResult .= (string)($header);
  65. $this->printableResult .= " ";
  66. }
  67. $this->printableResult .= ("\n" . str_repeat("-", $this->padder) . "\n");
  68. }
  69.  
  70. private function setHeadTrials()
  71. {
  72. foreach($this->head as $col=>$str) {
  73. $this->trail[$col] = mb_strlen($str);
  74. }
  75. }
  76.  
  77. private function setPadder()
  78. {
  79. $func = function($value) {
  80. return mb_strlen((string)$value);
  81. };
  82. $this->padder = array_sum(array_map($func, array_values($this->head))) +
  83. count(array_values($this->head)) - 1;
  84. }
  85.  
  86. private function fillPrettyData(array $arr)
  87. {
  88. $func = function($value) {
  89. return mb_strlen((string)$value);
  90. };
  91. $dataLens = [];
  92. $temp = array_combine(array_values($this->trail),
  93. array_map($func, array_values($arr)));
  94.  
  95. foreach($temp as $len1=>$len2) {
  96. $len = abs($len1 - $len2);
  97. $data = str_repeat(" ", $len);
  98. array_push($dataLens, $data);
  99. }
  100. $prettyChunk = array_combine(array_values($arr),
  101. $dataLens);
  102.  
  103. array_push($this->prettyData, $prettyChunk);
  104. }
  105.  
  106. private function setPrintableResult(array $arr)
  107. {
  108. foreach($arr as $data=>$padding) {
  109. $res = (string)$data . (string)$padding;
  110. $this->printableResult .= $res;
  111. $this->printableResult .= " ";
  112. }
  113. $this->printableResult .= ("\n" . str_repeat("-", $this->padder) . "\n");
  114. }
  115.  
  116. public function __toString()
  117. {
  118. return $this->printableResult;
  119. }
  120.  
  121. private function initFooter(array $arr)
  122. {
  123. $allWorkers = 0;
  124. $allCoffee = 0;
  125. $allSalary = 0;
  126. $allPages = 0;
  127. $allAvg = [];
  128.  
  129. foreach($arr as $subarr) {
  130. $cur_vals = array_values($subarr);
  131. $allWorkers += $cur_vals[2];
  132. $allSalary += $cur_vals[3];
  133. $allCoffee += $cur_vals[4];
  134. $allPages += $cur_vals[5];
  135. array_push($allAvg, $cur_vals[6]);
  136. }
  137.  
  138. $this->foot["col2"] = $allWorkers;
  139. $this->foot["col3"] = $allSalary;
  140. $this->foot["col4"] = $allCoffee;
  141. $this->foot["col5"] = $allPages;
  142. $this->foot["col6"] = array_sum($allAvg) / count($allAvg);
  143. }
  144.  
  145. private function setPrintableFoot()
  146. {
  147. $this->fillPrettyData($this->foot);
  148. }
  149. }
  150.  
  151.  
  152. abstract class Employee
  153. {
  154. private $salary;
  155. private $rank;
  156. private $coffeeAmt;
  157. private $pages;
  158. private $isBoss;
  159.  
  160. public function __construct($salary, $rank, $coffeeAmt, $pages, $boss=false)
  161. {
  162. $this->salary = $salary;
  163. $this->rank = $rank;
  164. $this->coffeeAmt = $coffeeAmt;
  165. $this->pages = $pages;
  166. $this->isBoss = $boss;
  167. }
  168.  
  169. public function getSalary()
  170. {
  171. if ($this->rank === 1) {
  172. $salary = $this->salary;
  173. } elseif($this->rank === 2) {
  174. $salary = $this->salary * 1.25;
  175. } elseif($this->rank === 3) {
  176. $salary = $this->salary * 1.5;
  177. }
  178.  
  179. if($this->isBoss) {
  180. $salary += $salary * 0.5;
  181. }
  182.  
  183. return $salary;
  184. }
  185.  
  186. public function getCoffee()
  187. {
  188. if($this->isBoss) {
  189. return $this->coffeeAmt * 2;
  190. }
  191. return $this->coffeeAmt;
  192. }
  193.  
  194. public function getPages()
  195. {
  196. if($this->isBoss) {
  197. return 0;
  198. }
  199. return $this->pages;
  200. }
  201.  
  202. public function isBoss()
  203. {
  204. return $this->isBoss;
  205. }
  206.  
  207. public function getRank()
  208. {
  209. return $this->rank;
  210. }
  211.  
  212. public function setRank($rank)
  213. {
  214. $this->rank = $rank;
  215. }
  216.  
  217. public function setSalary($salary)
  218. {
  219. $this->salary = $salary;
  220. }
  221.  
  222. public function setCoffee($amt)
  223. {
  224. $this->coffeeAmt = $amt;
  225. }
  226.  
  227. public function setPages($amt)
  228. {
  229. $this->pages = $amt;
  230. }
  231.  
  232. public function setBossStatus($status)
  233. {
  234. $this->isBoss = $status;
  235. }
  236. }
  237.  
  238.  
  239. class Manager extends Employee
  240. {
  241. }
  242.  
  243.  
  244. class Analyst extends Employee
  245. {
  246. }
  247.  
  248.  
  249. class Engineer extends Employee
  250. {
  251. }
  252.  
  253.  
  254. class Marketer extends Employee
  255. {
  256. }
  257.  
  258.  
  259. class Department
  260. {
  261. private $totalSalary;
  262. private $totalCoffeeAmount;
  263. private $totalWorkDone;
  264. private $employees = [];
  265. private $depName;
  266.  
  267. public function __construct($depName)
  268. {
  269. $this->depName = $depName;
  270. }
  271.  
  272. public function addEmployee(Employee $emp)
  273. {
  274. array_push($this->employees, $emp);
  275. }
  276.  
  277. public function fireEmployee(Employee $emp)
  278. {
  279. if(in_array($emp, $this->employees)) {
  280. $key = array_search($emp, $this->employees);
  281. unset($this->employees[$key]);
  282. }
  283. }
  284.  
  285. public function getTotalSalary()
  286. {
  287. $this->totalSalary = 0;
  288. foreach($this->employees as $employee) {
  289. $this->totalSalary += $employee->getSalary();
  290. }
  291. return $this->totalSalary;
  292. }
  293.  
  294. public function getTotalPages()
  295. {
  296. $this->totalWorkDone = 0;
  297. foreach($this->employees as $employee) {
  298. $this->totalWorkDone += $employee->getPages();
  299. }
  300. return $this->totalWorkDone;
  301. }
  302.  
  303. public function getTotalCoffee()
  304. {
  305. $this->totalCoffeeAmount = 0;
  306. foreach($this->employees as $employee) {
  307. $this->totalCoffeeAmount += $employee->getCoffee();
  308. }
  309. return $this->totalCoffeeAmount;
  310. }
  311.  
  312. public function getEmployeesNum()
  313. {
  314. return count($this->employees);
  315. }
  316.  
  317. public function getSalaryPagesRatio()
  318. {
  319. if($this->totalWorkDone !== 0) {
  320. return $this->totalSalary / $this->totalWorkDone;
  321. }
  322. exit("Division by zero");
  323. }
  324.  
  325. public function getDepName()
  326. {
  327. return $this->depName;
  328. }
  329.  
  330. public function getEmployees()
  331. {
  332. return $this->employees;
  333. }
  334.  
  335. public function __clone()
  336. {
  337. $clonedEmps = [];
  338. foreach($this->employees as $emp) {
  339. $clonedEmps[] = clone $emp;
  340. }
  341. $this->employees = $clonedEmps;
  342. $this->totalSalary = 0;
  343. $this->totalCoffeeAmount = 0;
  344. $this->totalWorkDone = 0;
  345. }
  346. }
  347.  
  348.  
  349. function createEmployee(Department $dep, $cls, $rank, $amt, $boss=false)
  350. {
  351. $empSalarys = ["Manager" => 500, "Marketer" => 400, "Analyst" => 800, "Engineer" => 200];
  352. $empCoffee = ["Manager" => 20, "Marketer" => 15, "Analyst" => 50, "Engineer" => 5];
  353. $empPages = ["Manager" => 200, "Marketer" => 150, "Analyst" => 5, "Engineer" => 50];
  354.  
  355. for($i = 0; $i < $amt; $i++) {
  356. $emp = new $cls($empSalarys[$cls], $rank, $empCoffee[$cls], $empPages[$cls], $boss);
  357. $dep->addEmployee($emp);
  358. }
  359. }
  360.  
  361.  
  362. function cmpRanks(Employee $emp1, Employee $emp2)
  363. {
  364. if($emp1->getRank() === $emp2->getRank()) {
  365. return 0;
  366. }
  367. return ($emp1->getRank() < $emp2->getRank()) ? -1 : 1;
  368. }
  369.  
  370. function tryModel1(Department $dep)
  371. {
  372. $engineers = [];
  373. foreach($dep->getEmployees() as $emp) {
  374. if(get_class($emp) === "Engineer" && $emp->isBoss() !== true) {
  375. $engineers[] = $emp;
  376. }
  377. }
  378. usort($engineers, "cmpRanks");
  379. $fireAmt = round(count($engineers) * 0.4);
  380. $firedEngineers = array_slice($engineers, 0, $fireAmt);
  381. foreach($firedEngineers as $engineer) {
  382. $dep->fireEmployee($engineer);
  383. }
  384. }
  385.  
  386. function tryModel2(Department $dep)
  387. {
  388. $analysts = [];
  389. foreach($dep->getEmployees() as $emp) {
  390. if(get_class($emp) === "Analyst") {
  391. $emp->setSalary(1100);
  392. $emp->setCoffee(75);
  393. $analysts[] = $emp;
  394. }
  395. }
  396. if($analysts) {
  397. usort($analysts, "cmpRanks");
  398. foreach($dep->getEmployees() as $emp) {
  399. if($emp->isBoss() && get_class($emp) !== "Analyst") {
  400. $emp->setBossStatus(false);
  401. $newBoss = max($analysts);
  402. $newBoss->setBossStatus(true);
  403. }
  404. }
  405. }
  406. }
  407.  
  408. function tryModel3(Department $dep)
  409. {
  410. $firstRankMan = [];
  411. $secondRankMan = [];
  412. foreach($dep->getEmployees() as $emp) {
  413. if(get_class($emp) === "Manager" && $emp->getRank() === 1 && $emp->isBoss() === false) {
  414. $firstRankMan[] = $emp;
  415. } elseif(get_class($emp) === "Manager" && $emp->getRank() === 2 && $emp->isBoss() === false) {
  416. $secondRankMan[] = $emp;
  417. }
  418. }
  419. $firstRankLim = array_slice($firstRankMan, 0, round(count($firstRankMan) * 0.5));
  420. $secondRankLim = array_slice($secondRankMan, 0, round(count($secondRankMan) * 0.5));
  421. foreach($firstRankLim as $manager) {
  422. $manager->setRank(2);
  423. }
  424. foreach($secondRankLim as $manager) {
  425. $manager->setRank(3);
  426. }
  427. }
  428.  
  429.  
  430. $purchaseDep = new Department("закупок");
  431. createEmployee($purchaseDep, "Manager", 1, 9);
  432. createEmployee($purchaseDep, "Manager", 2, 3);
  433. createEmployee($purchaseDep, "Manager", 3, 2);
  434. createEmployee($purchaseDep, "Marketer", 1, 2);
  435. createEmployee($purchaseDep, "Manager", 2, 1, $boss=true);
  436.  
  437. $salesDep = new Department("продаж");
  438. createEmployee($salesDep, "Manager", 1, 12);
  439. createEmployee($salesDep, "Marketer", 1, 6);
  440. createEmployee($salesDep, "Analyst", 1, 3);
  441. createEmployee($salesDep, "Analyst", 2, 2);
  442. createEmployee($salesDep, "Marketer", 2, 1, $boss=true);
  443.  
  444. $adsDep = new Department("рекламы");
  445. createEmployee($adsDep, "Marketer", 1, 15);
  446. createEmployee($adsDep, "Marketer", 2, 10);
  447. createEmployee($adsDep, "Manager", 1, 8);
  448. createEmployee($adsDep, "Engineer", 1, 2);
  449. createEmployee($adsDep, "Marketer", 3, 1, $boss=true);
  450.  
  451. $logisticsDep = new Department("логистики");
  452. createEmployee($logisticsDep, "Manager", 1, 13);
  453. createEmployee($logisticsDep, "Manager", 2, 5);
  454. createEmployee($logisticsDep, "Engineer", 1, 5);
  455. createEmployee($logisticsDep, "Manager", 1, 1, $boss=true);
  456.  
  457. $allDeps = [$purchaseDep, $salesDep, $adsDep, $logisticsDep];
  458. $clonedDeps1 = [];
  459. $clonedDeps2 = [];
  460. $clonedDeps3 = [];
  461.  
  462. foreach($allDeps as $department) {
  463. $clonedDeps1[] = clone $department;
  464. $clonedDeps2[] = clone $department;
  465. $clonedDeps3[] = clone $department;
  466. }
  467.  
  468. function tryCrisisModel(array $clonedDeps, callable $modelFunc, $description)
  469. {
  470. array_walk($clonedDeps, $modelFunc);
  471. $result = new PrettyPrinter($clonedDeps);
  472. echo "\n\n";
  473. echo "Применение атнкризисной модели: {$description}\n\n";
  474. echo $result;
  475. }
  476.  
  477. $baseData = new PrettyPrinter($allDeps);
  478. echo "Начальные данные.\n\n";
  479. echo $baseData;
  480.  
  481. tryCrisisModel($clonedDeps1, "tryModel1", "увольнение 40% инженеров");
  482. tryCrisisModel($clonedDeps2, "tryModel2", "повышение условий труда аналитиков");
  483. tryCrisisModel($clonedDeps3, "tryModel3", "повышение 1 и 2 рангов у 50% менеджеров");
  484.  
  485. ?>
Success #stdin #stdout 0.02s 24728KB
stdin
Standard input is empty
stdout
Начальные данные.

№ департамент Σрабов Σтугриков Σкофе Σстраниц тугриков/страниц 
--------------------------------------------------------------
1 закупок     17     9612.5    350   3100     3.101            
--------------------------------------------------------------
2 продаж      24     13550     610   3325     4.075            
--------------------------------------------------------------
3 рекламы     36     16300     575   5450     2.991            
--------------------------------------------------------------
4 логистики   24     11375     425   3850     2.955            
--------------------------------------------------------------
  Итого       101    50837.5   1960  15725    3.2805           
--------------------------------------------------------------


Применение атнкризисной модели: увольнение 40% инженеров

№ департамент Σрабов Σтугриков Σкофе Σстраниц тугриков/страниц 
--------------------------------------------------------------
1 закупок     17     9612.5    350   3100     3.101            
--------------------------------------------------------------
2 продаж      24     13550     610   3325     4.075            
--------------------------------------------------------------
3 рекламы     35     16100     570   5400     2.981            
--------------------------------------------------------------
4 логистики   22     10975     415   3750     2.927            
--------------------------------------------------------------
  Итого       98     50237.5   1945  15575    3.271            
--------------------------------------------------------------


Применение атнкризисной модели: повышение условий труда аналитиков

№ департамент Σрабов Σтугриков Σкофе Σстраниц тугриков/страниц 
--------------------------------------------------------------
1 закупок     17     9612.5    350   3100     3.101            
--------------------------------------------------------------
2 продаж      24     15637.5   795   3470     4.506            
--------------------------------------------------------------
3 рекламы     36     16300     575   5450     2.991            
--------------------------------------------------------------
4 логистики   24     11375     425   3850     2.955            
--------------------------------------------------------------
  Итого       101    52925     2145  15870    3.38825          
--------------------------------------------------------------


Применение атнкризисной модели: повышение 1 и 2 рангов у 50% менеджеров

№ департамент Σрабов Σтугриков Σкофе Σстраниц тугриков/страниц 
--------------------------------------------------------------
1 закупок     17     10487.5   350   3100     3.383            
--------------------------------------------------------------
2 продаж      24     14300     610   3325     4.301            
--------------------------------------------------------------
3 рекламы     36     16800     575   5450     3.083            
--------------------------------------------------------------
4 логистики   24     12625     425   3850     3.279            
--------------------------------------------------------------
  Итого       101    54212.5   1960  15725    3.5115           
--------------------------------------------------------------