Match applicant skills and versions to a job's requirements
I was asked this
No reports yet. Sign in to say where you were asked it.
An applicant tracking system screens candidates by the skills they list. Each applicant gives one comma-separated string of skills, strongest first. A job posting gives a comma-separated string of required skills.
A skill token is a name with an optional version after a hyphen, such as Rust-1.70, SQL or Go-Lang.
Part 1: parse and match
Implement is_qualified(applicant: str, required: str) -> bool. It returns True when the applicant lists every required skill.
- Trim the whitespace around each token and ignore empty tokens.
- Compare skill names case-insensitively.
- A token has a version only when the part after its last hyphen is numeric, made of digits and dots (
3,1.70,2.0.1).Go-Langis the namego-langwith no version. - If an applicant lists a skill twice, the first copy counts.
Part 2: versions
Now the versions count.
- A required skill with no version accepts any version of that skill.
- A required skill with a version needs an applicant version at least that high. Compare versions numerically, part by part:
1.70 > 1.9, and3.0 == 3. - An applicant who lists a skill without a version does not meet a versioned requirement for that skill.
Part 3: rank applicants
Implement rank_applicants(applicants: dict[str, str], required: str, preferred: str = "") -> list[str]. It returns the names of the qualified applicants, best first:
- More
preferredskills met first. Preferred skills follow the same version rules. - Then the smaller sum of the 0-based positions where the required skills appear in the applicant's list.
- Then the name, alphabetically.
Examples
is_qualified("Rust-1.70, Go-Lang, SQL", "sql, go-lang") -> True
is_qualified("Rust-1.9", "Rust-1.70") -> False # 9 < 70
is_qualified("Rust", "Rust-1") -> False
apps = {
"ana": "SQL, Kotlin-1.9, Rust-1.75",
"bo": "Rust-1.80, SQL",
"cy": "Rust-1.60, SQL, Kotlin-2",
"di": "Kotlin-2, Rust-1.72, SQL",
}
rank_applicants(apps, "Rust-1.70, SQL") -> ["bo", "ana", "di"]
rank_applicants(apps, "Rust-1.70, SQL", "Kotlin-2") -> ["di", "bo", "ana"]
cy is not qualified because Rust 1.60 is below 1.70.
Constraints
- Up to 10,000 applicants. Each lists up to 100 skills, and a job has up to 50 required skills.
- State the time and space complexity of each function.
Clarifying questions
- In Part 1, does a required skill with a version (
Rust-1.70) still match by name only, as long as the applicant lists Rust? - Can the required string itself list a skill twice, perhaps with two versions?
- Is
1.70read as the parts[1, 70], so trailing zeros are significant there but3.0 == 3because missing parts are zero? - Are hyphens ever used before a non-numeric suffix with a version after it, like
Python-3-beta? - In Part 3, do preferred skills that are also required count toward both rules?
What a strong answer covers
- One parser shared by every part: trim, skip empty tokens, split on the last hyphen only when the tail is digits and dots, lower-case the name, and turn the version into a tuple of integers.
- Turns the applicant list into a dict from name to
(version, position), keeping the first copy, so each requirement is one lookup. That is O(a + r) per check. - Compares versions as integer tuples padded with zeros, so
1.70 > 1.9and3.0 == 3, and treats "no version" as failing a versioned requirement. - Ranks with one sort key
(-preferred_met, position_sum, name)over the qualified applicants. That is O(A * (a + r + p) + A log A). - Tests: the examples,
Go-Langwith no version, a duplicate skill, whitespace and empty tokens, version ties like3against3.0.0, and ties broken by name.
Follow-ups
- Version ranges and caps (
Python>=3.8,<4). - Skill aliases (
JSandJavaScript,PostgresandPostgreSQL). - Score partial matches so near-qualified applicants are shown too.
- Screen millions of applicants against many jobs: build an index from skill to applicants.
Sign in to see the worked answer
The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.
What the labs asked this week
A weekly email of what OpenAI, Anthropic and the other top AI labs asked engineers, round by round.
Sign in to see the worked answer
The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.
Sign in to submit your code; every attempt is kept here.
