Quick reference for typical Codility tasks in PHP. Focus: correctness, edge cases, and time complexity. Source: github.com/iammikek/codility-quick-reference.
If you can explain the invariant while coding, you are less likely to regress.
=== / !==.isset.Useful when a platform is pinned to PHP 7.4 but you instinctively reach for PHP 8 conveniences.
| PHP 8 | PHP 7.4 equivalent | Notes |
|---|---|---|
match ($x) { ... } |
switch ($x) { ... } |
Remember break; watch loose comparisons in switch. |
$obj?->prop, $obj?->method() |
($obj !== null) ? $obj->prop : null |
Or guard early with if ($obj === null) return ...; |
str_contains($s, $needle) |
strpos($s, $needle) !== false |
Use !== false (position 0 is valid). |
str_starts_with($s, $prefix) |
strpos($s, $prefix) === 0 |
Or substr($s, 0, strlen($prefix)) === $prefix. |
str_ends_with($s, $suffix) |
substr($s, -strlen($suffix)) === $suffix |
Guard empty suffix if you care about edge cases. |
throw as an expression |
if (...) { throw ...; } |
Keep it explicit, especially in ternaries. |
Named arguments: f(x: 1, y: 2) |
f(1, 2) |
Use positional args, or pass an options array. |
Union types: int|string |
Docblock + runtime validation | E.g. /** @param int|string $x */ + is_int/is_string. |
mixed, static return type |
Omit type + docblock | Prefer precise types where possible, avoid overusing “anything”. |
$a ??= $b |
($a === null) ? ($a = $b) : $a |
In practice, write an if ($a === null) { $a = $b; } guard. |
$l/$r: current window bounds (and what invariant the window must satisfy).$P: prefix sums where P[i] means sum of the first i elements.$bestEnding: best value “ending at i” (Kadane-style DP).$lo/$hi: which bounds are inclusive, and what you return.strpos(...): always compare with !== false (0 is a valid index).sort() reindexes keys. Use asort() if you must preserve keys.=== / !== to avoid “0”, false, and "" surprises.$min/$max safely with PHP_INT_MAX/PHP_INT_MIN.function solution($A) {
$n = count($A); // [N]
if ($n === 0) {
return 0;
}
$ans = 0; // [return value]
for ($i = 0; $i < $n; $i++) { // [single pass]
$v = $A[$i]; // [current element]
// ...
}
return $ans;
}
// Hash map frequency
$freq = [];
foreach ($A as $v) {
$freq[$v] = ($freq[$v] ?? 0) + 1; // [count occurrences]
}
// Set membership
$seen = [];
$seen[$v] = true; // [mark as present]
if (isset($seen[$x])) {
// ...
}
// Sorting
sort($A); // ascending, reindexes
rsort($A); // descending, reindexes
asort($A); // ascending, preserves keys
ksort($A); // sort by keys
usort($A, function ($a, $b) {
return ($a <=> $b); // [negative/0/positive]
});
// Strings
$len = strlen($s);
$ch = $s[$i]; // [single byte]
$parts = explode(",", $s);
$pos = strpos($s, "needle"); // [false if not found]
// Safe min/max init
$min = PHP_INT_MAX; // [safe initial min]
$max = PHP_INT_MIN; // [safe initial max]
P (prefix sums):P[0] = 0
[empty prefix]
P[i + 1] = P[i] + A[i]
[so P[k] = sum(A[0..k-1])]
l..r (inclusive):sum(l..r) = P[r + 1] - P[l]
[convert range sum into two prefix sums]
$n = count($A);
$P = array_fill(0, $n + 1, 0); // [P[0] = 0]
for ($i = 0; $i < $n; $i++) {
$P[$i + 1] = $P[$i] + $A[$i]; // [P[i+1] = sum(A[0..i])]
}
$sumLR = $P[$r + 1] - $P[$l]; // [sum(l..r)]
l and r, maintain an invariant.$l = 0; // [left pointer]
$freq = [];
for ($r = 0; $r < $n; $r++) {
$x = $A[$r]; // [right element]
$freq[$x] = ($freq[$x] ?? 0) + 1;
while ($freq[$x] > 1) { // [shrink until invariant holds]
$y = $A[$l]; // [element leaving window]
$l++;
$freq[$y]--;
}
}
$stack[] = $v, array_pop.$stack = []; // [open brackets]
foreach (str_split($s) as $ch) {
if ($ch === "(" || $ch === "[" || $ch === "{") {
$stack[] = $ch;
continue;
}
if (!$stack) {
return 0; // [closing without opening]
}
$top = array_pop($stack);
if ($ch === ")" && $top !== "(") return 0; // [mismatch]
if ($ch === "]" && $top !== "[") return 0; // [mismatch]
if ($ch === "}" && $top !== "{") return 0; // [mismatch]
}
return $stack ? 0 : 1; // [must close all opens]
bestEnding: best sum ending here.best: best overall.$bestEnding = $A[0]; // [best sum ending at i]
$best = $A[0];
for ($i = 1; $i < $n; $i++) {
$bestEnding = max($A[$i], $bestEnding + $A[$i]); // [extend or restart]
$best = max($best, $bestEnding); // [global best]
}
return $best;
$lo = 0; // [inclusive]
$hi = $n - 1;
while ($lo <= $hi) {
$mid = intdiv($lo + $hi, 2);
if ($A[$mid] === $target) {
return $mid;
}
if ($A[$mid] < $target) {
$lo = $mid + 1; // [search right]
} else {
$hi = $mid - 1; // [search left]
}
}
return -1;
ok(x), search smallest x that works.$lo = $minCandidate; // [lower bound]
$hi = $maxCandidate;
while ($lo < $hi) {
$mid = intdiv($lo + $hi, 2);
if (ok($mid)) {
$hi = $mid; // [mid works, try smaller]
} else {
$lo = $mid + 1; // [mid fails, go bigger]
}
}
return $lo;
// XOR unpaired (OddOccurrencesInArray style)
// [assumes: exactly one value occurs odd times]
$x = 0;
foreach ($A as $v) {
$x = ($x ^ $v); // [pairs cancel: a^a = 0]
}
return $x; // [remaining unpaired value]
sort($A); // [group equal values]
$distinct = 0;
$prev = null;
foreach ($A as $v) {
if ($prev === null || $v !== $prev) {
$distinct++; // [new value]
}
$prev = $v;
}
PHP_INT_MAX guards for initialisation.$x = ($map[$k] ?? 0) + 1; [increment counter in a map]$arr = array_fill(0, $n, false); [boolean array size N]$mid = intdiv($lo + $hi, 2); [binary search midpoint]$min = min($min, $v);, $max = max($max, $v); [running min/max]Printing: use your browser print dialog, ensure background graphics are off, and keep scale at 100% unless needed.