fork(1) download
  1. <?php
  2.  
  3. abstract class Worker
  4. {
  5. protected $salary;
  6. protected $coffee;
  7. protected $pages;
  8. protected $rank;
  9. protected $isBoss = FALSE;
  10.  
  11. public function setSalary($x) { $this->salary = $x; }
  12. public function setCoffee($x) { $this->coffee = $x; }
  13. public function setIsBoss($x) { $this->isBoss = $x; }
  14. public function setRank($x) { $this->rank = $x; }
  15.  
  16. public function getRank() { return $this->rank; }
  17. public function getIsBoss() { return $this->isBoss; }
  18.  
  19. public function __construct($rank)
  20. {
  21. $this->rank = $rank;
  22. }
  23.  
  24. //использую статичесую функцию со new static для создания экземпляров класса.
  25. //иными словами, буду вызывать эту функцию через подклассы и создавать объекты
  26. public static function create($rank, $bodyCount)
  27. {
  28. $arrayOfMen = [];
  29. for($i = 1; $i <= $bodyCount; $i++){
  30. $newMan = new static($rank);
  31. $arrayOfMen[] = $newMan;
  32. }
  33. return $arrayOfMen;
  34. }
  35.  
  36. //функция, которая будет давать статистику по персонажу
  37. public function getStatistic()
  38. {
  39. $rankCoefficient = 0; // коэффициент для умножения результатов по рангам
  40. switch ($this->rank):
  41. case 1:
  42. $rankCoefficient = 1;
  43. break;
  44. case 2:
  45. $rankCoefficient = 1.25;
  46. break;
  47. case 3:
  48. $rankCoefficient = 1.5;
  49. break;
  50. endswitch;
  51.  
  52. $bossCoefficient = 0; //коэффициент для босса
  53. switch ($this->isBoss):
  54. case FALSE:
  55. $bossCoefficient = 1;
  56. break;
  57. case TRUE:
  58. $bossCoefficient = 2;
  59. break;
  60. endswitch;
  61.  
  62. $statistic = [
  63. "salary" => $this->salary * $rankCoefficient * $bossCoefficient,
  64. "coffee" => $this->coffee * $bossCoefficient,
  65. "pages" => $this->pages,
  66. ];
  67.  
  68. //проверяю, босс ли, чтобы стереть его страницы
  69. if ($this->isBoss) {
  70. $statistic["pages"] = 0;
  71. }
  72. return $statistic;
  73. }
  74.  
  75. public static function makeHimBoss(array $arrayOfMen)
  76. {
  77. $futureBoss = $arrayOfMen[0];
  78. $futureBoss->isBoss = TRUE;
  79. }
  80. }
  81.  
  82. class Marketing extends Worker
  83. {
  84. protected $salary = 400;
  85. protected $coffee = 15;
  86. protected $pages = 150;
  87. }
  88. class Management extends Worker
  89. {
  90. public $salary = 500;
  91. public $coffee = 20;
  92. public $pages = 200;
  93. }
  94.  
  95. class Engineer extends Worker
  96. {
  97. protected $salary = 200;
  98. protected $coffee = 5;
  99. protected $pages = 50;
  100. }
  101.  
  102. class Analysis extends Worker
  103. {
  104. protected $salary = 800;
  105. protected $coffee = 50;
  106. protected $pages = 5;
  107. }
  108.  
  109. class Department
  110. {
  111. //в этом массиве хранятся все сотрудники
  112. public $staff = [];
  113.  
  114. //тут добавляю сотрудников в этот массив
  115. public function addNewStaffMember(array $men)
  116. {
  117. $this->staff = array_merge($this->staff, $men);
  118. }
  119. public function __clone()
  120. {
  121. foreach ($this->staff as & $man) {
  122. $man = clone $man;
  123. }
  124. }
  125.  
  126. //увольняю(для антикризисных мер)
  127. public function fireStaffMember(Worker $fired)
  128. {
  129. foreach($this->staff as $id => $man){
  130. //тут долго думал, в итоге использую "===" для проверки того, идентичные ли объекты. Правильно всё?
  131. if($man === $fired) { unset($this->staff[$id]); }
  132. }
  133. }
  134.  
  135. //через эту функцию вывожу статистику по департаменту
  136. public function getStatisticOfDepartment()
  137. {
  138. $totalSalary = $totalCoffee = $totalPages = $totalBodies = 0;
  139. foreach($this->staff as $man){
  140. $totalSalary += $man->getStatistic()["salary"];
  141. $totalCoffee += $man->getStatistic()["coffee"];
  142. $totalPages += $man->getStatistic()["pages"];
  143. $totalBodies++;
  144. }
  145. $resultStats =
  146. [
  147. "bodies" => $totalBodies,
  148. "salary" => $totalSalary,
  149. "coffee" => $totalCoffee,
  150. "pages" => $totalPages,
  151. ];
  152. //возвращаю массив со статистикой
  153. return $resultStats;
  154. }
  155. }
  156. ///// для таблицы ----------------------------------------------------------------------
  157. //функция аналог str_pad, только для кириллицы (взял с инета, т.к. стандартная str_pad не работает с кириллицей)
  158. function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT)
  159. {
  160. $padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
  161. $padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
  162. $pad_len -= mb_strlen($str);
  163. $targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
  164. $strToRepeatLen = mb_strlen($pad_str);
  165. $repeatTimes = ceil($targetLen / $strToRepeatLen);
  166. $repeatedString = str_repeat($pad_str, max(0, $repeatTimes));
  167. $before = $padBefore ? mb_substr($repeatedString, 0, floor($targetLen)) : '';
  168. $after = $padAfter ? mb_substr($repeatedString, 0, ceil($targetLen)) : '';
  169. return $before . $str . $after;
  170. }
  171.  
  172. //пишу функцию для вставки пробелов справа
  173. function padRight($string, $length)
  174. {
  175. $spaces = $length - mb_strlen($string);
  176. if($spaces>0) { $string=mb_str_pad($string, mb_strlen($string) + $spaces, " ", STR_PAD_RIGHT); }
  177. return $string;
  178. }
  179.  
  180. //пишу функцию для вставки пробелов слева
  181. function padLeft($string, $length)
  182. {
  183. $spaces = $length - mb_strlen($string);
  184. if($spaces>0) { $string=mb_str_pad($string, mb_strlen($string) + $spaces, " ", STR_PAD_LEFT); }
  185. return $string;
  186. }
  187. ///// для таблицы ---------------------------------------------------------------------- КОНЕЦ
  188.  
  189. //Заполняем департменты рабочими
  190. $BuyingDep = new Department();
  191. $men = Management::create(1, 9);
  192. $BuyingDep->addNewStaffMember($men);
  193. $men = Management::create(2, 3);
  194. $BuyingDep->addNewStaffMember($men);
  195. $men = Management::create(3, 2);
  196. $BuyingDep->addNewStaffMember($men);
  197. $men = Marketing::create(1, 2);
  198. $BuyingDep->addNewStaffMember($men);
  199. $men = Management::create(2, 1);
  200. Worker::makeHimBoss($men);
  201. $BuyingDep->addNewStaffMember($men);
  202.  
  203. $SellingDep = new Department();
  204. $men = Management::create(1, 12);
  205. $SellingDep->addNewStaffMember($men);
  206. $men = Marketing::create(1, 6);
  207. $SellingDep->addNewStaffMember($men);
  208. $men = Analysis::create(1, 3);
  209. $SellingDep->addNewStaffMember($men);
  210. $men = Analysis::create(2, 2);
  211. $SellingDep->addNewStaffMember($men);
  212. $men = Marketing::create(2, 1);
  213. Worker::makeHimBoss($men);
  214. $SellingDep->addNewStaffMember($men);
  215.  
  216. $AdsDep = new Department();
  217. $men = Marketing::create(1, 15);
  218. $AdsDep->addNewStaffMember($men);
  219. $men = Marketing::create(2, 10);
  220. $AdsDep->addNewStaffMember($men);
  221. $men = Management::create(1, 8);
  222. $AdsDep->addNewStaffMember($men);
  223. $men = Engineer::create(1, 2);
  224. $AdsDep->addNewStaffMember($men);
  225. $men = Marketing::create(3, 1);
  226. Worker::makeHimBoss($men);
  227. $AdsDep->addNewStaffMember($men);
  228.  
  229. $LogisticsDep = new Department();
  230. $men = Management::create(1, 13);
  231. $LogisticsDep->addNewStaffMember($men);
  232. $men = Management::create(2, 5);
  233. $LogisticsDep->addNewStaffMember($men);
  234. $men = Engineer::create(1, 5);
  235. $LogisticsDep->addNewStaffMember($men);
  236. $men = Management::create(1, 1);
  237. Worker::makeHimBoss($men);
  238. $LogisticsDep->addNewStaffMember($men);
  239.  
  240. //функция вывода Таблицы
  241. function showTable($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep)
  242. {
  243. //два типа колонок
  244. $col1 = 25;
  245. $col2 = 15;
  246.  
  247. //верхняя строка таблицы
  248. echo padRight("Департамент", $col1) .
  249. padLeft("сотр.", $col2) .
  250. padLeft("тугр.", $col2) .
  251. padLeft("кофе", $col2) .
  252. padLeft("стр.", $col2) .
  253. padLeft("тугр./стр.", $col2) .
  254. "\n";
  255.  
  256. echo str_repeat("-", 100) . "\n";
  257.  
  258. $totalBodies = $totalSalary = $totalCoffee = $totalPages = $totalBalance = 0;
  259. //делаю массив массивов статистики по всем департаментам
  260. $statistics = [
  261. "Закупок" => $BuyingDep->getStatisticOfDepartment(),
  262. "Продаж" => $SellingDep->getStatisticOfDepartment(),
  263. "Рекламы" => $AdsDep->getStatisticOfDepartment(),
  264. "Логистики" => $LogisticsDep->getStatisticOfDepartment(),
  265. ];
  266.  
  267. //прохожусь по массиву массивов
  268. foreach ($statistics as $department => $datum) {
  269. $balance = round($datum["salary"] / $datum["pages"], 2);
  270. echo padRight("$department", $col1) .
  271. padLeft($datum["bodies"], $col2) .
  272. padLeft($datum["salary"], $col2) .
  273. padLeft($datum["coffee"], $col2) .
  274. padLeft($datum["pages"], $col2) .
  275. padLeft($balance, $col2) .
  276. "\n";
  277. $totalBodies += $datum["bodies"];
  278. $totalSalary += $datum["salary"];
  279. $totalCoffee += $datum["coffee"];
  280. $totalPages += $datum["pages"];
  281. $totalBalance += $balance;
  282. }
  283.  
  284. echo "\n";
  285.  
  286. //колонка СРЕДНЕЕ
  287. echo padRight("Среднее", $col1) .
  288. padLeft($totalBodies / 4, $col2) .
  289. padLeft($totalSalary / 4, $col2) .
  290. padLeft($totalCoffee / 4, $col2) .
  291. padLeft($totalPages / 4, $col2) .
  292. padLeft($totalBalance / 4, $col2) .
  293. "\n";
  294.  
  295. //колонка ВСЕГО
  296. echo padRight("Всего", $col1) .
  297. padLeft($totalBodies, $col2) .
  298. padLeft($totalSalary, $col2) .
  299. padLeft($totalCoffee, $col2) .
  300. padLeft($totalPages, $col2) .
  301. padLeft($totalBalance, $col2) .
  302. "\n";
  303. }
  304.  
  305. showTable($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep);
  306. echo "\n\n\n\n\n";
  307. //антикризисные меры, надо раскоментировать необходимую строчку
  308. executeAction1($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep);
  309. executeAction2($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep);
  310. executeAction3($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep);
  311.  
  312.  
  313. //
  314. // АНТИКРИЗИСНЫЕ МЕРЫ ---------------------
  315. //--------------------------------------------------
  316. //
  317. //1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров,
  318. // преимущественно самого низкого ранга.
  319. // Если инженер является боссом, вместо него надо уволить другого инженера, не босса.
  320. function executeAction1($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep)
  321. {
  322. $BuyingClone = clone $BuyingDep;
  323. $SellingClone = clone $SellingDep;
  324. $AdsClone =clone $AdsDep;
  325. $LogisticClone = clone $LogisticsDep;
  326. $allDepartments = [$BuyingClone, $SellingClone, $AdsClone, $LogisticClone];
  327.  
  328. foreach ($allDepartments as $department) {
  329. $allEngineers = 0;
  330. $listOfRank1 = [];
  331. $listOfRank2 = [];
  332. $listOfRank3 = [];
  333. $wasThereAnEngineerBoss = 0;
  334. //прохожусь по департаментам и распределяю инженеров
  335. foreach ($department->staff as $man) {
  336. if ($man instanceof Engineer AND $man->getIsBoss() == FALSE) {
  337. $allEngineers++;
  338. if ($man->getRank() == 1) {
  339. $listOfRank1[] = $man;
  340. } elseif ($man->getRank() == 2) {
  341. $listOfRank2[] = $man;
  342. } elseif ($man->getRank() == 3) {
  343. $listOfRank3[] = $man;
  344. }
  345. } elseif ($man instanceof Engineer AND $man->getIsBoss() == TRUE) {
  346. $wasThereAnEngineerBoss = 1;
  347. }
  348. $allEngineers += $wasThereAnEngineerBoss;
  349.  
  350. $engineersToFire = ceil($allEngineers * 0.4);
  351. $firedCount = 0;
  352. }
  353.  
  354. //соединяю в один массив, от меньших рангов к большим.
  355. $listByRank = array_merge($listOfRank1, $listOfRank2, $listOfRank3);
  356.  
  357. if (!empty($listByRank)) {
  358. foreach ($department->staff as $id => $man) {
  359. foreach ($listByRank as $fired) {
  360. if ($man === $fired) {
  361. unset($department->staff[$id]);
  362. $firedCount++;
  363. }
  364. }
  365. if ($firedCount == $engineersToFire) break;
  366. }
  367. }
  368. }
  369. echo "Solution #1. This is what would happen if we dismissed 40% of our Engineers\n\n";
  370. showTable($BuyingClone, $SellingClone, $AdsClone, $LogisticClone);
  371. echo "\n\n\n\n\n";
  372. }
  373.  
  374.  
  375. //2. 2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков,
  376. // а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель
  377. // не является аналитиком, заменить его на аналитика самого
  378. // высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)
  379. function executeAction2($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep)
  380. {
  381. $BuyingClone = clone $BuyingDep;
  382. $SellingClone = clone $SellingDep;
  383. $AdsClone = clone $AdsDep;
  384. $LogisticClone = clone $LogisticsDep;
  385. $allDepartments = [$BuyingClone, $SellingClone, $AdsClone, $LogisticClone];
  386. //прохожусь по департаментам
  387. foreach($allDepartments as $department) {
  388. $wasThereNotAnalysisBoss = FALSE; //использую эту переменную для того, чтоб унзать, был ли босс Аналитиком
  389. //прохожусь по сотрудникам департаментов
  390. foreach ($department->staff as $man) {
  391. $highestRank = 1;
  392. $highestRankedAnalysisMan = NULL; //эта переменная служит для выявления наиболее ранкнутого аналитика
  393. if ($man instanceof Analysis) {
  394. $man->setSalary(1100);
  395. $man->setCoffee(75);
  396. if ($man->getRank() >= $highestRank) {
  397. $highestRank = $man->getRank();
  398. $highestRankedAnalysisMan = $man;
  399. }
  400. //проверяю, есть ли босс не аналитик, если да, разжалую его
  401. } elseif($man->getIsBoss() == TRUE){
  402. $wasThereNotAnalysisBoss = TRUE;
  403. $exBoss = $man;
  404. }
  405. }
  406. //наиболее ранкнутого инженера повышаю, если $wasThereNotAnalysisBoss показало, что был босс-не-аналитик
  407. if($wasThereNotAnalysisBoss == TRUE AND $highestRankedAnalysisMan != NULL) {
  408. $highestRankedAnalysisMan->setIsBoss(TRUE);
  409. $exBoss->setIsBoss(FALSE);
  410. }
  411. }
  412. echo "Solution #2. This is what would happen if we raised the salary rate of the Analytics.\n\n";
  413. showTable($BuyingClone, $SellingClone, $AdsClone, $LogisticClone);
  414. echo "\n\n\n\n\n";
  415. }
  416.  
  417.  
  418.  
  419. //3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров
  420. // 1-го и 2-го ранга на один ранг с целью расширить их полномочия.
  421. function executeAction3($BuyingDep, $SellingDep, $AdsDep, $LogisticsDep)
  422. {
  423. $BuyingClone = clone $BuyingDep;
  424. $SellingClone = clone $SellingDep;
  425. $AdsClone =clone $AdsDep;
  426. $LogisticClone = clone $LogisticsDep;
  427. $allDepartments = [$BuyingClone, $SellingClone, $AdsClone, $LogisticClone];
  428. $allManagersOfRank1 = [];
  429. $allManagersOfRank2 = [];
  430. foreach($allDepartments as $department){
  431. foreach($department->staff as $man){
  432. if($man instanceof Management){
  433. if($man->getRank() == 1) {
  434. $allManagersOfRank1[] = $man;
  435. } elseif($man->getRank() == 2){
  436. $allManagersOfRank2[] = $man;
  437. }
  438. }
  439. }
  440. $toGetPromotedOfRank1 = ceil((count($allManagersOfRank1)+1)*0.5);
  441. $toGetPromotedOfRank2 = ceil((count($allManagersOfRank2)+1)*0.5);
  442. $alreadyPromotedOfRank1 = 0;
  443. $alreadyPromotedOfRank2 = 0;
  444. foreach($allManagersOfRank1 as $man){
  445. $man->setRank(2);
  446. $alreadyPromotedOfRank1++;
  447. if($toGetPromotedOfRank1 == $alreadyPromotedOfRank1) break;
  448. }
  449. foreach($allManagersOfRank2 as $man){
  450. $man->setRank(3);
  451. $alreadyPromotedOfRank2++;
  452. if($toGetPromotedOfRank2 == $alreadyPromotedOfRank2) break;
  453. }
  454. }
  455.  
  456. echo "Solution #3. This is what would happen if we promoted half of our Managers.\n\n";
  457. showTable($BuyingClone, $SellingClone, $AdsClone, $LogisticClone);
  458. echo "\n\n\n\n\n";
  459. }
  460.  
