Skip to content

SORT-O-MATIC

Minty Candycane

Hey there, KringleCon attendee! I'm Minty Candycane!

I'm working on fixing the Present Sort-O-Matic.

The Sort-O-Matic uses JavaScript regular expressions to sort presents apart from misfit toys, but it's not working right.

With some tools, regexes need / at the beginning and the ends, but they aren't used here.

You can find a regular expression cheat sheet here if you need it.

You can use this regex interpreter to test your regex against the required Sort-O-Matic patterns.

Do you think you can help me fix it?

TL;DR

1
2
3
4
5
6
7
8
\d+
[a-zA-Z]{3}
[a-z0-9]{2}
[^A-L1-5]{2}
^\d{3,}$
^([0][0-9]|[1][0-2]|[2][0-4]|[0-9]):([0-5][0-9]):([0-5][0-9])$
^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$
^([0][9]|[1][0-2]|[0-2][0-9]|[3][0-1])[.\-/]([0][9]|[1][0-2]|[0-2][0-9]|[3][0-1])[.\-/][0-9]{4}$

Location

Upper part of the Workshop see map

Hints

Here's a place to try out your JS Regex expressions: https://regex101.com/

Handy quick reference for JS regular expression construction: https://www.debuggex.com/cheatsheet/regex/javascript

Solution

Matches at least one digit

  • \d designates a character from the digits character class, and since we want at least one digit, we use the + quantifier
\d+

Matches 3 alpha a-z characters ignoring case

  • Ranges of characters can be designated in a set. For example, [a-z] means any of the characters in the ASCII range 0x61 to 0x7A (inclusive of the upper/lower bound). Since we are ignoring case, we also need to include the range for the capital letters. Finally, the quantifier is for exactly 3 of the characters from this set.
[a-zA-Z]{3}

Matches 2 chars of lowercase a-z or numbers

  • Similar to #2, except the ranges of characters in the set is different, and the quantifier is 2.
[a-z0-9]{2}

Matches any 2 chars not uppercase A-L or 1-5

  • Sets can be negated. The ^ character means any character not in this set.
[^A-L1-5]{2}

Matches three or more digits only

  • Quantifiers can have open ranges on the upper or lower bound. In this case, we want at least 3 occurrences, but it could be any number more. We add the ^ and $ assertions to make sure that there is nothing before or after the digits.
^\d{3,}$

Matches multiple hour:minute:second time formats only

  • This one starts to get tricky because regex is probably not the best tool for this particular validation in real life.

  • However, based on the valid/invalid examples we are given, the hours could have one or two digits, but the minutes and seconds must be two digits. Also, the hours could be in military or civilian time.

  • For the hours, there are a couple of scenarios of interest:

    • If there are two digits and the first digit is 0, the second digit must be in the range 0-9
    • If there are two digits and the first digit is 1, the second digit must be in the range 0-2
    • If there are two digits and the first digit is 2, the second digit must be in the range 0-4
    • If there is one digit it must be in the range 0-9
  • For minutes and seconds, the first digits must be in the range 0-5, and the second digits in the range 0-9
^([0][0-9]|[1][0-2]|[2][0-4]|[0-9]):([0-5][0-9]):([0-5][0-9])$

Matches MAC address format only while ignoring case

  • MAC addresses are hex digits, and since we're ignoring case the possible characters are [0-9a-fA-F]. These values followed by a semicolon match the first five sets. The last set does not have the semicolon, so it is declared separately.
^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$

Matches multiple day, month, and year date formats only

  • Again, regex might not be the best tool for this task because to really be accurate you would need to account for leap years, the fact that not all months have 31 days, the fact that the examples allow either the month or the day first, etc. Dates are hard to validate with regex, especially if you allow the month and day to be written either way.

  • But, let's take a naive approach for the sake of this challenge.

^([0][9]|[1][0-2]|[0-2][0-9]|[3][0-1])[.\-/]([0][9]|[1][0-2]|[0-2][0-9]|[3][0-1])[.\-/][0-9]{4}$