-
Notifications
You must be signed in to change notification settings - Fork 0
/
leetcode_allProblems.js
111 lines (98 loc) · 3.87 KB
/
leetcode_allProblems.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
let getCSRFToken = function(cookies) {
for (let ck of cookies) {
let kvp = ck.split('=');
if (kvp[0].indexOf('csrftoken') >= 0) return kvp[1];
}
return '';
};
let getQuestions = async function(csrfToken, skip, limit) {
let postBody = {
query: 'query problemsetQuestionList($categorySlug: String, $limit: Int, $skip: Int, $filters: QuestionListFilterInput) {problemsetQuestionList: questionList(categorySlug: $categorySlug limit: $limit skip: $skip filters: $filters){total:totalNum questions: data{likes dislikes acRate difficulty freqBar frontendQuestionId: questionFrontendId isFavor paidOnly: isPaidOnly status title titleSlug topicTags{name id slug}}}}',
variables: {"categorySlug":"","skip":skip,"limit":limit,"filters":{}},
};
let param = {
method: 'POST',
credentials: "include",
headers: {
'content-type': 'application/json',
'x-csrftoken': csrfToken,
},
body: JSON.stringify(postBody),
};
let ret = null;
await fetch('https://leetcode.com/graphql', param).then(response => response.json()).then(data => {
ret = data.data.problemsetQuestionList.questions;
});
return ret;
};
let saveFile = function(fileName, fileContent) {
let bb = new Blob([fileContent ], { type: 'text/plain' });
let a = document.createElement('a');
a.download = fileName;
a.href = window.URL.createObjectURL(bb);
a.click();
};
let main = async function() {
let csrfToken = getCSRFToken(document.cookie.split(';'));
if (csrfToken.length <= 0) throw 'csrfToken is empty';
let allProblems = [], batchSize = 100, batchQuestions = null;
do {
batchQuestions = await getQuestions(csrfToken, allProblems.length, batchSize);
allProblems = allProblems.concat(batchQuestions);
await new Promise(r => setTimeout(r, 2000));
console.log('allProblems count:' + allProblems.length);
} while (batchQuestions.length === batchSize);
let fileName = 'leetcode_all' + allProblems.length + '_' + (new Date().toISOString().split('T')[0]) + '.json'
let fileContent = JSON.stringify(allProblems);
saveFile(fileName, fileContent);
};
//main();
// running in Node.js
/**
* @param {*} problem
* @param {*} filter: {likesAtLeast:100, ratioAtLeast:10, status:"ac"|"notac"|null, topic:"Array"|"Linked List"|"Hash Table"}
* @returns true means this problem is what we want, false otherwise
*/
let passCheck = function(problem, filter) {
if ((filter.likesAtLeast !== undefined && problem.likes < filter.likesAtLeast) ||
(filter.ratioAtLeast !== undefined && problem.likes/problem.dislikes < filter.ratioAtLeast) ||
(filter.status !== undefined && problem.status !== filter.status)) {
return false;
}
let matchTopic = (filter.topic === undefined);
for (let topic of problem.topicTags) {
if (topic.name === filter.topic) {
matchTopic = true;
break;
}
}
return matchTopic;
};
const fs = require('fs');
let main2 = function(problemJsonFilePath, filter) {
let ret = [];
try {
let data = fs.readFileSync(problemJsonFilePath, 'utf8');
let problems = JSON.parse(data);
problems.forEach(p => {
if (passCheck(p, filter)) {
console.log('here');
ret.push({frontendQuestionId: p.frontendQuestionId, title: p.title, likes: p.likes, ratio: p.likes/p.dislikes});
console.log('ret.length:'+ret.length);
}
});
}
catch (err) {
console.log('err:'+err);
}
return ret;
};
let problemJsonFilePath = '/mnt/c/Users/leca/Downloads/leetcode_all2183_2022-02-22.json';
let filter = {
likesAtLeast: 2000,
ratioAtLeast: 10,
status: null,
};
let ret = main2(problemJsonFilePath, filter);
ret.sort((a,b) => a.likes - b.likes);
console.log(ret);