forked from neetcode-gh/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
updateCompletionTable.js
124 lines (109 loc) · 3.45 KB
/
updateCompletionTable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const { readdirSync } = require('fs');
const fs = require('fs');
const path = require('path');
const IGNORE_DIRS = ['.github', '.git', '.idea'];
const FOLDER_TO_LANG = {
javascript: 'JS',
typescript: 'TS',
csharp: 'C#',
c: 'C',
go: 'GO',
java: 'Java',
python: 'Python',
ruby: 'Ruby',
rust: 'Rust',
scala: 'Scala',
swift: 'Swift',
cpp: 'C++',
kotlin: 'Kotlin',
dart: 'Dart',
};
const PREPEND_PATH = process.argv[2] || './';
const TEMPLATE_PATH = process.argv[3] || './README_template.md';
const WRITE_PATH = process.argv[3] || './README.md';
const PROBLEM_SITE_DATA = JSON.parse(fs.readFileSync('./.problemSiteData.json', 'utf8'));
function createProblemsObj(PROBLEM_SITE_DATA) {
let PROBLEMS_OBJ = {}
for (const {problem, pattern, link, code} of PROBLEM_SITE_DATA) {
if (!(pattern in PROBLEMS_OBJ)) PROBLEMS_OBJ[pattern] = []
PROBLEMS_OBJ[pattern].push([problem, "https://leetcode.com/problems/" + link, code.slice(0, 4)])
}
return PROBLEMS_OBJ
}
const PROBLEMS_OBJ = createProblemsObj(PROBLEM_SITE_DATA)
const getDirectories = (source) =>
readdirSync(source, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);
function* walkSync(dir) {
const files = fs.readdirSync(dir, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
yield* walkSync(path.join(dir, file.name));
} else {
yield path.join(dir, file.name);
}
}
}
function nestedFiles(dir) {
files = [];
for (const filePath of walkSync(dir)) {
files.push(filePath);
}
return files;
}
const directories = getDirectories(PREPEND_PATH).filter(
(dir) => !IGNORE_DIRS.includes(dir)
);
const nestedFilesInDir = directories.reduce((acc, dir) => {
acc[dir] = nestedFiles(dir);
return acc;
}, {});
const tableHeader =
[
'Problem',
...directories.map((folder) => FOLDER_TO_LANG[folder] || folder),
]
.map((el) => `<sub>${el}</sub>`)
.join(' | ') + '\n';
const tableSep =
Array.from({ length: tableHeader.split('|').length })
.map((el) => '----')
.join(' | ') + '\n';
let fullOutput = '';
for (const problemCategory in PROBLEMS_OBJ) {
fullOutput += `### ${problemCategory}\n\n`;
fullOutput += tableHeader;
fullOutput += tableSep;
for (const [problemName, problemUrl, problemNumber] of PROBLEMS_OBJ[
problemCategory
]) {
let problemRow = [
`<sub>[${problemNumber} - ${problemName}](${problemUrl})</sub>`,
];
for (const dir of directories) {
let filePath = nestedFilesInDir[dir].find((file) =>
file
.match(/[\w-]+\..+/)?.[0]
?.startsWith(problemNumber)
);
if (filePath) {
problemRow.push(
`<sub><div align='center'>[✔️](${encodeURIComponent(
filePath
)})</div></sub>`
);
} else {
problemRow.push("<sub><div align='center'>❌</div></sub>");
}
}
fullOutput += problemRow.join(' | ') + '\n';
}
fullOutput += '\n';
}
const template = fs.readFileSync(TEMPLATE_PATH, { encoding: 'utf8' });
const toWrite = template.replaceAll('<completion-tables />', fullOutput);
console.log(toWrite);
fs.writeFileSync(WRITE_PATH, toWrite, {
encoding: 'utf8',
});