Skip to content

Commit dae6d5a

Browse files
committed
archive: 2025.4.6晚9点半左右
1 parent 264afd8 commit dae6d5a

9 files changed

+360
-12
lines changed

.nodeploy

Whitespace-only changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

Solutions/Other-English-LearningNotes-SomeWords.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,9 @@ categories: [自用]
10831083
|mitten|n. 连指手套|
10841084
|||
10851085
|luxurious|adj. 奢侈的,十分舒适的|
1086+
|||
1087+
|humanitarian|n. 人道主义,慈善家<br/>adj. 人道主义的,慈善的|
1088+
|brook|v. 小河<br/>v. 〈正式〉忍受|
10861089

10871090
<p class="wordCounts">单词收录总数</p>
10881091

WhatCanISay.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!--
2+
* @Author: LetMeFly
3+
* @Date: 2025-04-06 21:23:33
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2025-04-06 21:24:35
6+
-->
7+
我还以为newSolutions.py不兼容Mac,因为生成的题解源码里没有代码
8+
结果发现是代码命名写错了
9+
10+
python testGensolution.py 1863. 找出所有子集的异或总和再求和
11+
['testGensolution.py', '1863.', '找出所有子集的异或总和再求和']
12+
AllProblems/1863.找出所有子集的异或总和再求和.md
13+
https://blog.letmefly.xyz/2025/04/06/LeetCode%201863.%E6%89%BE%E5%87%BA%E6%89%80%E6%9C%89%E5%AD%90%E9%9B%86%E7%9A%84%E5%BC%82%E6%88%96%E6%80%BB%E5%92%8C%E5%86%8D%E6%B1%82%E5%92%8C/
14+
first: 1683
15+
1683 1863 False
16+
first: 1683
17+
1683 1863 False
18+
first: 1683
19+
1683 1863 False
20+
first: 1683
21+
1683 1863 False

test.cpp

Lines changed: 0 additions & 12 deletions
This file was deleted.