Success #stdin #stdout 0.03s 52472KB
stdin
Standard input is empty
stdout
Департамент                        сотр.          тугр.           кофе           стр.     тугр./стр.
----------------------------------------------------------------------------------------------------
Закупок                               17           9925            350           3100            3.2
Продаж                                24          13800            610           3325           4.15
Рекламы                               36          16600            575           5450           3.05
Логистики                             24          11625            425           3850           3.02

Среднее                            25.25        12987.5            490        3931.25          3.355
Всего                                101          51950           1960          15725          13.42





Solution #1. This is what would happen if we dismissed 40% of our Engineers

Департамент                        сотр.          тугр.           кофе           стр.     тугр./стр.
----------------------------------------------------------------------------------------------------
Закупок                               17           9925            350           3100            3.2
Продаж                                24          13800            610           3325           4.15
Рекламы                               35          16400            570           5400           3.04
Логистики                             22          11225            415           3750           2.99

Среднее                             24.5        12837.5         486.25        3893.75          3.345
Всего                                 98          51350           1945          15575          13.38





Solution #2. This is what would happen if we raised the salary rate of the Analytics.

Департамент                        сотр.          тугр.           кофе           стр.     тугр./стр.
----------------------------------------------------------------------------------------------------
Закупок                               17           9925            350           3100            3.2
Продаж                                24          15450            735           3325           4.65
Рекламы                               36          16600            575           5450           3.05
Логистики                             24          11625            425           3850           3.02

Среднее                            25.25          13400         521.25        3931.25           3.48
Всего                                101          53600           2085          15725          13.92





Solution #3. This is what would happen if we promoted half of our Managers.

Департамент                        сотр.          тугр.           кофе           стр.     тугр./стр.
----------------------------------------------------------------------------------------------------
Закупок                               17          11675            350           3100           3.77
Продаж                                24          15300            610           3325            4.6
Рекламы                               36          16725            575           5450           3.07
Логистики                             24          11750            425           3850           3.05

Среднее                            25.25        13862.5            490        3931.25         3.6225
Всего                                101          55450           1960          15725          14.49