Skip to content

Commit 2eb9283

Browse files
committed
Merge branch 'dev' into feature-test
2 parents b9fe2d0 + 2b5d8fd commit 2eb9283

12 files changed

+521
-192
lines changed

Readme.md

+10-8
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,23 @@
99

1010
#### 优先级高
1111

12-
- [ ] 获取更完备的测试用例,增强用户体验
13-
- [ ] 获取题解和代码
1412
- [ ] commit到leetcode
15-
- [ ] 私人项目部署的实现方案
13+
- [ ] 使用realm进行持久化,替换store.json
14+
- [ ] 实现lk/lf/lc指令的封装
1615

1716
#### 优先级中
1817

19-
- [ ] 创建一个单独指令lc,用于项目的单独指令,忽略npm/yarn/pnpm的执行差异/歧义
18+
- [ ] 获取题解和代码
19+
- [ ] 获取更完备的测试用例,增强用户体验
20+
- [ ] 实现docker部署
2021

2122
#### 优先级低
2223

23-
- [ ] 实现在编辑器中预览图片(感觉可以不做)
24-
2524
#### 代码优化及基础建设
2625

2726
- [ ] 优化随机题目的随机方式,减少请求
28-
- [ ] commonJS -> ES6 Module
29-
- [ ] 优化src下代码结构
3027
- [ ] 封装npm包,方便后续做成编辑器插件
28+
- [ ] 重构工具代码,对UI和logic进行解耦
3129

3230
### 已完归档
3331

@@ -39,6 +37,10 @@
3937
- [x] 6.特殊数据结构的处理(链表ListNode,树TreeNode,无向连通图Node)的处理
4038
- [x] 7.创建某一特定编号的题目脚本,以及实现随机题目【随机题目汇集本地题目,然后排除自己本地存在的题目进行随机】
4139
- [x] 8.加入eslint
40+
- [x] 私人项目部署的实现方案
41+
- [x] commonJS -> ES6 Module
42+
- [x] 实现在编辑器中预览图片(markdown中可以查看)
43+
4244

4345
## How to use for yourself ?
4446

bin/lc-enter.js

-9
This file was deleted.

bin/lc.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#! /usr/bin/env node
2+
import {program} from "commander";
3+
4+
program
5+
.version('1.0.0')
6+
.description(`
7+
8+
░▒▓█▓▒░ ░▒▓████████▓▒░▒▓████████▓▒░▒▓████████▓▒░▒▓██████▓▒░ ░▒▓██████▓▒░░▒▓███████▓▒░░▒▓████████▓▒░ ░▒▓███████▓▒░░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓████████▓▒░
9+
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░
10+
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░
11+
░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓██████▓▒░ ░▒▓███████▓▒░░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓██████▓▒░
12+
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░
13+
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░
14+
░▒▓████████▓▒░▒▓████████▓▒░▒▓████████▓▒░ ░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓██████▓▒░░▒▓███████▓▒░░▒▓████████▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓██████▓▒░░▒▓████████▓▒░
15+
16+
17+
LeetCode Practice CLI`)
18+
.argument('<string>', 'Default to get this identity.')
19+
.option('-i, --identity <identity>', 'Specify a question by identity.')
20+
.option('-r, --random', 'Get a question randomly.')
21+
.option('-t, --today', 'Get a question today.')
22+
.parse(process.argv);
23+
// program.
24+
// examples(`
25+
// $ lc
26+
// $ lc 1314
27+
// $ lc -i 1314
28+
// $ lc -r
29+
// $ lc -t
30+
// `)
31+
const args = program.args;
32+
const opts = program.opts();
33+
console.log("[args]",args)
34+
console.log("[opts]",opts)
35+
36+
const getCase = (args,opts)=>{
37+
return 'today'
38+
}
39+
40+
const rules = {
41+
'today':(args,opts)=>{},
42+
'random':(args,opts)=>{},
43+
'identity':(args,opts)=>{},
44+
}
45+
46+
// 执行指令分发
47+
const current = getCase(args,opts);
48+
rules[current](args,opts);

