1
+ #!/usr/bin/env python3
2
+
3
+ from dataclasses import dataclass
4
+ from os import listdir
5
+ from pathlib import Path
6
+
7
+ import requests
8
+
9
+
10
+ @dataclass
11
+ class Task :
12
+ """The task dataclass. Container for task info"""
13
+
14
+ id : str
15
+ title : str
16
+ solution : str
17
+ difficulty : str
18
+
19
+
20
+ def fetch_leetcode_folder_tasks (solutions_folder : Path ) -> list [Task ]:
21
+ """Fetch leetcode tasks from the Leetcode"""
22
+
23
+ # Fetch tasks info from the leetcode API.
24
+ resp = requests .get ("https://leetcode.com/api/problems/algorithms/" , timeout = 10 )
25
+ content_dict = resp .json ()
26
+
27
+ raw_tasks_id_dict = {}
28
+
29
+ for task in content_dict ["stat_status_pairs" ]:
30
+ task_stat = task ["stat" ]
31
+ raw_tasks_id_dict [str (task_stat ["frontend_question_id" ])] = task
32
+
33
+ # Generate result tasks info to be inserted into the document
34
+ tasks_list = []
35
+
36
+ difficulty = {1 : "Easy" , 2 : "Medium" , 3 : "Hard" }
37
+
38
+ for fl in listdir (solutions_folder ):
39
+ task_id = fl .split ("." )[0 ]
40
+
41
+ raw_task = raw_tasks_id_dict .get (task_id , None )
42
+ if raw_task is None :
43
+ continue
44
+
45
+ raw_task_stat = raw_task ["stat" ]
46
+ tasks_list .append (
47
+ Task (
48
+ id = f'{ raw_task_stat ["frontend_question_id" ]} ' ,
49
+ title = f'[{ raw_task_stat ["question__title" ]} ](https://leetcode.com/problems/{ raw_task_stat ["question__title_slug" ]} )' ,
50
+ solution = f"[C++](./src/{ fl } )" ,
51
+ difficulty = f'{ difficulty .get (raw_task ["difficulty" ]["level" ], "" )} ' ,
52
+ )
53
+ )
54
+
55
+ return tasks_list
56
+
57
+
58
+ HEADER_ID = "#"
59
+ HEADER_TITLE = "Title"
60
+ HEADER_SOLUTION = "Solution"
61
+ HEADER_DIFFICULTY = "Difficulty"
62
+ SEPARATOR = "-"
63
+
64
+
65
+ def print_directory_md (tasks_list : list [Task ]) -> None :
66
+ """Print tasks into the stdout"""
67
+
68
+ def get_max_len (get_item ):
69
+ return max (list (map (lambda x : len (get_item (x )), tasks_list )))
70
+
71
+ id_max_length = max (get_max_len (lambda x : x .id ), len (HEADER_ID ))
72
+ title_max_length = max (get_max_len (lambda x : x .title ), len (HEADER_TITLE ))
73
+ solution_max_length = max (get_max_len (lambda x : x .solution ), len (HEADER_SOLUTION ))
74
+ difficulty_max_length = max (
75
+ get_max_len (lambda x : x .difficulty ), len (HEADER_DIFFICULTY )
76
+ )
77
+
78
+ def formatted_string (header , title , solution , difficulty ):
79
+ return (
80
+ f"| { header .rjust (id_max_length )} "
81
+ + f"| { title .ljust (title_max_length )} "
82
+ + f"| { solution .ljust (solution_max_length )} "
83
+ + f"| { difficulty .ljust (difficulty_max_length )} |"
84
+ )
85
+
86
+ tasks_rows = []
87
+
88
+ tasks_rows .append (
89
+ formatted_string (HEADER_ID , HEADER_TITLE , HEADER_SOLUTION , HEADER_DIFFICULTY )
90
+ )
91
+ tasks_rows .append (
92
+ formatted_string (
93
+ id_max_length * SEPARATOR ,
94
+ title_max_length * SEPARATOR ,
95
+ solution_max_length * SEPARATOR ,
96
+ difficulty_max_length * SEPARATOR ,
97
+ )
98
+ )
99
+
100
+ tasks_list .sort (key = lambda x : int (x .id .strip ()))
101
+
102
+ for task in tasks_list :
103
+ tasks_rows .append (
104
+ formatted_string (task .id , task .title , task .solution , task .difficulty )
105
+ )
106
+
107
+ print (
108
+ """
109
+ # LeetCode
110
+
111
+ ### LeetCode Algorithm
112
+ """
113
+ )
114
+
115
+ for item in tasks_rows :
116
+ print (item )
117
+
118
+
119
+ if __name__ == "__main__" :
120
+ top_dir = Path ("." )
121
+ solutions_folder = top_dir / "leetcode" / "src"
122
+
123
+ tasks_list = fetch_leetcode_folder_tasks (solutions_folder )
124
+ print_directory_md (tasks_list )
0 commit comments