fork(3) download
  1. <?php
  2. header("Content-Type: text/plain");
  3.  
  4. // ООП. Вектор и антикризичные меры
  5.  
  6. // Класс сотрудника
  7. class Employee
  8. {
  9. private $rank = 1; // ранг
  10. private $chief = 0; // статус руководителя
  11. private $profession; // профессия
  12.  
  13. // Коофициенты зарплаты для ранга
  14. private $rankSalary = array(1 => 1,
  15. 2 => 1.25,
  16. 3 => 1.5);
  17. // Коофициенты зарплаты для начальников
  18. private $chiefSalary = array(0 => 1,
  19. 1 => 1.5);
  20. // Коофициенты потребления кофе для начальников
  21. private $chiefCoffee = array(0 => 1,
  22. 1 => 2);
  23. // Коофициенты продуктивности для начальников
  24. private $chiefProduct = array(0 => 1,
  25. 1 => 0);
  26.  
  27. public function __construct($profession, $rank, $chief)
  28. {
  29. // Присвоение профессии сотруднику
  30. $this->profession = $profession;
  31. // Присвоение ранга сотруднику
  32. $this->rank = $rank;
  33. // Присвоение статуса начальник
  34. $this->chief = $chief;
  35. }
  36.  
  37. // Присвоение профессии сотруднику
  38. public function addProfession(Profession $profession)
  39. {
  40. $this->profession = $profession;
  41. }
  42.  
  43. // Присвоение ранга сотруднику
  44. public function getRank()
  45. {
  46. return $this->rank;
  47. }
  48.  
  49. // Присвоение статуса начальник
  50.  
  51. public function setRank($rank)
  52. {
  53. $this->rank = $rank;
  54. }
  55.  
  56. // Изменение базовой ставки
  57.  
  58. public function setСhief($chief)
  59. {
  60. $this->chief = $chief;
  61. }
  62.  
  63. // Изменение кол-во выпиваемого кофе
  64.  
  65. public function setSalaryRate($salary)
  66. {
  67. $this->profession->setSalaryRate($salary);
  68. }
  69.  
  70. // Возвращаем ранг сотрудника
  71.  
  72. public function setCoffeeRate($coffee)
  73. {
  74. $this->profession->setCoffeeRate($coffee);
  75. }
  76.  
  77. // Возвращаем название профессии сотрудника
  78.  
  79. public function getProfession()
  80. {
  81. return $this->profession;
  82. }
  83.  
  84. // Возвращаем статус шафа сотрудника
  85. public function getChief()
  86. {
  87. return $this->chief;
  88. }
  89.  
  90. // Расчет зарплаты
  91. public function getSalary()
  92. {
  93. // Профессия
  94. $profession = $this->profession;
  95. // Ставка по профессии
  96. $salaryRate = $profession->getSalaryRate();
  97. // Узнаем коэффициент согласно рангу сотрудника
  98. $tmpxRank = $this->rankSalary[$this->rank];
  99. // Узнаем коэффициент для начальника
  100. $tmpchiefSalary = $this->chiefSalary[$this->chief];
  101. // Расчет зарплаты
  102. $salary = $salaryRate * $tmpxRank * $tmpchiefSalary;
  103.  
  104. return $salary;
  105. }
  106.  
  107. // Расчет потребления кофе
  108. public function getCoffee()
  109. {
  110. // Профессия
  111. $profession = $this->profession;
  112. // Потребление кофе по профессии
  113. $coffeeRate = $profession->getCoffeeRate();
  114. // Вычисляем коэффициент для начальника
  115. $tmpchiefCoffee = $this->chiefCoffee[$this->chief];
  116. // Расчет потребления кофе
  117. $coffee = $coffeeRate * $tmpchiefCoffee;
  118.  
  119. return $coffee;
  120. }
  121.  
  122. // Расчет продуктивности
  123. public function getProduct()
  124. {
  125. // Профессия
  126. $profession = $this->profession;
  127. // Продуктивность по профессии
  128. $productRate = $profession->getProduct();
  129. // Вычисляем коэффициент для начальника
  130. $tmpchiefProduct = $this->chiefProduct[$this->chief];
  131. // Расчет продуктивности
  132. $product = $productRate * $tmpchiefProduct;
  133.  
  134. return $product;
  135. }
  136. }
  137.  
  138. // Абстрактный класс профессии
  139. abstract class Profession
  140. {
  141. protected $salaryRate; // базовая ставка
  142. protected $coffeeRate; // кол-во выпиваемого кофе
  143.  
  144. // Изменение базовой ставки
  145.  
  146. public function getSalaryRate()
  147. {
  148. return $this->salaryRate;
  149. }
  150.  
  151. // Изменение кол-во выпиваемого кофе
  152.  
  153. public function setSalaryRate($salary)
  154. {
  155. $this->salaryRate = $salary;
  156. }
  157.  
  158. public function getCoffeeRate()
  159. {
  160. return $this->coffeeRate;
  161. }
  162.  
  163. public function setCoffeeRate($coffee)
  164. {
  165. $this->coffeeRate = $coffee;
  166. }
  167.  
  168. // Возвращает имя
  169.  
  170. public function getName()
  171. {
  172. return get_class($this);
  173. }
  174.  
  175. abstract public function getProduct();
  176. }
  177.  
  178. // Класс менджер
  179. class Manager extends Profession
  180. {
  181. protected $salaryRate = 500; // базовая ставка
  182. protected $coffeeRate = 20; // кол-во выпиваемого кофе
  183.  
  184. public function getProduct()
  185. {
  186. return 200;
  187. }
  188. }
  189.  
  190. // Класс маркетолог
  191. class Marketer extends Profession
  192. {
  193. protected $salaryRate = 400; // базовая ставка
  194. protected $coffeeRate = 15; // кол-во выпиваемого кофе
  195.  
  196. public function getProduct()
  197. {
  198. return 150;
  199. }
  200. }
  201.  
  202. // Класс инженер
  203. class Engineer extends Profession
  204. {
  205. protected $salaryRate = 200; // базовая ставка
  206. protected $coffeeRate = 5; // кол-во выпиваемого кофе
  207.  
  208. public function getProduct()
  209. {
  210. return 50;
  211. }
  212. }
  213.  
  214. // Класс аналитик
  215. class Analyst extends Profession
  216. {
  217. protected $salaryRate = 800; // базовая ставка
  218. protected $coffeeRate = 50; // кол-во выпиваемого кофе
  219.  
  220. public function getProduct()
  221. {
  222. return 5;
  223. }
  224. }
  225.  
  226. // Класс департамента
  227. class Departament
  228. {
  229. public $name = ""; // название
  230. private $employees = array(); // сотрудники
  231.  
  232. public function __construct($name)
  233. {
  234. $this->name = $name;
  235. }
  236.  
  237. // Клонирование департамента
  238. public function __clone()
  239. {
  240. $employeesClones = array(); // клоны работников
  241.  
  242. foreach ($this->employees as $employee) {
  243. $employee = clone $employee;
  244. $departamentsClones[] = $employee;
  245. }
  246. // Заменяем массив работников массивом клонов
  247. $this->employees = $departamentsClones;
  248. }
  249.  
  250. // Прием сотрудника на работу
  251. public function addEmployee(Employee $employee)
  252. {
  253. $this->employees[] = $employee;
  254. }
  255.  
  256. // Расчет количества сотрудников по профессии, не указанный параметр возвращает общее кол-во
  257. public function countEmployees($profession = null)
  258. {
  259. $employeesNumber = 0; // число сотрудников
  260.  
  261. // Если профессия не задана
  262. if (!$profession) {
  263. return count($this->employees);
  264. }
  265.  
  266. // Если считаем сотрудников определенной профессии
  267. foreach ($this->employees as $employee) {
  268.  
  269. // Если сотрудник не соответствует профессии
  270. if ($employee->getProfession()->getName() != $profession) {
  271. continue;
  272. }
  273. // Счетчик
  274. $employeesNumber++;
  275. }
  276. return $employeesNumber;
  277. }
  278.  
  279. // Возвращаем сотрудников массивом
  280. public function getEmployees()
  281. {
  282. return $this->employees;
  283. }
  284. // Поиск сотрудника по профессии, рангу, статусу шефа
  285. // параметр может принимать значение 'all', параметр будет игнорироваться
  286. public function findEmployee($profession, $rank, $chief)
  287. {
  288. $employee = null; // искомый Сотрудник
  289.  
  290. // Перебираем всех сотрудников
  291. foreach ($this->employees as $employee) {
  292.  
  293. // Если сотрудник не соответствует профессии
  294. if ($employee->getProfession()->getName() != $profession &&
  295. $profession != 'all'
  296. ) {
  297. continue;
  298. }
  299. // Если сотрудник не соответствует рангу
  300. if ($employee->getRank() != $rank &&
  301. $rank != 'all'
  302. ) {
  303. continue;
  304. }
  305. // Если сотрудник не является начальником
  306. if ($employee->getChief() != $chief &&
  307. $chief != 'all'
  308. ) {
  309. continue;
  310. }
  311. // Возвращаем Сотрудника
  312. return $employee;
  313. }
  314. }
  315.  
  316. // Возвращает сотрудников заданной профессии массивом
  317. public function findEmployees($profession)
  318. {
  319. $employees = array(); // массив Сотрудников
  320.  
  321. // Перебираем всех сотрудников
  322. foreach ($this->employees as $employee) {
  323. // Если сотрудник соответствует профессии
  324. if ($employee->getProfession()->getName() == $profession) {
  325. $employees[] = $employee;
  326. }
  327. }
  328. // Возвращаем Сотрудников
  329. return $employees;
  330. }
  331.  
  332. // Увольнение сотрудника
  333. public function dismissEmployee($employee)
  334. {
  335. $employeeKey = array_search($employee, $this->employees, TRUE);
  336. unset ($this->employees[$employeeKey]);
  337. }
  338.  
  339. // Расходы на зарплату
  340.  
  341. public function getTotalCoffee()
  342. {
  343. $totalCoffee = 0; // сумарное потребление кофе
  344. // Для каждого сотрудника
  345. foreach ($this->employees as $employee) {
  346. // Запрашиваем потребление кофе у сотрудника и суммируем результат
  347. $totalCoffee += $employee->getCoffee();
  348. }
  349. return $totalCoffee;
  350. }
  351.  
  352. // Рассход кофе
  353.  
  354. public function getAverageCostPerProduct()
  355. {
  356. // Средняя стоимость 1 страницы = суммарная зарплата / сумарное количество страниц
  357. $avrCostPerProduct = $this->getTotalSalary() / $this->getTotalProduct();
  358.  
  359. return $avrCostPerProduct;
  360. }
  361.  
  362. // Суммарная производительность
  363.  
  364. public function getTotalSalary()
  365. {
  366. $totalSalary = 0; // сумарная зарплата
  367. // Для каждого сотрудника
  368. foreach ($this->employees as $employee) {
  369. // Запрашиваем зп у сотрудника и суммируем результат
  370. $totalSalary += $employee->getSalary();
  371. }
  372. return $totalSalary;
  373. }
  374.  
  375. // Средний расход тугриков на одну страницу
  376.  
  377. public function getTotalProduct()
  378. {
  379. $totalProduct = 0; // сумарная продуктивность
  380. // Для каждого сотрудника
  381. foreach ($this->employees as $employee) {
  382. // Запрашиваем продуктивность у сотрудника и суммируем результат
  383. $totalProduct += $employee->getProduct();
  384. }
  385. return $totalProduct;
  386. }
  387. }
  388.  
  389. // Класс компании
  390. class Company
  391. {
  392. public $name = ""; // название
  393. private $departaments = array(); // департаменты
  394.  
  395. public function __construct($name)
  396. {
  397. $this->name = $name;
  398. }
  399.  
  400. // Клонирование компании
  401. public function __clone()
  402. {
  403. $departamentsClones = array(); // клоны департаментов
  404.  
  405. foreach ($this->departaments as $departament) {
  406. $departament = clone $departament;
  407. $departamentsClones[] = $departament;
  408. }
  409. // Заменяем массив департаментов массивом клонов
  410. $this->departaments = $departamentsClones;
  411. }
  412.  
  413. // Создание департамента
  414. public function createDepartament($name)
  415. {
  416. $this->departaments[$name] = new Departament ($name);
  417. }
  418.  
  419. // Поиск департамента по названию,
  420. // если название не определено, возращает все департааменты
  421. public function findDepartamentByName($name = null)
  422. {
  423. $result; // ссылка на департамент или массив департаментов
  424. // Ищем департамент в массиве по названию
  425. if ($name) {
  426. $result = $this->departaments[$name];
  427. } else {
  428. // Возвращаем все департаменты массивом
  429. foreach ($this->departaments as $name => $departament) {
  430. $result[$name] = $departament;
  431. }
  432. }
  433. // Если ничего не нашли
  434. if ($result == null) {
  435. // Ничего не возвращам, выкидываем исключение
  436. throw new Exception ( "Департамент не найден" ) ;
  437. }
  438. return $result;
  439. }
  440.  
  441. // Сумарное количество работников
  442.  
  443. public function getAverageEmployees()
  444. {
  445. // Среднее количество работников = суммарное кол-во работников / кол-во департаментов
  446. $avrEmployees = $this->getTotalEmployees() / count($this->departaments);
  447.  
  448. return $avrEmployees;
  449. }
  450.  
  451. // Расходы на зарплату в сумме
  452.  
  453. public function getTotalEmployees()
  454. {
  455. $totalEmployees = 0;
  456. // Для каждого департамента
  457. foreach ($this->departaments as $departament) {
  458. // Сумируем работников всех департаментов
  459. $totalEmployees += $departament->countEmployees();
  460. }
  461. return $totalEmployees;
  462. }
  463.  
  464. // Рассход кофе в сумме
  465.  
  466. public function getAverageSalary()
  467. {
  468. // Средняя зарплата = суммарная зарплата / кол-во департаментов
  469. $avrSalary = $this->getTotalSalary() / count($this->departaments);
  470.  
  471. return $avrSalary;
  472. }
  473.  
  474. // Суммарная производительность
  475.  
  476. public function getTotalSalary()
  477. {
  478. $salary = 0;
  479. // Для каждого департамента
  480. foreach ($this->departaments as $departament) {
  481. // Сумируем зп всех департаментов
  482. $salary += $departament->getTotalSalary();
  483. }
  484. return $salary;
  485. }
  486.  
  487. // Среднее количество работников по департаментам
  488.  
  489. public function getAverageCoffee()
  490. {
  491. // Среднее потребление кофе = суммарная потребление кофе / кол-во департаментов
  492. $avrCoffee = $this->getTotalCoffee() / count($this->departaments);
  493.  
  494. return $avrCoffee;
  495. }
  496.  
  497. // Средняя зарплата по департаментам
  498.  
  499. public function getTotalCoffee()
  500. {
  501. $coffee = 0;
  502. // Для каждого департамента
  503. foreach ($this->departaments as $departament) {
  504. // Суммируем расход кофе у департаментов
  505. $coffee += $departament->getTotalCoffee();
  506. }
  507. return $coffee;
  508. }
  509.  
  510. // Среднее потребление кофе по департаментам
  511.  
  512. public function getAverageProduct()
  513. {
  514. // Средняя производительность = суммарная производительность / кол-во департаментов
  515. $avrProduct = $this->getTotalProduct() / count($this->departaments);
  516.  
  517. return $avrProduct;
  518. }
  519.  
  520. // Средняя производительность по департаментам
  521.  
  522. public function getTotalProduct()
  523. {
  524. $product = 0;
  525. // Для каждого департамента
  526. foreach ($this->departaments as $departament) {
  527. // Суммируем производительность каждого департамента
  528. $product += $departament->getTotalProduct();;
  529. }
  530. return $product;
  531. }
  532.  
  533. // Средний расход тугриков на одну страницу по департаментам
  534.  
  535. public function getAverageCostPerProduct()
  536. {
  537. $avrCostPerProduct = 0;
  538. // Для каждого департамента
  539. foreach ($this->departaments as $departament) {
  540. // Сумируем средний расход
  541. $avrCostPerProduct += $departament->getAverageCostPerProduct();
  542. }
  543. // Средняя стоимость 1 страницы = cредняя стоимость всех департ / кол-во департаментов
  544. $avrCostPerProduct = $avrCostPerProduct / count($this->departaments);
  545.  
  546. return $avrCostPerProduct;
  547. }
  548. }
  549.  
  550. // Антикризисный коммитет
  551. class AnticrisisCommittee
  552. {
  553. // Сожержит клон компании, к которому применяются АМ
  554. private $companyClone;
  555.  
  556. // Клонирует компанию
  557. public function cloneCompany($company)
  558. {
  559. $this->companyClone = clone $company;
  560. }
  561.  
  562. /*
  563.   * Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров,
  564.   * преимущественно самого низкого ранга. Если инженер является боссом,
  565.   * вместо него надо уволить другого инженера, не босса.
  566.   * */
  567. public function dismissEngineers()
  568. {
  569. // Запрашивавем все департаменты в компании
  570. $departaments = $this->companyClone->findDepartamentByName();
  571.  
  572. // Перебираем все департаменты в компании
  573. foreach ($departaments as $departamentName => $departament) {
  574.  
  575. // Берем всех работников определенной профессии
  576. $engineers = $departament->findEmployees("Engineer");
  577. // Если таковых нет, переходим к следующему департаменту
  578. if (!$engineers) continue;
  579.  
  580. // Исключаем из списка босса
  581. foreach ($engineers as $key => $engineer) {
  582. if ($engineer->getChief() == 1) {
  583. unset($engineers[$key]);
  584. }
  585. }
  586. sort($engineers);
  587.  
  588. // Сортируем массив работников по рангу по возрастанию
  589. // Внешний цикл повторяется до тех пор,
  590. // пока во внутреннем цикле не будет перестановок
  591. $isSort = false; // массив не отсортирован
  592. while (!$isSort) {
  593. $isSort = true; // Считаем, что массив отсортирован, и перестановок не будет
  594. // Перебираем массив старым добрым for
  595. for ($i = 0; $i < (count($engineers) - 1); $i++) {
  596. // Ранги первого и следующего в массиве работника
  597. $rank1 = $engineers[$i]->getRank();
  598. $rank2 = $engineers[$i++]->getRank();
  599. // Сравниваем ранги работников попарно.
  600. // Если ранг первого работника больше ранга следующего работника
  601. // их нужно поменять местами
  602. if ($rank1 > $rank2) {
  603. // Меняем местами работников в массиве
  604. $tmp = $engineers[$i++];
  605. $engineers[$i++] = $engineers[$i];
  606. $engineers[$i] = $tmp;
  607. // Массив не отсортирован, т.к. была перестановка
  608. $isSort = false;
  609. }
  610. }
  611. }
  612.  
  613. // Берем первые 40% через array_slice
  614. $dismissingEngineers = ceil(count($engineers) * 0.4);
  615. $engineers = array_slice($engineers, $dismissingEngineers);
  616.  
  617. // Увольняем сотрудников
  618. foreach ($engineers as $engineer) {
  619. $departament->dismissEmployee($engineer);
  620. }
  621. }
  622. }
  623.  
  624. /*
  625.   * Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков,
  626.   * а количество выпиваемого им кофе с 50 до 75 литров.
  627.   * */
  628. public function increaseSalaryRate()
  629. {
  630. // Запрашивавем все департаменты в компании
  631. $departaments = $this->companyClone->findDepartamentByName();
  632.  
  633. // Перебираем все департаменты в компании
  634. foreach ($departaments as $departamentName => $departament) {
  635.  
  636. // Запрашиваем работников
  637. $analysts = $departament->findEmployees("Analyst");
  638. // Если таковых нет, переходим к следующему департаменту
  639. if (!$analysts) continue;
  640.  
  641. // Перебираем $analysts
  642. foreach ($analysts as $analyst) {
  643.  
  644. // Повышаем ставку
  645. $analyst->setSalaryRate(1100);
  646. // Повышаем количество выпиваемого им кофе
  647. $analyst->setCoffeeRate(75);
  648. }
  649. }
  650. }
  651.  
  652. /*
  653.   * В тех департаментах, где руководитель не является аналитиком,
  654.   * заменить его на аналитика самого высшего ранга из этого департамента
  655.   * (а бывшего руководителя вернуть к обычной работе)
  656.   * */
  657. public function setAnalystAsChief()
  658. {
  659. // Запрашивавем все департаменты в компании
  660. $departaments = $this->companyClone->findDepartamentByName();
  661.  
  662. // Перебираем все департаменты в компании
  663. foreach ($departaments as $departamentName => $departament) {
  664.  
  665. // Находим шефа в компании
  666. $chiefEmployee = $departament->findEmployee("all", "all", 1);
  667. // Узнаем профессию
  668. $professionName = $chiefEmployee->getProfession()->getName();
  669. // Если профессия не Аналитик, начинаем переназначение
  670. if ($professionName != "Analyst") {
  671.  
  672. // Находим аналитика самого высокого ранга
  673. // Повторяем для всех рангов, начиная с самого высокого
  674. for ($rank = 3; $rank > 0; $rank--) {
  675.  
  676. // Запрашиваем Ааналитика из Департамента текущего ранга
  677. // Т.к. мы начинаем с самого высокого ранга, то
  678. // первый Аналитик, которого мы найдем,
  679. // будет иметь самый высокий ранг в департаменте
  680. $analyst = $departament->findEmployee("Analyst", $rank, 0);
  681.  
  682. // Проверяем, вернул ли Департамент Аналитика
  683. if ($analyst != null) {
  684.  
  685. // Назначаем Аналитика шефом
  686. $analyst->setСhief(1);
  687.  
  688. // Снимаем с должности текущего шефа
  689. $chiefEmployee->setСhief(0);
  690. break; // танцуем
  691. }
  692. }
  693. }
  694. }
  695. }
  696.  
  697. /*
  698.   * В каждом департаменте повысить 50% (округляя в большую сторону)
  699.   * менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.
  700.   * */
  701. public function liftManager()
  702. {
  703. // Запрашивавем все департаменты в компании
  704. $departaments = $this->companyClone->findDepartamentByName();
  705.  
  706. // Перебираем все департаменты в компании
  707. foreach ($departaments as $departamentName => $departament) {
  708.  
  709. // Берем всех работников определенной профессии
  710. $employees = $departament->findEmployees("Manager");
  711. // Если таковых нет, переходим к следующему департаменту
  712. if (!$employees) continue;
  713.  
  714. // Исключаем из списка менеджеров вышые 2ого ранга
  715. foreach ($employees as $key => $employee) {
  716. if ($employee->getRank() > 2) {
  717. unset($employees[$key]);
  718. }
  719. }
  720. sort($employees);
  721.  
  722. // Берем 50% через array_slice
  723. $enhancingEmployees = ceil(count($employees) * 0.5);
  724. $employees = array_slice($employees, $enhancingEmployees);
  725.  
  726. // Повышаем сотрудников
  727. foreach ($employees as $employee) {
  728. $currentRank = $employee->getRank();
  729. $employee->setRank($currentRank + 1);
  730. }
  731. }
  732. }
  733.  
  734. // Выводим статистику на печать
  735. public function printStat($message)
  736. {
  737. printStatistics($this->companyClone, $message);
  738. }
  739. }
  740.  
  741. // Функция создания компании
  742. function createCompany($name)
  743. {
  744. // Создаем новый класс компании
  745. $vector = new Company('$name');
  746.  
  747. // Создаем классы департаментов
  748. $vector->createDepartament('Департамент закупок');
  749. $vector->createDepartament('Департамент продаж');
  750. $vector->createDepartament('Департамент рекламы');
  751. $vector->createDepartament('Департамент логистики');
  752.  
  753. // Создаем классы профессий
  754. $me = new Manager();
  755. $ma = new Marketer();
  756. $en = new Engineer();
  757. $an = new Analyst();
  758.  
  759. // Добавляем профессии в масив для последующего создания сотрудников пачкой
  760. $professions['me'] = $me;
  761. $professions['ma'] = $ma;
  762. $professions['en'] = $en;
  763. $professions['an'] = $an;
  764.  
  765. // Лист вакансий: департамент => группы вакансий: профессияРанг статус_начальника => кол-во
  766. $vacancies = array(
  767. 'Департамент закупок' => array('me1' => '9', 'me2' => '3', 'me3' => '2', 'ma1' => '2', 'me2 1' => '1'),
  768. 'Департамент продаж' => array('me1' => '12', 'ma1' => '6', 'an1' => '3', 'an2' => '2', 'ma2 1' => '1'),
  769. 'Департамент рекламы' => array('ma1' => '15', 'ma2' => '10', 'me1' => '8', 'en1' => '2', 'ma3 1' => '1'),
  770. 'Департамент логистики' => array('me1' => '13', 'me2' => '5', 'en1' => '5', 'me1 1' => '1')
  771. );
  772.  
  773. // Для каждого департамента
  774. foreach ($vacancies as $depName => $vacancyGroup) {
  775.  
  776. // Для каждой группы вакансий
  777. foreach ($vacancyGroup as $vacancyName => $vacancyQuantity) {
  778.  
  779. // Достаем название профессии из вакансии
  780. $professionIndex = mb_substr($vacancyName, 0, 2);
  781. $profession = $professions[$professionIndex];
  782. // Достаем ранг и из вакансии
  783. preg_match ('/\d/', $vacancyName, $matches1);
  784. $rank = $matches1[0];
  785. // Достаем статус начальника из вакансии
  786. if(preg_match ('/ \d/', $vacancyName, $matches2)) {
  787. $chief = trim($matches2[0]);
  788. } else {
  789. $chief = 0;
  790. }
  791.  
  792. // Создаем столько сотрудников, сколько вакансий в группе
  793. for ($id = 1; $id <= $vacancyQuantity; $id++) {
  794. // Создаем сотрудника
  795. $employee = new Employee($profession, $rank, $chief);
  796.  
  797. // Запрашиваем в Компании нужный департамент
  798. $departament = $vector->findDepartamentByName($depName);
  799. // Добавляем сотрудника в этот Департамент
  800. $departament->addEmployee($employee);
  801. }
  802. }
  803. }
  804. // Возвращаем объект Компания
  805. return $vector;
  806. }
  807.  
  808. // Класс строки таблицы, хранит не фарматированную строку
  809. class TableRow
  810. {
  811. private $columns = array(); // строка это массив из колонок
  812.  
  813. // Конструктор принимает массив колонок
  814. public function __construct($columns)
  815. {
  816. $this->columns = $columns;
  817. }
  818.  
  819. // Метод возвращает содержимое строки (все ее колоночки)
  820. public function getColumns()
  821. {
  822. return $this->columns;
  823. }
  824. }
  825.  
  826. // Класс таблицы
  827. class Table
  828. {
  829. private $tableRows = array(); // массив объектов Строк
  830. private $length = 15; // ширина колонок
  831.  
  832. // Добавление строки в таблицу, принимает массив
  833. public function addRow($row)
  834. {
  835. // Создаем новую строку
  836. $this->tableRows[] = new TableRow($row);
  837. }
  838.  
  839. // Печать таблицы
  840. public function printTable()
  841. {
  842. $caption = 1; // первая строка - заголовок таблицы
  843.  
  844. // Перебираем массив объектов Строк
  845. foreach ($this->tableRows as $row) {
  846.  
  847. $stringRow = ""; // строка для печати
  848. $columnNumber = 0; // счетчик колонок
  849.  
  850. // Извлекаем колонки из строки
  851. $columns = $row->getColumns();
  852.  
  853. // Форматируем каждую колонку в строке
  854. foreach ($columns as $column) {
  855.  
  856. // Округляем числа до 2х знаков после запятой
  857. if (is_float($column)) {
  858. $column = round($column, 2);
  859. }
  860. // Добавляем отступы справа для первой колонки
  861. if ($columnNumber == 0) {
  862. $stringRow .= "\n" . $this->padRight($column, $this->length);
  863. // Добавляем оступы слева для остальных колонок
  864. } else {
  865. $stringRow .= $this->padLeft($column, $this->length);
  866. }
  867. $columnNumber++;
  868. }
  869. // Добавляем черту после заголовка
  870. if ($caption == 1) {
  871. $stringRow .= "\n" . $this->formatCaption($columnNumber, $this->length);
  872. }
  873. // Выводим строку на печать
  874. echo "{$stringRow}";
  875.  
  876. $caption--; // останется только один заголовок
  877. }
  878. }
  879.  
  880. // Добавление пробелов слева
  881. private function padRight($string, $length)
  882. {
  883. // Разница между переданной строкой и шириной колонки
  884. $lenghtDifference = $length - mb_strlen($string);
  885. // Проверка на отрицательное значение при вычитании
  886. if ($lenghtDifference >= 0) {
  887. // Заполняем разницу пробелами
  888. $string .= str_repeat(" ", $lenghtDifference);
  889. } else {
  890. // Если таки отрицательное, обрезаем край строки до ширины колонки
  891. $string = mb_substr($string, 0, $length);
  892. }
  893. return $string;
  894. }
  895.  
  896. // Добавление пробелов справа
  897. private function padLeft($string, $length)
  898. {
  899. // Разница между переданной строкой и шириной колонки
  900. $lenghtDifference = $length - mb_strlen($string);
  901. // Проверка на отрицательное значение при вычитании
  902. if ($lenghtDifference >= 0) {
  903. // Заполняем разницу пробелами
  904. $string = str_repeat(" ", $lenghtDifference) . $string;
  905. } else {
  906. // Если таки отрицательное, обрезаем край строки до ширины колонки
  907. $string = mb_substr($string, 0, $length);
  908. }
  909. return $string;
  910. }
  911.  
  912. // Делаем горизонтальную черту
  913. private function formatCaption($columnNumber, $length)
  914. {
  915. $string = str_repeat("-", $length * $columnNumber);
  916. return $string;
  917. }
  918. }
  919.  
  920. /* Вывод таблицы результатов */
  921.  
  922. // Функция вывода статистики по компании
  923. function printStatistics($company, $caption)
  924. {
  925.  
  926. // Создаем таблицу
  927. $table = new Table();
  928.  
  929. // Заголовок таблицы
  930. $table->addRow(array("Департамент",
  931. "сотр.",
  932. "тугр.",
  933. "кофе",
  934. "стр.",
  935. "тугр./стр.."));
  936.  
  937. // Статистика по департаентам
  938. $departaments = $company->findDepartamentByName();
  939. // Каждый департамент строка
  940. foreach ($departaments as $departament) {
  941. unset($columns); // обнуляем массив
  942. // Заполняем массив строк
  943. $columns[] = mb_convert_case(mb_substr($departament->name, 12), MB_CASE_TITLE, "UTF-8");
  944. $columns[] = $departament->countEmployees();
  945. $columns[] = $departament->getTotalSalary();
  946. $columns[] = $departament->getTotalCoffee();
  947. $columns[] = $departament->getTotalProduct();
  948. $columns[] = $departament->getAverageCostPerProduct();
  949. // Добавляем строку в таблицу
  950. $table->addRow($columns);
  951. }
  952.  
  953. // Пустая строка
  954. unset($columns); // обнуляем массив
  955. $columns[] = ' ';
  956. // Добавляем строку в таблицу
  957. $table->addRow($columns);
  958.  
  959. // Среднее для всей компании
  960. unset($columns); // обнуляем массив
  961. // Заполняем массив строк
  962. $columns[] = 'Среднее';
  963. $columns[] = $company->getAverageEmployees();
  964. $columns[] = $company->getAverageSalary();
  965. $columns[] = $company->getAverageCoffee();
  966. $columns[] = $company->getAverageProduct();
  967. $columns[] = $company->getAverageCostPerProduct();
  968. // Добавляем строку в таблицу
  969. $table->addRow($columns);
  970.  
  971. // Всего для всей компании
  972. unset($columns); // обнуляем массив
  973. // Заполняем массив строк
  974. $columns[] = 'Всего';
  975. $columns[] = $company->getTotalEmployees();
  976. $columns[] = $company->getTotalSalary();
  977. $columns[] = $company->getTotalCoffee();
  978. $columns[] = $company->getTotalProduct();
  979. // Добавляdем строку в таблицу
  980. $table->addRow($columns);
  981.  
  982. // Выводим на печать заголовок
  983. echo "{$caption}\n";
  984.  
  985. // Выводим таблицу на печать
  986. $table->printTable();
  987. echo "\n\n";
  988. }
  989.  
  990. // Регистрируем Vector Inc на Сейшельских островах
  991. $vector = createCompany('Vector');
  992. printStatistics($vector, "Докризисная статистика");
  993. // Создаем антикризисный коммитет
  994. $anticrisisCommittee = new AnticrisisCommittee();
  995. // Первый набор Антикризисных мер
  996. $anticrisisCommittee->cloneCompany($vector);
  997. $anticrisisCommittee->dismissEngineers();
  998. $anticrisisCommittee->printStat("Антикризисные меры 1");
  999. // Второй набор Антикризисных мер
  1000. $anticrisisCommittee->cloneCompany($vector);
  1001. $anticrisisCommittee->increaseSalaryRate();
  1002. $anticrisisCommittee->setAnalystAsChief();
  1003. $anticrisisCommittee->printStat("Антикризисные меры 2");
  1004. // Третий набор Антикризисных мер
  1005. $anticrisisCommittee->cloneCompany($vector);
  1006. $anticrisisCommittee->liftManager();
  1007. $anticrisisCommittee->printStat("Антикризисные меры 3");
  1008. ?>
