fork download
  1. <?php
  2.  
  3. ini_set('display_errors', 'on');
  4.  
  5. class Employee
  6. {
  7. const FIRST_RANK = 1.0;
  8. const SECOND_RANK = 1.25;
  9. const THIRD_RANK = 1.5;
  10. const BOSS_PREMIUM = 1.5;
  11. const BOSS_COFFEE_PREMIUM = 2.0;
  12. const BOSS_PAGES_MULTIPLIER = 0;
  13.  
  14. public $isBoss;
  15. public $rank;
  16. public $profession;
  17.  
  18. private static $dependencies = array(
  19. 'manager'=>array('coffee'=>20, 'pages'=>200, 'wageRate'=>500),
  20. 'marketer'=>array('coffee'=>15, 'pages'=>150, 'wageRate'=>400),
  21. 'engineer'=>array('coffee'=>5, 'pages'=>50, 'wageRate'=>200),
  22. 'analyst'=>array('coffee'=>50, 'pages'=>5, 'wageRate'=>800),
  23. );
  24.  
  25. public function getDependencies()
  26. {
  27. return self::$dependencies;
  28. }
  29.  
  30. public static function updateDependencies(array $dependencies)
  31. {
  32. self::$dependencies = array_merge(self::$dependencies, $dependencies);
  33. }
  34.  
  35. private function getProfDependencies()
  36. {
  37. $allDependencies = $this->getDependencies();
  38. return $allDependencies[$this->profession];
  39. }
  40.  
  41.  
  42. public function getCoffeeConsuming()
  43. {
  44. $profDependencies = $this->getProfDependencies($this->profession);
  45. return ($this->isBoss) ? self::BOSS_COFFEE_PREMIUM * $profDependencies['coffee']
  46. : $profDependencies['coffee'];
  47. }
  48.  
  49. public function getSalary()
  50. {
  51. $profDependencies = $this->getProfDependencies($this->profession);
  52. return ($this->isBoss) ? self::BOSS_PREMIUM * $profDependencies['wageRate'] * $this->rank
  53. : $profDependencies['wageRate'] * $this->rank;
  54. }
  55.  
  56. public function getPages()
  57. {
  58. $profDependencies = $this->getProfDependencies($this->profession);
  59. return ($this->isBoss) ? self::BOSS_PAGES_MULTIPLIER * $profDependencies['pages']
  60. : $profDependencies['pages'];
  61. }
  62.  
  63. public function __construct($profession, $rank = 1, $isBoss = false)
  64. {
  65. $this->profession = $profession;
  66. $this->rank = $rank;
  67. $this->isBoss = $isBoss;
  68. }
  69. }
  70.  
  71. class Report
  72. {
  73. public $departmentName;
  74. public $salary;
  75. public $coffee;
  76. public $pages;
  77. public $employeeCount;
  78. }
  79.  
  80. class Department
  81. {
  82. public $name;
  83. public $employees = array();
  84.  
  85. public function __construct($name)
  86. {
  87. $this->name = $name;
  88. }
  89.  
  90. public function getReport()
  91. {
  92. $report = new Report;
  93. foreach ($this->employees as $employee) {
  94. $report->salary += $employee->getSalary();
  95. $report->coffee += $employee->getCoffeeConsuming();
  96. $report->pages += $employee->getPages();
  97. }
  98. $report->departmentName = $this->name;
  99. $report->employeeCount = count($this->employees);
  100. return $report;
  101. }
  102.  
  103. public function hireEmployee(Employee $employee)
  104. {
  105. $this->employees[] = $employee;
  106. }
  107.  
  108. public function fireEmployee(Employee $e)
  109. {
  110. foreach ($this->employees as $employee) {
  111. if ($employee != $e) continue;
  112. $index = array_search($employee, $this->employees);
  113. unset($this->employees[$index]);
  114. break;
  115. }
  116. }
  117.  
  118. public function fireMassive($profession, $amount)
  119. {
  120. $tolalCount = 0;
  121. foreach ($this->employees as $employee) {
  122. if ($employee->profession == $profession) $tolalCount += 1;
  123. }
  124. $toFire = intval(ceil($tolalCount * $amount));
  125. $fired = 0;
  126. foreach ($this->employees as $employee) {
  127. if ($employee->profession != $profession or $employee->isBoss) continue;
  128. if ($fired == $toFire) break;
  129. $this->fireEmployee($employee);
  130. $fired++;
  131. }
  132. }
  133. }
  134.  
  135. function hireCrowd(Department $dep, $number, $profession, $rank = 1, $isBoss = false) {
  136. for ($i = 0; $i < $number; $i++) {
  137. $employee = new Employee($profession, $rank, $isBoss);
  138. $dep->hireEmployee($employee);
  139. }
  140. }
  141.  
  142. class Company
  143. {
  144. private $departments = array();
  145. public function getDepartments()
  146. {
  147. return $this->departments;
  148. }
  149.  
  150. public $name;
  151.  
  152. public function __construct($name)
  153. {
  154. $this->name = $name;
  155. }
  156.  
  157. public function getReport()
  158. {
  159. $report = array();
  160. foreach ($this->departments as $department) {
  161. $report[] = $department->getReport();
  162. }
  163. return $report;
  164. }
  165.  
  166. public function addDepartment(Department $department)
  167. {
  168. $this->departments[] = $department;
  169. }
  170.  
  171. public function dismissDepartment(Department $dep)
  172. {
  173. foreach ($this->departments as $department) {
  174. if ($department != $dep) continue;
  175. unset($department);
  176. break;
  177. }
  178. }
  179. }
  180.  
  181. $procurement = new Department('Отдел закупок');
  182. hireCrowd($procurement, 9, 'manager');
  183. hireCrowd($procurement, 3, 'manager', Employee::SECOND_RANK);
  184. hireCrowd($procurement, 2, 'manager', Employee::THIRD_RANK);
  185. hireCrowd($procurement, 2, 'marketer');
  186. hireCrowd($procurement, 1, 'manager', Employee::SECOND_RANK, true);
  187.  
  188. $selling = new Department('Отдел продаж');
  189. hireCrowd($selling, 12, 'manager');
  190. hireCrowd($selling, 6, 'marketer');
  191. hireCrowd($selling, 3, 'analyst');
  192. hireCrowd($selling, 2, 'analyst', Employee::SECOND_RANK);
  193. hireCrowd($selling, 1, 'marketer', Employee::SECOND_RANK, true);
  194.  
  195. $advertisement = new Department('Отдел рекламы');
  196. hireCrowd($advertisement, 15, 'marketer');
  197. hireCrowd($advertisement, 10, 'marketer', Employee::SECOND_RANK);
  198. hireCrowd($advertisement, 8, 'manager');
  199. hireCrowd($advertisement, 2, 'engineer');
  200. hireCrowd($advertisement, 1, 'marketer', Employee::THIRD_RANK, true);
  201.  
  202. $logistics = new Department('Отдел логистики');
  203. hireCrowd($logistics, 13, 'manager');
  204. hireCrowd($logistics, 5, 'manager', Employee::SECOND_RANK);
  205. hireCrowd($logistics, 5, 'engineer');
  206. hireCrowd($logistics, 1, 'manager', Employee::FIRST_RANK, true);
  207.  
  208. $vector = new Company('Вектор');
  209. $vector->addDepartment($procurement);
  210. $vector->addDepartment($selling);
  211. $vector->addDepartment($advertisement);
  212. $vector->addDepartment($logistics);
  213.  
  214. // Начальные условия
  215. ViewHelper::printReport($vector);
  216.  
  217. // 1. Антикризисные меры: увольняю 40% инженеров во всех отделах
  218. /*foreach ($vector->getDepartments() as $department) {
  219.   $department->fireMassive('engineer', 0.4);
  220. }
  221. ViewHelper::printReport($vector);*/
  222. // 2. Антикризисные меры: меняю расходы на аналитиков, делаю аналитиков начальниками
  223. // в тех департаментах, где они есть, иначе не меняю босса
  224. Employee::updateDependencies(array('analyst'=>array('wageRate'=>1100,'coffee'=>75,'pages'=>5)));
  225. foreach ($vector->getDepartments() as $department) {
  226. foreach ($department->employees as $employee) {
  227. if ($employee->isBoss) {
  228. $oldBoss = $employee;
  229. break;
  230. }
  231. }
  232. if ($oldBoss->profession == 'analyst') continue;
  233. $pretendent = null;
  234. foreach ($department->employees as $employee) {
  235. if ($employee->profession != 'analyst') continue;
  236. if (!$pretendent or $pretendent->rank < $employee->rank) {
  237. $pretendent = $employee;
  238. }
  239. }
  240. if ($pretendent) {
  241. $oldBossIndex = array_search($oldBoss, $department->employees);
  242. $department->employees[$oldBossIndex]->isBoss = false;
  243. $pretendentIndex = array_search($pretendent, $department->employees);
  244. $department->employees[$pretendentIndex]->isBoss = true;
  245. }
  246. }
  247. ViewHelper::printReport($vector);
  248.  
  249. class ViewHelper
  250. {
  251. public static function printReport(Company $company)
  252. {
  253. echo self::padRight('Департамент');
  254. echo self::padLeft('сотр.');
  255. echo self::padLeft('тугр.');
  256. echo self::padLeft('кофе');
  257. echo self::padLeft('стр.');
  258. echo self::padLeft('тугр./стр.'), "\n";
  259. for ($i=0; $i < 95; $i++) echo '-';
  260. echo "\n";
  261. $reports = $company->getReport();
  262. foreach ($reports as $report) {
  263. echo self::padRight($report->departmentName);
  264. echo self::padLeft($report->employeeCount);
  265. echo self::padLeft($report->salary);
  266. echo self::padLeft($report->coffee);
  267. echo self::padLeft($report->pages);
  268. echo self::padLeft(round($report->salary / $report->pages, 1));
  269. echo "\n";
  270. }
  271. echo self::padRight('Среднее');
  272. echo self::padLeft(self::average($reports, 'employeeCount'));
  273. echo self::padLeft(self::average($reports, 'salary'));
  274. echo self::padLeft(self::average($reports, 'coffee'));
  275. echo self::padLeft(self::average($reports, 'pages'));
  276. echo "\n";
  277. echo self::padRight('Всего');
  278. echo self::padLeft(self::summary($reports, 'employeeCount'));
  279. echo self::padLeft(self::summary($reports, 'salary'));
  280. echo self::padLeft(self::summary($reports, 'coffee'));
  281. echo self::padLeft(self::summary($reports, 'pages'));
  282. echo "\n";
  283. }
  284.  
  285. private static function summary($reports, $propertyName)
  286. {
  287. if (!is_array($reports) || count($reports) == 0) return 0;
  288. for ($i=0, $sum=0; $i < count($reports); $i++) {
  289. $sum += $reports[$i]->$propertyName;
  290. }
  291. return $sum;
  292. }
  293.  
  294. private static function average($reports, $propertyName)
  295. {
  296. $sum = self::summary($reports, $propertyName);
  297. return round($sum / count($reports), 1);
  298. }
  299.  
  300. private static function padRight($string, $columnSize=20) {
  301. $paddingSize = $columnSize - mb_strlen($string);
  302. $string .= str_repeat(' ', $paddingSize);
  303. return $string;
  304. }
  305.  
  306. private static function padLeft($string, $columnSize=15) {
  307. $paddingSize = $columnSize - mb_strlen($string);
  308. $string = str_repeat(' ', $paddingSize) . $string;
  309. return $string;
  310. }
  311. }
Success #stdin #stdout 0.02s 52432KB
stdin
Standard input is empty
stdout
Департамент                   сотр.          тугр.           кофе           стр.     тугр./стр.
-----------------------------------------------------------------------------------------------
Отдел закупок                    17         9612.5            350           3100            3.1
Отдел продаж                     24          13550            610           3325            4.1
Отдел рекламы                    36          16300            575           5450              3
Отдел логистики                  24          11375            425           3850              3
Среднее                        25.3        12709.4            490         3931.3
Всего                           101        50837.5           1960          15725
Департамент                   сотр.          тугр.           кофе           стр.     тугр./стр.
-----------------------------------------------------------------------------------------------
Отдел закупок                    17         9612.5            350           3100            3.1
Отдел продаж                     24        15637.5            795           3470            4.5
Отдел рекламы                    36          16300            575           5450              3
Отдел логистики                  24          11375            425           3850              3
Среднее                        25.3        13231.3          536.3         3967.5
Всего                           101          52925           2145          15870