T: / Corrigés des challenges / PHP
Avec des if, puis sans if, puis array_key_exists, puis array_count_values et une belle classe pour finir
Ce corrigé et ces explications s’appuient sur le challenge POKEMON_1.
Pour coller avec le thème, imagine que chaque Pokémon représente un élément dans une liste. Si tu te demandes combien de fois Pikachu apparaît, tu cherches en fait son « occurrence » dans cette liste.
En termes simples, une occurrence indique combien de fois un élément particulier se manifeste. En PHP, tu as plusieurs outils et techniques pour repérer et compter ces occurrences. En voici quelques uns :
$nbFeu = 0;
$nbEau = 0;
$nbHerbe = 0;
$nbRare = 0;
foreach ($types as $type) {
if ($type === 'Feu') {
$nbFeu++;
continue;
}
if ($type === 'Eau') {
$nbEau++;
continue;
}
if ($type === 'Herbe') {
$nbHerbe++;
continue;
}
$nbRare++;
}
$reponse = min([$nbFeu, $nbEau, $nbHerbe, $nbRare]);
Explications
$nbFeu = 0;
$nbEau = 0;
$nbHerbe = 0;
foreach ($types as $type) {
$nbFeu += (int) ($type === 'Feu');
$nbEau += (int) ($type === 'Eau');
$nbHerbe += (int) ($type === 'Herbe');
}
$nbRare = count($types) - $nbFeu - $nbEau - $nbHerbe;
$reponse = min([$nbFeu, $nbEau, $nbHerbe, $nbRare]);
Explications
Cette technique est décrite dans l’article dédié au remplacement des if dans le code en PHP.
$groupes = ['Feu' => 0, 'Eau' => 0, 'Herbe' => 0, 'Rare' => 0];
foreach ($types as $type) {
if (array_key_exists($type, $groupes)) {
$groupes[$type]++;
continue;
}
$groupes['Rare']++;
}
echo min($groupes);
Explications
$values = array_count_values($types);
$reponse = min(
$values['Feu'],
$values['Eau'],
$values['Herbe'],
count($types) - $values['Feu'] - $values['Eau'] - $values['Herbe']
);
Explications
array_count_values est une fonction native de PHP, qui fait (grosso modo) exactement la même chose que la V3. Je vais récupérer un tableau avec comme clés les différents éléments de mon (premier) tableau, et comme valeurs le nombre d’occurrences de chacun de ces éléments.
ATTENTION : ce code n’est pas 100% correct ! En effet, si je n’ai pas de type « Eau », array_count_values ne saura pas créer « Eau » => 0. Il faudrait donc tester l’existence de chaque clé avant de vouloir l’utiliser…
function countType(string|array $searchType, array $types): int
{
$searchType = (array) $searchType;
$count = 0;
foreach ($types as $type) {
$count += (int) in_array($type, $searchType);
}
return $count;
}
$reponse = min(
countType('Feu', $types),
countType('Eau', $types),
countType('Herbe', $types),
countType(['Insecte', 'Psychique', 'Air', 'Glace', 'Poison'], $types)
Explications
Remarque : l’union de typage dans la déclaration d’une fonction, ici string|array, est disponible à partir de PHP 8.0
final class POKEMONS
{
private const TYPES_RARES = ['Air', 'Poison', 'Glace', 'Psychique', 'Insecte'];
private const TYPES_CLASSIQUES = ['Feu', 'Eau', 'Herbe'];
private array $types;
private array $countTypes;
public function __construct(array $types)
{
$this->types = $types;
$this->countTypes = array_count_values($types);
}
private function countType(string $type): int
{
return $this->countTypes[$type] ?? 0;
}
public function nbGroups(): int
{
return min(
array_map([$this, 'countType'], self::TYPES_CLASSIQUES)
+
[array_sum(array_map([$this, 'countType'], self::TYPES_RARES))]
);
}
}
$reponse = (new POKEMONS($types))->nbGroups();
Explications
On a vu dans ce corrigé plusieurs façons de compter des occurrences en PHP. Certaines assez classiques, d’autres plus évoluées. Selon les problématiques que tu rencontreras, n’hésite pas à expérimenter avec de nouvelles idées et développer tes propres méthodes !
Tu peux aussi choisir un de ces challenges pour t’entrainer :
Other content to discover