3606. Coupon Code Validator
Source: Dev.to
Problem Description
You are given three arrays of length n that describe the properties of n coupons:
code[i]: a string representing the coupon identifier.businessLine[i]: a string denoting the business category of the coupon.isActive[i]: a boolean indicating whether the coupon is currently active.
A coupon is valid if all of the following conditions hold:
code[i]is non‑empty and consists only of alphanumeric characters (a‑z,A‑Z,0‑9) and underscores (_).businessLine[i]is one of the four categories:"electronics","grocery","pharmacy","restaurant".isActive[i]istrue.
Return an array of the codes of all valid coupons, sorted first by their businessLine in the order
"electronics" → "grocery" → "pharmacy" → "restaurant"
and then by code in lexicographical (ascending) order within each category.
Example 1
Input
code = ["SAVE20", "", "PHARMA5", "SAVE@20"]
businessLine = ["restaurant", "grocery", "pharmacy", "restaurant"]
isActive = [true, true, true, true]
Output
["PHARMA5", "SAVE20"]
Explanation
- The first coupon is valid.
- The second coupon has an empty code → invalid.
- The third coupon is valid.
- The fourth coupon contains a special character
@→ invalid.
After filtering, the remaining codes are sorted by business line (pharmacy before restaurant) and then by code.
Example 2
Input
code = ["GROCERY15", "ELECTRONICS_50", "DISCOUNT10"]
businessLine = ["grocery", "electronics", "invalid"]
isActive = [false, true, true]
Output
["ELECTRONICS_50"]
Explanation
- The first coupon is inactive → invalid.
- The second coupon is valid.
- The third coupon has an invalid business line → invalid.
Constraints
n == code.length == businessLine.length == isActive.length1 ≤ n ≤ 1000 ≤ code[i].length, businessLine[i].length ≤ 100code[i]andbusinessLine[i]consist of printable ASCII characters.isActive[i]is eithertrueorfalse.
Hint
- Filter out any coupon where:
isActive[i]isfalse,code[i]is empty or contains characters other than alphanumerics/underscore,businessLine[i]is not in the allowed set.
- Store each remaining coupon as a pair
(businessLine[i], code[i]). - Define a priority map, e.g.
{ "electronics":0, "grocery":1, "pharmacy":2, "restaurant":3 }. - Sort the list of pairs by
(priority[businessLine], code)and return the code values in order.
Solution Overview
-
Validation
- Use a regular expression
^[a-zA-Z0-9_]+$to check thecode. - Verify
isActiveistrue. - Ensure
businessLinebelongs to the allowed set.
- Use a regular expression
-
Mapping Priority
Create an associative array that maps each business line to its sorting priority. -
Sorting
- Collect all valid coupons as an array of associative arrays
{ "line": ..., "code": ... }. - Use
usortwith a custom comparator that first compares the priority values, then compares the codes lexicographically (strcmp).
- Collect all valid coupons as an array of associative arrays
-
Result Extraction
After sorting, extract only thecodefields into the final result array.
PHP Implementation
0,
"grocery" => 1,
"pharmacy" => 2,
"restaurant" => 3,
];
$valid = [];
$n = count($code);
for ($i = 0; $i $businessLine[$i],
'code' => $code[$i],
];
}
// Sort by business line priority, then by code lexicographically
usort($valid, function ($a, $b) use ($priority) {
$pA = $priority[$a['line']];
$pB = $priority[$b['line']];
if ($pA !== $pB) {
return $pA $pB;
}
return strcmp($a['code'], $b['code']);
});
// Extract only the codes
return array_column($valid, 'code');
}
// ----- Test cases -----
print_r(validateCoupons(
["SAVE20", "", "PHARMA5", "SAVE@20"],
["restaurant", "grocery", "pharmacy", "restaurant"],
[true, true, true, true]
)); // Expected: ["PHARMA5", "SAVE20"]
print_r(validateCoupons(
["GROCERY15", "ELECTRONICS_50", "DISCOUNT10"],
["grocery", "electronics", "invalid"],
[false, true, true]
)); // Expected: ["ELECTRONICS_50"]
?>
Complexity Analysis
- Time Complexity:
O(n log n)— filtering is linear, sorting dominates withnbeing the number of valid coupons (≤ 100). - Space Complexity:
O(n)— additional storage for the list of valid coupons.