My attempts at exercism.org
1<?php
2
3declare(strict_types=1);
4
5class Tournament
6{
7 private const HEADER = "Team | MP | W | D | L | P";
8
9 public function tally(string $input): string
10 {
11 if ($input === "") {
12 return self::HEADER;
13 }
14
15 $teams = [];
16
17 foreach ($this->parseInput($input) as [$team1, $team2, $result]) {
18 $this->initTeam($teams, $team1);
19 $this->initTeam($teams, $team2);
20
21 $this->updateMatchesPlayed($teams, $team1, $team2);
22 $this->updateMatchResult($teams, $team1, $team2, $result);
23 }
24
25 $this->sortTeams($teams);
26
27 return $this->generateTable($teams);
28 }
29
30 private function parseInput(string $input): array
31 {
32 $rows = explode("\n", $input);
33 $matches = [];
34
35 foreach ($rows as $row) {
36 if ($row === "") {
37 continue;
38 }
39
40 $matches[] = explode(";", $row);
41 }
42
43 return $matches;
44 }
45
46 private function initTeam(array &$teams, string $team): void
47 {
48 if (!isset($teams[$team])) {
49 $teams[$team] = [
50 "MP" => 0,
51 "W" => 0,
52 "D" => 0,
53 "L" => 0,
54 "P" => 0,
55 ];
56 }
57 }
58
59 private function updateMatchesPlayed(
60 array &$teams,
61 string $team1,
62 string $team2,
63 ): void {
64 $teams[$team1]["MP"]++;
65 $teams[$team2]["MP"]++;
66 }
67
68 private function updateMatchResult(
69 array &$teams,
70 string $team1,
71 string $team2,
72 string $result,
73 ): void {
74 switch ($result) {
75 case "win":
76 $teams[$team1]["W"]++;
77 $teams[$team2]["L"]++;
78 $teams[$team1]["P"] += 3;
79 break;
80
81 case "loss":
82 $teams[$team2]["W"]++;
83 $teams[$team1]["L"]++;
84 $teams[$team2]["P"] += 3;
85 break;
86
87 case "draw":
88 $teams[$team1]["D"]++;
89 $teams[$team2]["D"]++;
90 $teams[$team1]["P"]++;
91 $teams[$team2]["P"]++;
92 break;
93 }
94 }
95
96 private function sortTeams(array &$teams): void
97 {
98 uksort($teams, function ($teamA, $teamB) use ($teams) {
99 return $teams[$teamB]["P"] <=> $teams[$teamA]["P"] ?:
100 strcmp($teamA, $teamB);
101 });
102 }
103
104 private function generateTable(array $teams): string
105 {
106 $output = self::HEADER;
107
108 foreach ($teams as $team => $stats) {
109 $output .= sprintf(
110 "\n%-31s| %2d | %2d | %2d | %2d | %2d",
111 $team,
112 $stats["MP"],
113 $stats["W"],
114 $stats["D"],
115 $stats["L"],
116 $stats["P"],
117 );
118 }
119
120 return $output;
121 }
122}