fix: python script

This commit is contained in:
yanglbme 2023-05-10 14:18:34 +08:00
parent 66f2af498f
commit dbeacb344e
11 changed files with 162 additions and 78 deletions

View File

@ -3,9 +3,9 @@ class Solution:
def dfs(i: int):
vis[i] = True
for j, x in enumerate(isConnected[i]):
if not vis[j] and x:
if not vis[j] and x:
dfs(j)
n = len(isConnected)
vis = [False] * n
ans = 0
@ -13,4 +13,4 @@ class Solution:
if not vis[i]:
dfs(i)
ans += 1
return ans
return ans

View File

@ -17,4 +17,4 @@ class Solution:
r = mid - 1
return max(dfs(l - 1, j - 1), dfs(i - l, j)) + 1
return dfs(n, k)
return dfs(n, k)

View File

@ -1,13 +1,14 @@
from threading import Semaphore
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.z = Semaphore(1)
self.e = Semaphore(0)
self.o = Semaphore(0)
# printNumber(x) outputs "x", where x is an integer.
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n):
self.z.acquire()
@ -16,13 +17,13 @@ class ZeroEvenOdd:
self.o.release()
else:
self.e.release()
def even(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(2, self.n + 1, 2):
self.e.acquire()
printNumber(i)
self.z.release()
def odd(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(1, self.n + 1, 2):
self.o.acquire()

View File

@ -16,4 +16,4 @@ class Solution:
cnt[i - 1] -= 1
if i == 4:
x -= 1
return -1 if x else ans
return -1 if x else ans

View File

@ -6,4 +6,4 @@ class Solution:
if mx < t or (mx == t and ans > uid):
ans, mx = uid, t
last += t
return ans
return ans

View File

@ -8,18 +8,18 @@
如果竞赛积分处于段位的临界值,在每周比赛结束重新计算后会出现段位升级或降级的情况。段位升级或降级后会自动替换对应的荣誉勋章。
| 段位 | 比例 | 段位名 | 国服分数线 | 勋章 |
| ----- | ------ | -------- | --------- | --------------------------------------------------------------------------- |
| LV3 | 5% | Guardian | &ge;2251.88 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Guardian.gif" style="width: 80px;" /></p> |
| LV2 | 20% | Knight | &ge;1879.80 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Knight.gif" style="width: 80px;" /></p> |
| LV1 | 75% | - | - | - |
| 段位 | 比例 | 段位名 | 国服分数线 | 勋章 |
| ---- | ---- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| LV3 | 5% | Guardian | &ge;2251.88 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Guardian.gif" style="width: 80px;" /></p> |
| LV2 | 20% | Knight | &ge;1879.80 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Knight.gif" style="width: 80px;" /></p> |
| LV1 | 75% | - | - | - |
力扣竞赛 **全国排名前 10** 的用户,全站用户名展示为品牌橙色。
## 赛后估分网站
- https://lcpredictor.herokuapp.com
- https://lccn.lbao.site
- https://lcpredictor.herokuapp.com
- https://lccn.lbao.site
## 往期竞赛

View File

@ -11,11 +11,11 @@ If you are in the top 5% of the contest rating, youll get the “Guardian”
If you are in the top 25% of the contest rating, youll get the “Knight” badge.
| Level | Proportion | Badge | Rating | |
| ----- | ---------- | ---------- | -------------- | ----------------------------------------------------------------------------------------------------------------------- |
| LV3 | 5\% | Guardian | &ge;2228.90 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Guardian.gif" style="width: 80px;" /></p> |
| LV2 | 20\% | Knight | &ge;1842.73 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Knight.gif" style="width: 80px;" /></p> |
| LV1 | 75\% | - | - | - |
| Level | Proportion | Badge | Rating | |
| ----- | ---------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| LV3 | 5\% | Guardian | &ge;2228.90 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Guardian.gif" style="width: 80px;" /></p> |
| LV2 | 20\% | Knight | &ge;1842.73 | <p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/images/Knight.gif" style="width: 80px;" /></p> |
| LV1 | 75\% | - | - | - |
For top 10 users (excluding LCCN users), your LeetCode ID will be colored orange on the ranking board. You'll also have the honor with you when you post/comment under discuss.

View File

@ -2687,4 +2687,4 @@
## 版权
著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 [@yanglbme](mailto:contact@yanglibin.info) 获得授权,非商业转载请注明出处。
著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 [@yanglbme](mailto:contact@yanglibin.info) 获得授权,非商业转载请注明出处。

View File

@ -2685,4 +2685,4 @@ Press <kbd>Control</kbd>+<kbd>F</kbd>(or <kbd>Command</kbd>+<kbd>F</kbd> on the
## Copyright
[@Doocs](https://github.com/doocs)
[@Doocs](https://github.com/doocs)

View File

@ -1,3 +1,4 @@
import json
import time
from datetime import timezone, timedelta, datetime
@ -21,6 +22,8 @@ weekly_range = range(83, 500)
biweekly_range = range(1, 300)
WEEKLY_URL = 'https://leetcode.cn/contest/api/info/weekly-contest-{}/'
BIWEEKLY_URL = 'https://leetcode.cn/contest/api/info/biweekly-contest-{}/'
WEEKLY_SLUG = 'weekly-contest-{}'
BIWEEKLY_SLUG = 'biweekly-contest-{}'
class Spider:
@ -57,18 +60,18 @@ class Spider:
form1 = {
'operationName': 'globalData',
'query': 'query globalData {\n feature {\n questionTranslation\n subscription\n signUp\n '
'discuss\n mockInterview\n contest\n store\n book\n chinaProblemDiscuss\n '
'socialProviders\n studentFooter\n cnJobs\n enableLsp\n enableWs\n '
'enableDebugger\n enableDebuggerAdmin\n enableDarkMode\n tasks\n '
'leetbook\n __typename\n }\n userStatus {\n isSignedIn\n isAdmin\n '
'isStaff\n isSuperuser\n isTranslator\n isPremium\n isVerified\n '
'isPhoneVerified\n isWechatVerified\n checkedInToday\n username\n '
'realName\n userSlug\n groups\n avatar\n optedIn\n '
'requestRegion\n region\n activeSessionId\n permissions\n notificationStatus {\n '
'lastModified\n numUnread\n __typename\n }\n completedFeatureGuides\n '
'useTranslation\n accountStatus {\n isFrozen\n inactiveAfter\n __typename\n '
'}\n __typename\n }\n siteRegion\n chinaHost\n websocketUrl\n userBannedInfo {\n '
'bannedData {\n endAt\n bannedType\n __typename\n }\n __typename\n }\n}\n',
'discuss\n mockInterview\n contest\n store\n book\n chinaProblemDiscuss\n '
'socialProviders\n studentFooter\n cnJobs\n enableLsp\n enableWs\n '
'enableDebugger\n enableDebuggerAdmin\n enableDarkMode\n tasks\n '
'leetbook\n __typename\n }\n userStatus {\n isSignedIn\n isAdmin\n '
'isStaff\n isSuperuser\n isTranslator\n isPremium\n isVerified\n '
'isPhoneVerified\n isWechatVerified\n checkedInToday\n username\n '
'realName\n userSlug\n groups\n avatar\n optedIn\n '
'requestRegion\n region\n activeSessionId\n permissions\n notificationStatus {\n '
'lastModified\n numUnread\n __typename\n }\n completedFeatureGuides\n '
'useTranslation\n accountStatus {\n isFrozen\n inactiveAfter\n __typename\n '
'}\n __typename\n }\n siteRegion\n chinaHost\n websocketUrl\n userBannedInfo {\n '
'bannedData {\n endAt\n bannedType\n __typename\n }\n __typename\n }\n}\n',
'variables': {},
}
headers = {
@ -83,20 +86,20 @@ class Spider:
'operationName': 'questionData',
'variables': {'titleSlug': question_title_slug},
'query': 'query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n '
'questionId\n questionFrontendId\n categoryTitle\n boundTopicId\n title\n '
'titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n '
'difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n '
'contributors {\n username\n profileUrl\n avatarUrl\n __typename\n '
'}\n langToValidPlayground\n topicTags {\n name\n slug\n '
'translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n '
'lang\n langSlug\n code\n __typename\n }\n stats\n hints\n '
'solution {\n id\n canSeeDetail\n __typename\n }\n status\n '
'sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n '
'enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n '
'source\n shortDescription\n fullDescription\n bookImgUrl\n '
'pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n '
'isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n '
'exampleTestcases\n __typename\n }\n}\n',
'questionId\n questionFrontendId\n categoryTitle\n boundTopicId\n title\n '
'titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n '
'difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n '
'contributors {\n username\n profileUrl\n avatarUrl\n __typename\n '
'}\n langToValidPlayground\n topicTags {\n name\n slug\n '
'translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n '
'lang\n langSlug\n code\n __typename\n }\n stats\n hints\n '
'solution {\n id\n canSeeDetail\n __typename\n }\n status\n '
'sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n '
'enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n '
'source\n shortDescription\n fullDescription\n bookImgUrl\n '
'pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n '
'isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n '
'exampleTestcases\n __typename\n }\n}\n',
}
try:
@ -120,7 +123,11 @@ class Spider:
except Exception as e:
print(e)
time.sleep(2)
return self.get_question_detail(question_title_slug, retry - 1) if retry > 0 else {}
return (
self.get_question_detail(question_title_slug, retry - 1)
if retry > 0
else {}
)
@staticmethod
def format_question_detail(question_detail: dict) -> dict:
@ -149,13 +156,18 @@ class Spider:
'url_en': url_en,
'relative_path_cn': path_cn,
'relative_path_en': path_en,
'title_cn': question_detail.get('translatedTitle') or question_title_en or '',
'title_cn': question_detail.get('translatedTitle')
or question_title_en
or '',
'title_en': question_title_en or '',
'question_title_slug': question_title_slug,
'content_en': question_detail.get('content'),
'content_cn': question_detail.get('translatedContent') or question_detail.get('content') or '',
'content_cn': question_detail.get('translatedContent')
or question_detail.get('content')
or '',
'tags_en': [e['name'] for e in topic_tags if e['name']] or [],
'tags_cn': [e['translatedName'] for e in topic_tags if e['translatedName']] or [],
'tags_cn': [e['translatedName'] for e in topic_tags if e['translatedName']]
or [],
'difficulty_en': question_detail.get('difficulty'),
'difficulty_cn': difficulty.get(question_detail.get('difficulty')),
'code_snippets': question_detail.get('codeSnippets') or [],
@ -187,10 +199,18 @@ class Contest:
def __init__(self, contest_seq: int, contest_type: int = 1):
double = contest_type % 2 == 0
url_pattern = BIWEEKLY_URL if double else WEEKLY_URL
slug_pattern = BIWEEKLY_SLUG if double else WEEKLY_SLUG
self.contest_type = contest_type
self.contest_url = url_pattern.format(contest_seq)
self.contest_title = f'{contest_seq} 场双周赛' if double else f'{contest_seq} 场周赛'
self.contest_title_en = f'Biweekly Contest {contest_seq}' if double else f'Weekly Contest {contest_seq}'
self.contest_title_slug = slug_pattern.format(contest_seq)
self.contest_title = (
f'{contest_seq} 场双周赛' if double else f'{contest_seq} 场周赛'
)
self.contest_title_en = (
f'Biweekly Contest {contest_seq}'
if double
else f'Weekly Contest {contest_seq}'
)
@staticmethod
def format_time(timestamp: int) -> str:
@ -212,7 +232,7 @@ class Contest:
'contest_start_time': res['contest']['origin_start_time'],
'contest_duration': res['contest']['duration'],
'user_num': res['user_num'],
'question_slugs': question_slugs
'question_slugs': question_slugs,
}
except Exception as e:
print(e)
@ -229,27 +249,37 @@ class Contest:
duration = data['contest_duration']
cost_minutes = duration // 60
user_num = data['user_num']
rows = [f'#### {title}({Contest.format_time(start_time)}, {cost_minutes} 分钟) 参赛人数 {user_num}\n']
rows = [
f'#### {title}({Contest.format_time(start_time)}, {cost_minutes} 分钟) 参赛人数 {user_num}\n'
]
rows_en = [f'#### {title_en}\n']
for question in data['question_list']:
frontend_question_id, title_cn, title_en, relative_path_cn, relative_path_en = question
(
frontend_question_id,
title_cn,
title_en,
relative_path_cn,
relative_path_en,
) = question
rows.append(f'- [{frontend_question_id}. {title_cn}]({relative_path_cn})')
rows_en.append(f'- [{frontend_question_id}. {title_en}]({relative_path_en})')
return [
start_time,
'\n'.join(rows),
'\n'.join(rows_en)
]
rows_en.append(
f'- [{frontend_question_id}. {title_en}]({relative_path_en})'
)
return [start_time, '\n'.join(rows), '\n'.join(rows_en)]
def get_contests() -> List:
res = []
def get_contests(fetch_new=True) -> List:
res = [] if fetch_new else load_contest_result()
t = 0
d = {x.get('contest_title_slug'): x for x in res}
for r in (weekly_range, biweekly_range):
t += 1
cnt = 0
for i in r:
contest_data = Contest(i, contest_type=t).get_data(retry=3)
c = Contest(i, contest_type=t)
if c.contest_title_slug in d:
continue
contest_data = c.get_data(retry=3)
if not contest_data:
cnt += 1
if cnt > 2:
@ -257,6 +287,8 @@ def get_contests() -> List:
continue
print(contest_data)
res.append(contest_data)
d[c.contest_title_slug] = contest_data
save_contest_result(res)
return res
@ -265,17 +297,28 @@ def get_contests() -> List:
cookie_cn, cookie_en = load_cookies()
spider = Spider(cookie_cn, cookie_en)
# 题目详情列表
# 是否刷新所有题目
refresh_all = load_refresh_config()
question_details = {}
if not refresh_all:
for item in load_result():
slug = item.get('question_title_slug')
if slug:
question_details[slug] = item
for q in spider.get_all_questions(retry=4):
slug = q['stat']['question__title_slug']
if slug in question_details:
print(f'{slug} 已存在, 跳过')
continue
detail = spider.get_question_detail(slug, retry=4)
time.sleep(0.3)
question_details[slug] = Spider.format_question_detail(detail)
# 周赛场次列表
contest_list = get_contests()
contest_list = get_contests(refresh_all)
cls = []
for contest in contest_list:
contest_title = contest['contest_title']
@ -289,8 +332,13 @@ for contest in contest_list:
detail['md_table_row_en'][4] = contest_title_en
# 给周赛信息添加题目详情
add = [detail['frontend_question_id'], detail['title_cn'],
detail['title_en'], detail['relative_path_cn'], detail['relative_path_en']]
add = [
detail['frontend_question_id'],
detail['title_cn'],
detail['title_en'],
detail['relative_path_cn'],
detail['relative_path_en'],
]
contest_question_list.append(add)
contest['question_list'] = contest_question_list
@ -307,4 +355,5 @@ generate_summary(ls)
generate_contest_readme(cls)
# 刷新题目文件
refresh(ls)
if refresh_all:
refresh(ls)

View File

@ -29,10 +29,12 @@ contest_readme_en = load_template('contest_readme_template_en')
def load_cookies() -> Tuple[str, str]:
cookie_cn, cookie_en = None, None
with open("./.env", "r") as f:
cookie_cn, cookie_en = '', ''
env_file = './.env'
if not os.path.exists(env_file):
return cookie_cn, cookie_en
with open(env_file, "r") as f:
lines = f.readlines()
for line in lines:
if line.startswith("COOKIE_CN"):
parts = line.split("=")[1:]
@ -46,17 +48,49 @@ def load_cookies() -> Tuple[str, str]:
return cookie_cn, cookie_en
def load_refresh_config() -> bool:
env_file = './.env'
if not os.path.exists(env_file):
return False
with open(env_file, "r") as f:
lines = f.readlines()
for line in lines:
if line.startswith("REFRESH"):
parts = line.split("=")[1:]
return "=".join(parts).strip().strip('"') == 'True'
return False
def load_result() -> List[dict]:
with open('./result.json', 'r', encoding='utf-8') as f:
result_file = './result.json'
if not os.path.exists(result_file):
return []
with open(result_file, 'r', encoding='utf-8') as f:
res = f.read()
return json.loads(res)
def load_contest_result() -> List[dict]:
contest_result_file = './contest.json'
if not os.path.exists(contest_result_file):
return []
with open(contest_result_file, 'r', encoding='utf-8') as f:
res = f.read()
if res:
return json.loads(res)
return []
def save_result(data: List[dict]):
with open('./result.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(data))
def save_contest_result(data: List[dict]):
with open('./contest.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(data))
def select_templates(category):
if category == 'Shell':
return [bash_readme_cn, bash_readme_en]
@ -248,4 +282,4 @@ def generate_contest_readme(result: List):
f.write(content_cn)
content_en = contest_readme_en.format(content_en)
with open('./CONTEST_README_EN.md', 'w', encoding='utf-8') as f:
f.write(content_en)
f.write(content_en)