bin/lf.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#! /usr/bin/env node

bin/lk-enter.js bin/lk.js

File renamed without changes.

common/resources/store.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"today":"2182","today-question-info":{"enName":"jump-game-vi","title":"跳跃游戏 VI","detail":"<p>给你一个下标从 <strong>0</strong> 开始的整数数组 <code>nums</code> 和一个整数 <code>k</code> 。</p>\n\n<p>一开始你在下标 <code>0</code> 处。每一步,你最多可以往前跳 <code>k</code> 步,但你不能跳出数组的边界。也就是说,你可以从下标 <code>i</code> 跳到 <code>[i + 1, min(n - 1, i + k)]</code> <strong>包含</strong> 两个端点的任意位置。</p>\n\n<p>你的目标是到达数组最后一个位置(下标为 <code>n - 1</code> ),你的 <strong>得分</strong> 为经过的所有数字之和。</p>\n\n<p>请你返回你能得到的 <strong>最大得分</strong> 。</p>\n\n<p> </p>\n\n<p><strong>示例 1:</strong></p>\n\n<pre>\n<b>输入:</b>nums = [<strong>1</strong>,<strong>-1</strong>,-2,<strong>4</strong>,-7,<strong>3</strong>], k = 2\n<b>输出:</b>7\n<b>解释:</b>你可以选择子序列 [1,-1,4,3] (上面加粗的数字),和为 7 。\n</pre>\n\n<p><strong>示例 2:</strong></p>\n\n<pre>\n<strong>输入:</strong>nums = [<strong>10</strong>,-5,-2,<strong>4</strong>,0,<strong>3</strong>], k = 3\n<b>输出:</b>17\n<b>解释:</b>你可以选择子序列 [10,4,3] (上面加粗数字),和为 17 。\n</pre>\n\n<p><strong>示例 3:</strong></p>\n\n<pre>\n<b>输入:</b>nums = [1,-5,-20,4,-1,3,-6,-3], k = 2\n<b>输出:</b>0\n</pre>\n\n<p> </p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li> <code>1 <= nums.length, k <= 10<sup>5</sup></code></li>\n\t<li><code>-10<sup>4</sup> <= nums[i] <= 10<sup>4</sup></code></li>\n</ul>\n","id":"1696","jsCode":"/**\n * @param {number[]} nums\n * @param {number} k\n * @return {number}\n */\nvar maxResult = function(nums, k) {\n\n};","date":"2024-02-05"},"today-tag":"82","random-id":1314,"random-question-info":{"enName":"multiply-strings","title":"字符串相乘","detail":"<p>给定两个以字符串形式表示的非负整数&nbsp;<code>num1</code>&nbsp;和&nbsp;<code>num2</code>,返回&nbsp;<code>num1</code>&nbsp;和&nbsp;<code>num2</code>&nbsp;的乘积,它们的乘积也表示为字符串形式。</p>\n\n<p><strong>注意:</strong>不能使用任何内置的 BigInteger 库或直接将输入转换为整数。</p>\n\n<p>&nbsp;</p>\n\n<p><strong>示例 1:</strong></p>\n\n<pre>\n<strong>输入:</strong> num1 = \"2\", num2 = \"3\"\n<strong>输出:</strong> \"6\"</pre>\n\n<p><strong>示例&nbsp;2:</strong></p>\n\n<pre>\n<strong>输入:</strong> num1 = \"123\", num2 = \"456\"\n<strong>输出:</strong> \"56088\"</pre>\n\n<p>&nbsp;</p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li><code>1 &lt;= num1.length, num2.length &lt;= 200</code></li>\n\t<li><code>num1</code>&nbsp;和 <code>num2</code>&nbsp;只能由数字组成。</li>\n\t<li><code>num1</code>&nbsp;和 <code>num2</code>&nbsp;都不包含任何前导零,除了数字0本身。</li>\n</ul>\n","id":"43","jsCode":"/**\n * @param {string} num1\n * @param {string} num2\n * @return {string}\n */\nvar multiply = function(num1, num2) {\n\n};"},"specified-question-info":{"enName":"design-add-and-search-words-data-structure","title":"添加与搜索单词 - 数据结构设计","detail":"<p>请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。</p>\n\n<p>实现词典类 <code>WordDictionary</code> :</p>\n\n<ul>\n\t<li><code>WordDictionary()</code> 初始化词典对象</li>\n\t<li><code>void addWord(word)</code> 将 <code>word</code> 添加到数据结构中,之后可以对它进行匹配</li>\n\t<li><code>bool search(word)</code> 如果数据结构中存在字符串与&nbsp;<code>word</code> 匹配,则返回 <code>true</code> ;否则,返回&nbsp; <code>false</code> 。<code>word</code> 中可能包含一些 <code>'.'</code> ,每个&nbsp;<code>.</code> 都可以表示任何一个字母。</li>\n</ul>\n\n<p>&nbsp;</p>\n\n<p><strong>示例:</strong></p>\n\n<pre>\n<strong>输入:</strong>\n[\"WordDictionary\",\"addWord\",\"addWord\",\"addWord\",\"search\",\"search\",\"search\",\"search\"]\n[[],[\"bad\"],[\"dad\"],[\"mad\"],[\"pad\"],[\"bad\"],[\".ad\"],[\"b..\"]]\n<strong>输出:</strong>\n[null,null,null,null,false,true,true,true]\n\n<strong>解释:</strong>\nWordDictionary wordDictionary = new WordDictionary();\nwordDictionary.addWord(\"bad\");\nwordDictionary.addWord(\"dad\");\nwordDictionary.addWord(\"mad\");\nwordDictionary.search(\"pad\"); // 返回 False\nwordDictionary.search(\"bad\"); // 返回 True\nwordDictionary.search(\".ad\"); // 返回 True\nwordDictionary.search(\"b..\"); // 返回 True\n</pre>\n\n<p>&nbsp;</p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li><code>1 &lt;= word.length &lt;= 25</code></li>\n\t<li><code>addWord</code> 中的 <code>word</code> 由小写英文字母组成</li>\n\t<li><code>search</code> 中的 <code>word</code> 由 '.' 或小写英文字母组成</li>\n\t<li>最多调用 <code>10<sup>4</sup></code> 次 <code>addWord</code> 和 <code>search</code></li>\n</ul>\n","id":"211","jsCode":"\nvar WordDictionary = function() {\n\n};\n\n/** \n * @param {string} word\n * @return {void}\n */\nWordDictionary.prototype.addWord = function(word) {\n\n};\n\n/** \n * @param {string} word\n * @return {boolean}\n */\nWordDictionary.prototype.search = function(word) {\n\n};\n\n/**\n * Your WordDictionary object will be instantiated and called as such:\n * var obj = new WordDictionary()\n * obj.addWord(word)\n * var param_2 = obj.search(word)\n */"}}
1+
{"today":"2182","today-question-info":{"enName":"p0NxJO","title":"魔塔游戏","detail":"小扣当前位于魔塔游戏第一层,共有 `N` 个房间,编号为 `0 ~ N-1`。每个房间的补血道具/怪物对于血量影响记于数组 `nums`,其中正数表示道具补血数值,即血量增加对应数值;负数表示怪物造成伤害值,即血量减少对应数值;`0` 表示房间对血量无影响。\n\n**小扣初始血量为 1,且无上限**。假定小扣原计划按房间编号升序访问所有房间补血/打怪,**为保证血量始终为正值**,小扣需对房间访问顺序进行调整,**每次仅能将一个怪物房间(负数的房间)调整至访问顺序末尾**。请返回小扣最少需要调整几次,才能顺利访问所有房间。若调整顺序也无法访问完全部房间,请返回 -1。\n\n\n**示例 1:**\n>输入:`nums = [100,100,100,-250,-60,-140,-50,-50,100,150]`\n>\n>输出:`1`\n>\n>解释:初始血量为 1。至少需要将 nums[3] 调整至访问顺序末尾以满足要求。\n\n**示例 2:**\n>输入:`nums = [-200,-300,400,0]`\n>\n>输出:`-1`\n>\n>解释:调整访问顺序也无法完成全部房间的访问。\n\n**提示:**\n- `1 <= nums.length <= 10^5`\n- `-10^5 <= nums[i] <= 10^5`","id":"LCP 30","jsCode":"/**\n * @param {number[]} nums\n * @return {number}\n */\nvar magicTower = function(nums) {\n\n};","date":"2024-02-06"},"today-tag":"82","random-id":1314,"random-question-info":{"enName":"multiply-strings","title":"字符串相乘","detail":"<p>给定两个以字符串形式表示的非负整数&nbsp;<code>num1</code>&nbsp;和&nbsp;<code>num2</code>,返回&nbsp;<code>num1</code>&nbsp;和&nbsp;<code>num2</code>&nbsp;的乘积,它们的乘积也表示为字符串形式。</p>\n\n<p><strong>注意:</strong>不能使用任何内置的 BigInteger 库或直接将输入转换为整数。</p>\n\n<p>&nbsp;</p>\n\n<p><strong>示例 1:</strong></p>\n\n<pre>\n<strong>输入:</strong> num1 = \"2\", num2 = \"3\"\n<strong>输出:</strong> \"6\"</pre>\n\n<p><strong>示例&nbsp;2:</strong></p>\n\n<pre>\n<strong>输入:</strong> num1 = \"123\", num2 = \"456\"\n<strong>输出:</strong> \"56088\"</pre>\n\n<p>&nbsp;</p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li><code>1 &lt;= num1.length, num2.length &lt;= 200</code></li>\n\t<li><code>num1</code>&nbsp;和 <code>num2</code>&nbsp;只能由数字组成。</li>\n\t<li><code>num1</code>&nbsp;和 <code>num2</code>&nbsp;都不包含任何前导零,除了数字0本身。</li>\n</ul>\n","id":"43","jsCode":"/**\n * @param {string} num1\n * @param {string} num2\n * @return {string}\n */\nvar multiply = function(num1, num2) {\n\n};"},"specified-question-info":{"enName":"design-add-and-search-words-data-structure","title":"添加与搜索单词 - 数据结构设计","detail":"<p>请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。</p>\n\n<p>实现词典类 <code>WordDictionary</code> :</p>\n\n<ul>\n\t<li><code>WordDictionary()</code> 初始化词典对象</li>\n\t<li><code>void addWord(word)</code> 将 <code>word</code> 添加到数据结构中,之后可以对它进行匹配</li>\n\t<li><code>bool search(word)</code> 如果数据结构中存在字符串与&nbsp;<code>word</code> 匹配,则返回 <code>true</code> ;否则,返回&nbsp; <code>false</code> 。<code>word</code> 中可能包含一些 <code>'.'</code> ,每个&nbsp;<code>.</code> 都可以表示任何一个字母。</li>\n</ul>\n\n<p>&nbsp;</p>\n\n<p><strong>示例:</strong></p>\n\n<pre>\n<strong>输入:</strong>\n[\"WordDictionary\",\"addWord\",\"addWord\",\"addWord\",\"search\",\"search\",\"search\",\"search\"]\n[[],[\"bad\"],[\"dad\"],[\"mad\"],[\"pad\"],[\"bad\"],[\".ad\"],[\"b..\"]]\n<strong>输出:</strong>\n[null,null,null,null,false,true,true,true]\n\n<strong>解释:</strong>\nWordDictionary wordDictionary = new WordDictionary();\nwordDictionary.addWord(\"bad\");\nwordDictionary.addWord(\"dad\");\nwordDictionary.addWord(\"mad\");\nwordDictionary.search(\"pad\"); // 返回 False\nwordDictionary.search(\"bad\"); // 返回 True\nwordDictionary.search(\".ad\"); // 返回 True\nwordDictionary.search(\"b..\"); // 返回 True\n</pre>\n\n<p>&nbsp;</p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li><code>1 &lt;= word.length &lt;= 25</code></li>\n\t<li><code>addWord</code> 中的 <code>word</code> 由小写英文字母组成</li>\n\t<li><code>search</code> 中的 <code>word</code> 由 '.' 或小写英文字母组成</li>\n\t<li>最多调用 <code>10<sup>4</sup></code> 次 <code>addWord</code> 和 <code>search</code></li>\n</ul>\n","id":"211","jsCode":"\nvar WordDictionary = function() {\n\n};\n\n/** \n * @param {string} word\n * @return {void}\n */\nWordDictionary.prototype.addWord = function(word) {\n\n};\n\n/** \n * @param {string} word\n * @return {boolean}\n */\nWordDictionary.prototype.search = function(word) {\n\n};\n\n/**\n * Your WordDictionary object will be instantiated and called as such:\n * var obj = new WordDictionary()\n * obj.addWord(word)\n * var param_2 = obj.search(word)\n */"}}