Success #stdin #stdout 0.03s 52472KB
stdin
Standard input is empty
stdout
Докризисная статистика

Департамент              сотр.          тугр.           кофе           стр.    тугр./стр..
------------------------------------------------------------------------------------------
Закупок                     17         9612.5            350           3100            3.1
Продаж                      24          13550            610           3325           4.08
Рекламы                     36          16300            575           5450           2.99
Логистики                   24          11375            425           3850           2.95
               
Среднее                  25.25       12709.38            490        3931.25           3.28
Всего                      101        50837.5           1960          15725

Антикризисные меры 1

Департамент              сотр.          тугр.           кофе           стр.    тугр./стр..
------------------------------------------------------------------------------------------
Закупок                     17         9612.5            350           3100            3.1
Продаж                      24          13550            610           3325           4.08
Рекламы                     35          16100            570           5400           2.98
Логистики                   21          10775            410           3700           2.91
               
Среднее                  24.25       12509.38            485        3881.25           3.27
Всего                       97        50037.5           1940          15525

Антикризисные меры 2

Департамент              сотр.          тугр.           кофе           стр.    тугр./стр..
------------------------------------------------------------------------------------------
Закупок                     17         9612.5            350           3100            3.1
Продаж                      24        15637.5            795           3470           4.51
Рекламы                     36          16300            575           5450           2.99
Логистики                   24          11375            425           3850           2.95
               
Среднее                  25.25       13231.25         536.25         3967.5           3.39
Всего                      101          52925           2145          15870

Антикризисные меры 3

Департамент              сотр.          тугр.           кофе           стр.    тугр./стр..
------------------------------------------------------------------------------------------
Закупок                     17          10425            350           3100           3.36
Продаж                      24          15950            735           3325            4.8
Рекламы                     36          16800            575           5450           3.08
Логистики                   24        12562.5            425           3850           3.26
               
Среднее                  25.25       13934.38         521.25        3931.25           3.63
Всего                      101        55737.5           2085          15725