Skip to content

Commit f2923a1

Browse files
author
Mauricio Klein
committed
Add solution for challenge #26
1 parent 860754d commit f2923a1

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@
2525
- [x] [Challenge 23: Invert a binary tree](challenge-23/)
2626
- [x] [Challenge 24: Move zeros](challenge-24/)
2727
- [x] [Challenge 25: Falling Dominoes](challenge-25/)
28+
- [x] [Challenge 26: Course Pre-requisites](challenge-26/)

Diff for: challenge-26/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
python test_*.py
3+
4+
.PHONY: test

Diff for: challenge-26/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Course Pre-requisites
2+
3+
This problem was asked by Google.
4+
5+
## Description
6+
7+
You are given a hash table where the key is a course code, and the value is a list of all the course codes that are prerequisites for the key.
8+
9+
Return a valid ordering in which we can complete the courses.
10+
11+
If no such ordering exists, return NULL.
12+
13+
## Example
14+
15+
```
16+
Input:
17+
{
18+
'CSC300': ['CSC100', 'CSC200'],
19+
'CSC200': ['CSC100'],
20+
'CSC100': []
21+
}
22+
23+
Output: ['CSC100', 'CSC200', 'CSC300']
24+
```

Diff for: challenge-26/__init__.py

Whitespace-only changes.

Diff for: challenge-26/solver.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
def courses_to_take(input):
2+
"""
3+
Time complexity: O(n) (we process each course only once)
4+
Space complexity: O(n) (array to store the result)
5+
"""
6+
# Normalize the dependencies, using a set to track the
7+
# dependencies more efficiently
8+
course_with_deps = {}
9+
to_take = []
10+
11+
for course, deps in input.items():
12+
if not deps:
13+
# Course with no dependencies:
14+
# candidate to start the search
15+
to_take.append(course)
16+
else:
17+
course_with_deps[course] = set(deps)
18+
19+
result = []
20+
while to_take:
21+
course = to_take.pop()
22+
23+
# Add course to journey
24+
result.append(course)
25+
26+
# Iterate through courses and remove this course from
27+
# dependencies
28+
for prereq_course, prereq_deps in course_with_deps.items():
29+
if course in prereq_deps:
30+
prereq_deps.remove(course)
31+
32+
if not prereq_deps:
33+
# Course has all the dependencies solved:
34+
# add to the "to_take" queue
35+
to_take.append(prereq_course)
36+
del course_with_deps[prereq_course]
37+
38+
return result if len(result) == len(input) else None

Diff for: challenge-26/test_solver.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest
2+
from solver import courses_to_take
3+
4+
class TestSolver(unittest.TestCase):
5+
def test_courses_to_take(self):
6+
self.assertEqual(
7+
courses_to_take({
8+
'CSC300': ['CSC100', 'CSC200'],
9+
'CSC200': ['CSC100'],
10+
'CSC100': []
11+
}),
12+
['CSC100', 'CSC200', 'CSC300']
13+
)
14+
15+
self.assertEqual(
16+
courses_to_take({
17+
'CSC400': ['CSC300', 'CSC200'],
18+
'CSC300': ['CSC200'],
19+
'CSC200': ['CSC300', 'CSC100'],
20+
'CSC100': []
21+
}),
22+
None
23+
)
24+
25+
if __name__ == "__main__":
26+
unittest.main()

0 commit comments

Comments
 (0)