common/scripts/check.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
*/
44
import {temExe} from "#common/utils/temExe.js";
55
import {readStore} from "#common/utils/store.js";
6+
import path from "path";
7+
import {parseFilePath} from "#common/utils/parseFilePath.js";
68
const args = process.argv.slice(2);
79
let name;
810
switch (args[0]) {
@@ -32,6 +34,7 @@ switch (args[0]) {
3234
}
3335
break;
3436
}
35-
temExe('node ./src/{0}/index.js', name)
37+
const filePath = parseFilePath(`./src/${name}/index.js`);
38+
temExe('node {0}',filePath)
3639
.then(res => console.log(`执行结果:\n${res}`))
3740
.catch(e => console.log("执行报错: ", e));

common/scripts/test.js

-5
This file was deleted.

common/utils/parseFilePath.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import path from "path";
2+
export function parseFilePath(oldPath){
3+
return `\"${path.normalize(oldPath)}\"`;
4+
}

package.json

+9-7
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
"#common/*": "./common/*"
99
},
1010
"bin": {
11-
"lc": "./bin/lc-enter.js",
12-
"lk": "./bin/lk-enter.js"
11+
"lk": "bin/lk.js",
12+
"lf": "bin/lf.js",
13+
"lc": "bin/lc.js"
1314
},
1415
"scripts": {
1516
"leet-create": "node common/scripts/create.js",
@@ -23,20 +24,21 @@
2324
"author": "EternalHeart",
2425
"license": "ISC",
2526
"dependencies": {
26-
"commitizen": "^4.3.0",
27-
"cz-conventional-changelog": "^3.3.0",
27+
"commander": "^12.0.0",
28+
"inquirer": "^9.2.14",
2829
"jsdom": "^23.2.0",
29-
"vite": "^5.0.11"
30+
"realm": "^12.6.0"
3031
},
3132
"devDependencies": {
3233
"@types/node": "^20.11.5",
3334
"@vitest/coverage-v8": "^1.2.2",
35+
"commitizen": "^4.3.0",
36+
"cz-conventional-changelog": "^3.3.0",
3437
"eslint": "^8.56.0",
3538
"eslint-config-airbnb-base": "^15.0.0",
3639
"eslint-plugin-import": "^2.29.1",
37-
"inquirer": "^9.2.14",
3840
"rimraf": "^5.0.5",
39-
"shelljs": "^0.8.5",
41+
"vite": "^5.0.11",
4042
"vitest": "^1.2.2"
4143
},
4244
"config": {

0 commit comments

Comments
 (0)