testGensolution.py

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
'''
2+
Author: LetMeFly
3+
Date: 2022-07-03 11:21:14
4+
LastEditors: LetMeFly.xyz
5+
LastEditTime: 2025-04-06 21:22:59
6+
Command: python newSolution.py 102. 二叉树的层序遍历
7+
What's more: 当前仅支持数字开头的题目
8+
What's more: 代码结构写的很混乱 - 想单文件实现所有操作
9+
'''
10+
import os
11+
import re
12+
import sys
13+
import json
14+
import time
15+
import datetime
16+
import subprocess
17+
from urllib.parse import quote
18+
19+
20+
argv = sys.argv
21+
print(argv)
22+
23+
num = int(argv[1][:-1])
24+
title = ""
25+
for i in range(2, len(argv)):
26+
if i != 2:
27+
title += " "
28+
title += argv[i]
29+
nameProblem = "AllProblems/{0}.{1}.md".format(num, title)
30+
print(nameProblem)
31+
32+
title = ""
33+
for i in range(2, len(argv)):
34+
title += argv[i]
35+
36+
timeURL = time.strftime("%Y/%m/%d", time.localtime())
37+
solutionURLll = "https://blog.letmefly.xyz/{0}/LeetCode%20{1:04d}.{2}/".format(timeURL, num, quote(title, "utf-8"))
38+
solutionURLll_humanable = "https://blog.letmefly.xyz/{0}/LeetCode {1:04d}.{2}/".format(timeURL, num, title)
39+
print(solutionURLll)
40+
41+
# 获取最后一次commit的sha
42+
def get_latest_commit_sha() -> str:
43+
try:
44+
# 执行 git log 命令获取最后一次提交的 SHA
45+
sha = subprocess.check_output(['git', 'log', '-1', '--pretty=format:%H']).decode('utf-8').strip()
46+
return sha
47+
except subprocess.CalledProcessError as e:
48+
print(f"Error: {e}")
49+
return None
50+
lastSHA = get_latest_commit_sha()
51+
52+
# # 认领issue
53+
# os.system(f'git checkout -b {num}')
54+
# os.system(f'git push --set-upstream origin {num}') # (#832)
55+
def getPlatform():
56+
platform = sys.platform
57+
if platform == 'win32':
58+
return 'Windows'
59+
elif platform == 'darwin':
60+
return 'MacOS'
61+
else:
62+
return 'Linux(or others)'
63+
# issueCreateResult = os.popen(f'gh issue create -t "Who can add 1 more problem of LeetCode {num}" -b "By [newSolution.py](https://github.com/LetMeFly666/LeetCode/blob/{lastSHA}/newSolution.py) using GH on {getPlatform()} " -l "题解" -a "@me"').read()
64+
# print(issueCreateResult)
65+
# issueNum = int(issueCreateResult.split('\n')[0].split('/')[-1])
66+
67+
# input('代码写完后按回车生成题解模板:')
68+
69+
with open(nameProblem, "r", encoding="utf-8") as f:
70+
problem = f.read()
71+
72+
def genSolutionPart(num):
73+
suffix2markdowncode = {
74+
'cpp': ('cpp', 'C++'), # markdown、汉语名
75+
'py': ('python', 'Python'),
76+
'c': ('c', 'C语言'),
77+
'java': ('java', 'Java'),
78+
'go': ('go', 'Go')
79+
}
80+
today4code = []
81+
for file in os.listdir('Codes'):
82+
first = file.split('-')[0]
83+
stop = False
84+
if first == '1683':
85+
input('first: 1683')
86+
stop = True
87+
try:
88+
first = int(first)
89+
except:
90+
pass
91+
if stop:
92+
print(first, num, first == num)
93+
if first != num:
94+
continue
95+
print(file)
96+
with open(os.path.join('Codes', file), 'r', encoding='utf-8') as f:
97+
data = f.read()
98+
time_pattern = re.compile(r"(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})")
99+
match = time_pattern.search(data)
100+
if not match:
101+
print('time not found')
102+
continue
103+
year, month, day, hour, miunte, second = map(int, match.groups())
104+
fileDay = f'{year:04d}-{day:02d}-{month:02d}'
105+
today = datetime.date.today().strftime('%Y-%d-%m')
106+
if fileDay != today:
107+
print(f'{fileDay} != {today}')
108+
continue
109+
today4code.append(os.path.join('Codes', file))
110+
# TODO: 一题两解的支持
111+
result = """
112+
## 解题方法:xx
113+
114+
11111
115+
116+
+ 时间复杂度$O(N^2)$
117+
+ 空间复杂度$O(N\log N)$
118+
119+
### AC代码
120+
"""
121+
for thisFileType in suffix2markdowncode: # 修改题解中的展示顺序为suffix2markdowncode中出现的顺序而不是后缀字典序(复杂度可优化但没必要)
122+
for file in today4code:
123+
fileType = os.path.splitext(file)[-1]
124+
if fileType.startswith('.'):
125+
fileType = fileType[1:]
126+
if fileType != thisFileType:
127+
continue
128+
markdowncode = suffix2markdowncode[fileType]
129+
with open(file, 'r', encoding='utf-8') as f:
130+
data = f.read()
131+
# data = removePrefix(data, fileType) # TODO: 移除前面注释以及其他头部文件
132+
result += f'\n#### {markdowncode[1]}\n\n```{markdowncode[0]}\n{data}\n```\n'
133+
return result
134+
135+
136+
solution = problem + genSolutionPart(num) +"""
137+
> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/--------------------------)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接]({0})哦~
138+
>
139+
> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode)
140+
""".format(solutionURLll) # .format(solutionURLll, solutionURLll_humanable)
141+
142+
def refreshPublistTime(solution: str) -> str:
143+
splited = solution.split("\n")
144+
splited[2] = "date: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
145+
splited.insert(4, 'categories: [题解, LeetCode]')
146+
return "\n".join(splited)
147+
148+
solution = refreshPublistTime(solution)
149+
# print(solution)
150+
151+
exit()
152+
153+
solutionName = "Solutions/LeetCode {0:04d}.{1}.md".format(num, title)
154+
with open(solutionName, "x", encoding="utf-8") as f:
155+
f.write(solution)
156+
157+
print("请编辑题解: “{0}”,注意不要更改文件前5行".format(solutionName))
158+
159+
print("请去掉可能的由其他插件自动生成的头部注释信息,并保存你所编辑的题解")
160+
csdnid = input("请输入CSDN题解文章的id(11022152):")
161+
solutionURLcs = "https://letmefly.blog.csdn.net/article/details/{0}".format(csdnid)
162+
163+
with open(solutionName, "r", encoding="utf-8") as f:
164+
solution = f.read()
165+
166+
solution = solution.replace("--------------------------", csdnid)
167+
# solution = solution.replace("--------------------------", csdnid)
168+
169+
with open(solutionName, "w", encoding="utf-8") as f:
170+
f.write(solution)
171+
172+
print("请重新复制所有的题解内容,并粘贴到CSDN中发布")
173+
print("请在LeetCode中新建、编辑并发布题解")
174+
175+
solutionURLlc = input("LeetCode题解的url: ")
176+
177+
with open("README.md", "r", encoding="utf-8") as f:
178+
readme = f.read()
179+
180+
def readmeNewLine(readme: str) -> str:
181+
splited = readme.split("\n")
182+
def getTiJieBeginEnd(splited: list) -> tuple:
183+
begin, end = 0, 0
184+
for i in range(len(splited)):
185+
if splited[i] == "|题目名称|困难程度|题目地址|题解地址|CSDN题解|LeetCode题解|":
186+
begin = i + 2
187+
lineSplited = splited[i].split("|")
188+
if begin and i >= begin:
189+
if not ord('0') <= ord(lineSplited[1][0]) <= ord('9'):
190+
end = i
191+
break
192+
return (begin, end)
193+
beginLine, endLine = getTiJieBeginEnd(splited)
194+
print(beginLine, endLine)
195+
haveBigger = False
196+
for i in range(beginLine, endLine):
197+
thisNum = int(splited[i].split("|")[1].split(".")[0])
198+
if thisNum > num:
199+
haveBigger = True
200+
break
201+
if not haveBigger:
202+
i = endLine
203+
def generateNewLine():
204+
def getHard():
205+
solutionSplited = solution.split("\n")
206+
tags = solutionSplited[3]
207+
realTags = tags.split("tags: [")[1][:-1].split(", ")
208+
if "简单" in realTags:
209+
return "简单"
210+
elif "中等" in realTags:
211+
return "中等"
212+
elif "困难" in realTags:
213+
return "困难"
214+
else:
215+
return input("自动获取难易程度失败!请手动输入[简单/中等/困难]并检查代码: ")
216+
def getProblemUrl():
217+
tempUrl = solutionURLlc
218+
if tempUrl[len(tempUrl) - 1] != '/':
219+
tempUrl += "/"
220+
splitedUrl = tempUrl.split("/")
221+
del splitedUrl[len(splitedUrl) - 2]
222+
del splitedUrl[len(splitedUrl) - 2]
223+
del splitedUrl[len(splitedUrl) - 2] # solutions
224+
return "/".join(splitedUrl)
225+
return """|{0:04d}.{1}|{2}|<a href="{3}" target="_blank">题目地址</a>|<a href="{4}" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/{5}" target="_blank">CSDN题解</a>|<a href="{6}" target="_blank">LeetCode题解</a>|""".format(num, title, getHard(), getProblemUrl(), solutionURLll, csdnid, solutionURLlc)
226+
splited.insert(i, generateNewLine())
227+
return "\n".join(splited)
228+
229+
readme = readmeNewLine(readme)
230+
print(readme)
231+
with open("README.md", "w", encoding="utf-8") as f:
232+
f.write(readme)
233+
234+
# commit push pr merge delete-branch
235+
os.system('git add .')
236+
def getPrOrIssueMaxNum(prOrIssue: str) -> int: # (#811)
237+
print(f'max {prOrIssue} number:', end=' ')
238+
sys.stdout.flush()
239+
cmd = ['gh', prOrIssue, 'list', '--state', 'all', '--limit', '1', '--json', 'number']
240+
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
241+
data = json.loads(result.stdout)
242+
print(data)
243+
return data[0]['number']
244+
lastNum = max(getPrOrIssueMaxNum('pr'), getPrOrIssueMaxNum('issue'))
245+
print(lastNum)
246+
commitMsg = f'update: 添加问题“{num}.{title}”的代码和题解(#{lastNum + 1})'
247+
if os.path.exists('.commitmsg') and os.path.isfile('.commitmsg'): # (#795)
248+
with open('.commitmsg', 'r', encoding='utf-8') as f:
249+
commitMsgFromfile = f.read()
250+
if not commitMsgFromfile.startswith('\n'):
251+
commitMsgFromfile = '\n' + commitMsgFromfile
252+
commitMsg += commitMsgFromfile
253+
subprocess.run(['git', 'commit', '-s', '-m', commitMsg]) # os.system('git commit -s -m "{msg}"')的话没法评论多行
254+
os.system(f'git push --set-upstream origin {num}')
255+
cmd = f'gh pr create -t "添加问题“{num}.{title}”的代码和题解" -b "By [newSolution.py](https://github.com/LetMeFly666/LeetCode/blob/{lastSHA}/newSolution.py) using GH on {getPlatform()} | close: #{issueNum}" -l "题解" -a "@me"'
256+
prResult = os.popen(cmd).read()
257+
print(prResult)
258+
prNumber = int(prResult.split('/')[-1])
259+
os.system('gh pr edit --add-label "under merge"')
260+
input('enter when ready to merge:') # 万一给带密码的东西merge了就无法恢复了(虽然这个仓库一次都没有过)
261+
os.system('gh pr edit --remove-label "under merge"')
262+
# os.system(f'gh pr merge {prNumber} -r -d') # rebase没有verified的标,且sha也不一样
263+
def get_commit_diff():
264+
# 获取题解分支比master多出的提交次数
265+
try:
266+
count = int(subprocess.check_output(
267+
['git', 'rev-list', '--count', f'master..{num}'],
268+
stderr=subprocess.DEVNULL # 屏蔽错误输出
269+
).decode().strip())
270+
except subprocess.CalledProcessError:
271+
print("无法获取提交差异,请确认分支存在")
272+
return 1
273+
return count
274+
commitCount = get_commit_diff()
275+
if commitCount < 2: # 直接本地merge,即不是rebase又减少一次merge记录 | 这个merge大概不会产生冲突
276+
os.system(f'git switch master')
277+
os.system(f'git merge {num}')
278+
os.system(f'git push')
279+
os.system(f'git branch -d {num}')
280+
os.system(f'git push --delete origin {num}')
281+
else: # 使用gh在github上通过squash的方式merge | 在本地squash merge并push的话github无法自动识别并关闭pr
282+
os.system(f'gh pr merge -s -d -t "update: 添加问题“{num}.{title}”的代码和题解(#{prNumber})"')
283+
# https://github.com/LetMeFly666/LeetCode/blob/3435204860a8a85aa666618d90f40916dc70a1f1/reassign.py
284+
def syncGitcodeCSDN():
285+
nowCWD = os.getcwd()
286+
os.chdir('OtherSource/gitcode_knowledge')
287+
os.system('git pull --force')
288+
# 判断一个commit是否按配置签名
289+
def verify_commit(commit_hash: str) -> bool:
290+
result = subprocess.run(
291+
['git', 'verify-commit', commit_hash],
292+
stdout=subprocess.PIPE,
293+
stderr=subprocess.PIPE,
294+
)
295+
return not result.returncode
296+
# 获取一个commit的上一个commit
297+
def get_parent_commit(commit_hash: str) -> str:
298+
result = subprocess.run(
299+
['git', 'log', commit_hash, '--pretty=%H', '-n', '2'],
300+
stdout=subprocess.PIPE,
301+
stderr=subprocess.PIPE,
302+
)
303+
return result.stdout.decode('utf-8').strip().split()[-1]
304+
# 将从某次commit开始至HEAD的所有commit重新签名
305+
def re_assign(commit_hash: str) -> None:
306+
# cmd = f'git filter-branch -f --commit-filter \'git commit-tree -S "$@";\' {commit_hash}..HEAD'
307+
# print(cmd)
308+
# os.system(cmd)
309+
env = os.environ.copy()
310+
env['FILTER_BRANCH_SQUELCH_WARNING'] = "1"
311+
result = subprocess.run(
312+
["git", "filter-branch", "-f", "--commit-filter", 'git commit-tree -S "$@";', f"{commit_hash}..HEAD"],
313+
env=env,
314+
)
315+
print(result.returncode)
316+
# subprocess.Popen(cmd)
317+
def re_assign_main():
318+
# re_assign('HEAD~2')
319+
# return
320+
if verify_commit('HEAD'): # HEAD的签名也能被验证
321+
return
322+
notVerified = 'HEAD'
323+
while True:
324+
next = get_parent_commit(notVerified)
325+
if next == notVerified:
326+
break
327+
notVerified = next
328+
if verify_commit(next):
329+
break
330+
print(notVerified)
331+
re_assign(notVerified)
332+
re_assign_main()
333+
os.system('git push --force') # resign gitcode
334+
os.system('git push Let main:From_GitCode_CSDN')
335+
os.chdir(nowCWD)
336+
syncGitcodeCSDN()

0 commit comments

Comments
 (0)