Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 72058e4

Browse files
feat(book/graph): add schedule exercise and solution
1 parent 802e9d3 commit 72058e4

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// tag::description[]
2+
function canFinish(n, prerequisites) {
3+
// end::description[]
4+
// tag::placeholder[]
5+
// write your code here...
6+
// end::placeholder[]
7+
// tag::solution[]
8+
const graph = new Map(Array(n).fill().map((v, i) => ([i, []])));
9+
prerequisites.forEach(([u, v]) => graph.get(v).push(u));
10+
11+
const seen = [];
12+
const hasCycle = (node) => {
13+
if (seen[node] === 1) return true; // if visiting, it's a cycle!
14+
if (seen[node] === 2) return false; // if visited, skip it.
15+
16+
seen[node] = 1; // mark as visiting.
17+
for (const adj of graph.get(node)) if (hasCycle(adj)) return true;
18+
seen[node] = 2; // mark as visited.
19+
return false;
20+
};
21+
22+
for (let i = 0; i < n; i++) if (hasCycle(i)) return false;
23+
return true;
24+
// end::solution[]
25+
// tag::description[]
26+
}
27+
// end::description[]
28+
29+
module.exports = { canFinish };
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const { canFinish } = require('./course-schedule');
2+
// const { } = require('../../src/index');
3+
4+
[canFinish].forEach((fn) => {
5+
describe(`TOPIC: ${fn.name}`, () => {
6+
it('should work with null/empty', () => {
7+
const actual = [];
8+
const expected = true;
9+
expect(fn(0, actual)).toEqual(expected);
10+
});
11+
12+
it('should work basic case', () => {
13+
const actual = [[1, 0]];
14+
const courses = 2;
15+
const expected = true;
16+
expect(fn(courses, actual)).toEqual(expected);
17+
});
18+
19+
it('should detect cycle', () => {
20+
const actual = [[0, 1], [1, 0]];
21+
const courses = 2;
22+
const expected = false;
23+
expect(fn(courses, actual)).toEqual(expected);
24+
});
25+
26+
it('multiple links to a node without cycle', () => {
27+
const actual = [[2, 1], [1, 0], [2, 0]];
28+
const courses = 3;
29+
const expected = true;
30+
expect(fn(courses, actual)).toEqual(expected);
31+
});
32+
33+
it('multiple links to a node without cycle (different order)', () => {
34+
const actual = [[2, 0], [1, 0], [2, 1]];
35+
const courses = 3;
36+
const expected = true;
37+
expect(fn(courses, actual)).toEqual(expected);
38+
});
39+
40+
it('indirect cycle', () => {
41+
const actual = [[1, 0], [2, 1], [0, 2]];
42+
const courses = 3;
43+
const expected = false;
44+
expect(fn(courses, actual)).toEqual(expected);
45+
});
46+
47+
it('indirect cycle with nodes without indegrees', () => {
48+
const actual = [[1, 0], [2, 1], [3, 2], [1, 3]];
49+
const courses = 4;
50+
const expected = false;
51+
expect(fn(courses, actual)).toEqual(expected);
52+
});
53+
});
54+
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /