From 6cad601a0c8b644f46e38225abec6868a46cbd65 Mon Sep 17 00:00:00 2001 From: sudo Date: Thu, 1 Jul 2021 22:48:55 +0800 Subject: [PATCH 01/77] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=90=8D=E4=B8=AD=E7=9A=84=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main.cpp" | 0 .../solution.h" | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename "questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" => "questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" (100%) rename "questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/solution.h" => "questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/solution.h" (100%) diff --git "a/questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" "b/questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" similarity index 100% rename from "questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" rename to "questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/main.cpp" diff --git "a/questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/solution.h" "b/questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/solution.h" similarity index 100% rename from "questions/815. \345\205\254\344\272\244\350\267\257\347\272\277/solution.h" rename to "questions/815.\345\205\254\344\272\244\350\267\257\347\272\277/solution.h" -- Gitee From 7a3ec0027003ba8f144e440c3d78847cc3a4e439 Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 2 Jul 2021 22:06:51 +0800 Subject: [PATCH 02/77] =?UTF-8?q?leetcode-1833.=E9=9B=AA=E7=B3=95=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++- include/sort.h | 26 +++++++++++++++++++ .../main.cpp" | 22 ++++++++++++++++ .../solution.h" | 16 ++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 include/sort.h create mode 100644 "questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/main.cpp" create mode 100644 "questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/solution.h" diff --git a/README.md b/README.md index 8402c5f..212068f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # leetcode ## BFS -[815. 公交路线](https://leetcode-cn.com/problems/bus-routes/) \ No newline at end of file +[815. 公交路线](https://leetcode-cn.com/problems/bus-routes/) + +## 贪心算法 +[1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) diff --git a/include/sort.h b/include/sort.h new file mode 100644 index 0000000..3e032a9 --- /dev/null +++ b/include/sort.h @@ -0,0 +1,26 @@ +#pragma once + +template +void QuickSort(Iterator begin, Iterator end){ + if(end <= begin) return; + auto low = begin, high = end; + auto key = *begin; + while(low < high){ + while(key<*high && low +void QuickSort(Container & a){ + QuickSort(std::begin(a), std::end(a)-1); +} diff --git "a/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/main.cpp" "b/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/main.cpp" new file mode 100644 index 0000000..174f568 --- /dev/null +++ "b/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/main.cpp" @@ -0,0 +1,22 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + std::vector costs = { +// 1,3,2,4,1 +// 10,6,8,7,7,8 +27,23,33,26,46,86,70,85,89,82,57,66,42,18,18,5,46,56,42,82,52,78,4,27,96,74,74,52,2,24,78,18,42,10,12,10,80,30,60,38,32,7,98,26,18,62,50,42,15,14,32,86,93,98,47,46,58,42,74,69,51,53,58,40,66,46,65,2,10,82,94,26,6,78,2,101,97,16,12,18,71,5,46,22,58,12,18,62,61,51,2,18,34,12,36,58,20,12,17,70 + }; + int coins = +// 7 +// 5 + 241 + ; + Solution sln; + int max = sln.maxIceCream(costs, coins); + print("costs=", costs) + print("\ncoin=", coins) + print("\nmax=", max) + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/solution.h" "b/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/solution.h" new file mode 100644 index 0000000..9cbc0af --- /dev/null +++ "b/questions/1833.\351\233\252\347\263\225\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217/solution.h" @@ -0,0 +1,16 @@ +// #define print(...) +#include "sort.h" + +class Solution { +public: + int maxIceCream(vector& costs, int coins) { + QuickSort(costs); + int cnt = 0; + while(cnt Date: Sat, 3 Jul 2021 11:56:35 +0800 Subject: [PATCH 03/77] =?UTF-8?q?leetcode-5.=E6=9C=80=E9=95=BF=E5=9B=9E?= =?UTF-8?q?=E6=96=87=E5=AD=90=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++ .../main.cpp" | 19 +++++++++++ .../solution.h" | 32 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 "questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/main.cpp" create mode 100644 "questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/solution.h" diff --git a/README.md b/README.md index 212068f..47a4ec1 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,6 @@ ## 贪心算法 [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) + +## 动态规则 +[5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git "a/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/main.cpp" "b/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/main.cpp" new file mode 100644 index 0000000..cb67f61 --- /dev/null +++ "b/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string str[] ={ + "babad", + "cbbd", + "a", + "ac", + "bb", + }; + Solution sln; + for(auto & s : str){ + auto dp = sln.longestPalindrome(s); + print("string=", s, "\npalind:", dp, "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/solution.h" "b/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/solution.h" new file mode 100644 index 0000000..d6ad5e3 --- /dev/null +++ "b/questions/5.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/solution.h" @@ -0,0 +1,32 @@ +// #define print(...) + +#define DP(i,j) ( (i)>(j) ? dp[(1+(i))*(i)/2+(j)] : dp[(1+(j))*(j)/2+(i)] ) + +class Solution { +public: + string longestPalindrome(string s) { + auto N = s.size(); + if(N < 2) return s; + vector dp((1+N)*N/2, false); + // 单字符是回文串 + for(int i=0; imaxlen){ + maxlen = len; + begin = i; + } + } + } + return s.substr(begin, maxlen); + } +}; -- Gitee From 5c173bc3f55042a3cadedf0a0ffc0daba2fe25f9 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 3 Jul 2021 20:30:59 +0800 Subject: [PATCH 04/77] =?UTF-8?q?leetcode-451.=E6=A0=B9=E6=8D=AE=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E5=87=BA=E7=8E=B0=E9=A2=91=E7=8E=87=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../main.cpp" | 17 ++++++++++++++ .../solution.h" | 23 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 "questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/main.cpp" create mode 100644 "questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/solution.h" diff --git a/README.md b/README.md index 47a4ec1..b56bc8c 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ ## 动态规则 [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) + +## 排序 +[451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 diff --git "a/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/main.cpp" "b/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/main.cpp" new file mode 100644 index 0000000..a72f76d --- /dev/null +++ "b/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/main.cpp" @@ -0,0 +1,17 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + Solution sln; + string tests[] = { + "tree", + "cccaaa", + "Aabb", + }; + for(auto &s: tests){ + print("stri=", s, "\nsort:", + sln.frequencySort(s), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/solution.h" "b/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/solution.h" new file mode 100644 index 0000000..dd4e4de --- /dev/null +++ "b/questions/451.\346\240\271\346\215\256\345\255\227\347\254\246\345\207\272\347\216\260\351\242\221\347\216\207\346\216\222\345\272\217/solution.h" @@ -0,0 +1,23 @@ +// #define print(...) + +class Solution { +public: + string frequencySort(string s) { + map counter; + int maxLen = 0; + for(auto & c : s){ + maxLen = max(++counter[c], maxLen); + } + + vector bucket(maxLen, ""); + for(auto &[c,n] : counter) + bucket[n-1].append(1, c); + + string sorted; + for(int n=maxLen; n>0; n--){ + for(auto c:bucket[n-1]) + sorted.insert(sorted.end(), n, c); + } + return sorted; + } +}; -- Gitee From bd2c05c4be16e057ccd6492efbf6fb2bc98823c2 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 3 Jul 2021 22:04:02 +0800 Subject: [PATCH 05/77] =?UTF-8?q?leetcode-6.Z=E5=AD=97=E5=BD=A2=E5=8F=98?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../main.cpp" | 18 +++++++++++++ .../solution.h" | 27 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 "questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/main.cpp" create mode 100644 "questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/solution.h" diff --git a/README.md b/README.md index b56bc8c..ed3158f 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,6 @@ ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 + +## 字符串 +[6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/main.cpp" "b/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/main.cpp" new file mode 100644 index 0000000..358c211 --- /dev/null +++ "b/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string strs[] = { + "PAYPALISHIRING", + };int numRows[] = { + 3, + }; + + Solution sln; + for(int i = 0; i < std::size(strs); i++){ + print("str=", strs[i], "\nres:", + sln.convert(strs[i], numRows[i]), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/solution.h" "b/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/solution.h" new file mode 100644 index 0000000..41a0b3e --- /dev/null +++ "b/questions/6.Z\345\255\227\345\275\242\345\217\230\346\215\242/solution.h" @@ -0,0 +1,27 @@ +// #define print(...) +class Solution { +public: + string convert(string s, int numRows) { + int nRow = min((int)s.size(), numRows); + if(nRow==1) return s; + + vector rows(nRow); + auto it = rows.begin(); + it->reserve(s.size()); + while(++it != rows.end()) it->reserve(s.size()/nRow+1); + + int i=0, step=-1; + for(auto &c:s){ + rows[i].append(1, c); + if(0==i || i==nRow-1) + step = -step; + i += step; + } + + auto rs = rows.begin(); + for(auto it=rs+1; it != rows.end(); it++){ + rs->insert(rs->end(), it->begin(), it->end()); + } + return *rs; + } +}; -- Gitee From 11639cb0d8158a4a561e8bf72a9bed52532dd276 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 3 Jul 2021 22:41:21 +0800 Subject: [PATCH 06/77] =?UTF-8?q?leetcode-7.=E6=95=B4=E6=95=B0=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../main.cpp" | 18 ++++++++++++++++++ .../solution.h" | 15 +++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 "questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/main.cpp" create mode 100644 "questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/solution.h" diff --git a/README.md b/README.md index ed3158f..599c14f 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,6 @@ ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) + +## 代数 +[7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/main.cpp" "b/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/main.cpp" new file mode 100644 index 0000000..652e041 --- /dev/null +++ "b/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + int a[] = { + 123, + -123, + 120, + 0, + }; + + Solution sln; + for(auto i:a){ + print("i=", i, "\nr:", sln.reverse(i), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/solution.h" "b/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/solution.h" new file mode 100644 index 0000000..e2cc95d --- /dev/null +++ "b/questions/7.\346\225\264\346\225\260\345\217\215\350\275\254/solution.h" @@ -0,0 +1,15 @@ +// #define print(...) + +class Solution { +public: + int reverse(int x) { + int rev = 0; + while(x){ + if(rev < INT_MIN/10 || INT_MAX/10 < rev) + return 0; + rev = rev*10 + x%10; + x /= 10; + } + return rev; + } +}; -- Gitee From adb814aebb1e82b0053d6af55556d26bb0a54289 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 3 Jul 2021 23:28:10 +0800 Subject: [PATCH 07/77] =?UTF-8?q?leetcode-8.=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=95=B4=E6=95=B0=20(atoi)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 +++++++++++++ .../solution.h" | 28 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 "questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/main.cpp" create mode 100644 "questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/solution.h" diff --git a/README.md b/README.md index 599c14f..7b00ab0 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,7 @@ ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) +[8. 字符串转换整数 (atoi)](https://leetcode-cn.com/problems/string-to-integer-atoi/) + ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/main.cpp" "b/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/main.cpp" new file mode 100644 index 0000000..4a1e965 --- /dev/null +++ "b/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string strs[] = { + "42", + " -42", + "4193 with words", + "words and 987", + "-91283472332", + }; + + Solution sln; + for(auto a:strs){ + print("a=", a, "\ni:", sln.myAtoi(a), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/solution.h" "b/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/solution.h" new file mode 100644 index 0000000..0ee1b1d --- /dev/null +++ "b/questions/8.\345\255\227\347\254\246\344\270\262\350\275\254\346\215\242\346\225\264\346\225\260(atoi)/solution.h" @@ -0,0 +1,28 @@ +// #define print(...) + +#define IS_DIGIT(x) ('0'<=(x) && (x)<='9') +#define IS_SIGN(x) ('-'==(x) ? -1 : ((x)=='+' ? 1 : 0)) +class Solution { +public: + int myAtoi(string s) { + int sign = 1; + auto p = s.begin(), end=s.end(); + while(p!=end && ' ' == *p) ++p; + if(p!=end && !IS_DIGIT(*p) && !IS_SIGN(*p)) return 0; + if(p!=end && IS_SIGN(*p)){ + sign=IS_SIGN(*p); + ++p; + } + int64_t ret = 0; + while(p!=end && IS_DIGIT(*p)){ + ret = ret*10 + (*p)-'0'; + ++p; + if(1==sign){ + ret = min(ret, (int64_t)INT_MAX); + }else if(-1==sign){ + ret = min(ret, -(int64_t)INT_MIN); + } + } + return int(sign * ret); + } +}; -- Gitee From efbba7dce1d943e10d9d2f0d1810e0f39a51ff76 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 4 Jul 2021 00:17:13 +0800 Subject: [PATCH 08/77] =?UTF-8?q?leetcode-9.=E5=9B=9E=E6=96=87=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 20 +++++++++++++++++++ .../solution.h" | 19 ++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 "questions/9.\345\233\236\346\226\207\346\225\260/main.cpp" create mode 100644 "questions/9.\345\233\236\346\226\207\346\225\260/solution.h" diff --git a/README.md b/README.md index 7b00ab0..73a33dc 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,5 @@ ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) + +[9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) diff --git "a/questions/9.\345\233\236\346\226\207\346\225\260/main.cpp" "b/questions/9.\345\233\236\346\226\207\346\225\260/main.cpp" new file mode 100644 index 0000000..4eb67a6 --- /dev/null +++ "b/questions/9.\345\233\236\346\226\207\346\225\260/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + int n[] = { + 121, + -121, + 10, + -101, + 11, + 1221, + 0, + }; + Solution sln; + for(auto i:n){ + print("i=", i, " [", sln.isPalindrome(i)?"√":"×", "]\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/9.\345\233\236\346\226\207\346\225\260/solution.h" "b/questions/9.\345\233\236\346\226\207\346\225\260/solution.h" new file mode 100644 index 0000000..f12f3ce --- /dev/null +++ "b/questions/9.\345\233\236\346\226\207\346\225\260/solution.h" @@ -0,0 +1,19 @@ +// #define print(...) + +class Solution { +public: + bool isPalindrome(int x) { + if(x == 0) return true; + if(x < 0 ) return false; + if(x%10==0)return false; + int y = 0; + while(x>y){ + y = 10*y + x%10; + if(y==x || y==x/10){ + return true; + } + x /= 10; + } + return false; + } +}; -- Gitee From 6db4bd46b1bbcfdbdc8c39940def70dca18d274f Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 4 Jul 2021 00:46:35 +0800 Subject: [PATCH 09/77] =?UTF-8?q?leetcode-645.=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=9B=86=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 16 ++++++++++++++ .../solution.h" | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 "questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/main.cpp" create mode 100644 "questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/solution.h" diff --git a/README.md b/README.md index 73a33dc..6007298 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 +[645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/main.cpp" "b/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/main.cpp" new file mode 100644 index 0000000..85aa993 --- /dev/null +++ "b/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/main.cpp" @@ -0,0 +1,16 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector> sets = { + {1,2,2,4}, + {1,1}, + }; + Solution sln; + for(auto &s:sets){ + print("s=", s, "\n") + print("ri:", sln.findErrorNums(s), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/solution.h" "b/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/solution.h" new file mode 100644 index 0000000..8f27fab --- /dev/null +++ "b/questions/645.\351\224\231\350\257\257\347\232\204\351\233\206\345\220\210/solution.h" @@ -0,0 +1,22 @@ +// #define print(...) + +class Solution { +public: + vector findErrorNums(vector& nums) { + vector repeat_lost(2); + vector bucket; + bucket.reserve(nums.size()); + bucket.resize(nums.size()); + for(int i:nums) + bucket[i-1]++; + print("bucket:", bucket, "\n") + int re = 0; + for(auto it=bucket.begin(); re<2 && it!=bucket.end(); it++){ + if(0 == *it && ++re) + repeat_lost[1] = int(it-bucket.begin()+1); + else if(1 < *it && ++re) + repeat_lost[0] = int(it-bucket.begin()+1); + } + return repeat_lost; + } +}; -- Gitee From e7644b9153cc578e2e39153d401fdf8dbd81cc4a Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 4 Jul 2021 19:19:27 +0800 Subject: [PATCH 10/77] =?UTF-8?q?leetcode-10.=E6=AD=A3=E5=88=99=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- .../main.cpp" | 26 +++++++++++++++++++ .../solution.h" | 25 ++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 "questions/10.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215/main.cpp" create mode 100644 "questions/10.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215/solution.h" diff --git a/README.md b/README.md index 6007298..1392411 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,13 @@ ## BFS [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/) -## 贪心算法 +## 贪心 [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) ## 动态规则 [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) +[10. 正则表达式匹配](https://leetcode-cn.com/problems/regular-expression-matching/) ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 diff --git "a/questions/10.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215/main.cpp" "b/questions/10.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215/main.cpp" new file mode 100644 index 0000000..b7eb9dd --- /dev/null +++ "b/questions/10.\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217\345\214\271\351\205\215/main.cpp" @@ -0,0 +1,26 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string sp[] = { + "aa", + "a", + "aa", + "a*", + "ab", + ".*", + "aab", + "c*a*b", + "mississippi", + "mis*is*p*.", + "", + ".*", + }; + Solution sln; + for(int i=0; i > dp(sz+1, vector(pz+1)); + dp[0][0] = true; + auto st = s.begin(), pt = p.begin(); + for(int i=0; i<=sz; i++){ + for(int j=1; j<=pz; j++){ + if('*' == p[j-1]){ + if(dp[i][j-2]) + dp[i][j] = true; + else if(i && OK(st+i, pt+j-1)) + dp[i][j] = dp[i-1][j]; + }else if( i && OK(st+i, pt+j) && dp[i-1][j-1]){ + dp[i][j] = true; + } + } + } + return dp[sz][pz]; + } +}; -- Gitee From 09b6beec7ab79ac89bd8b13d547f692e666e677c Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 5 Jul 2021 23:31:03 +0800 Subject: [PATCH 11/77] =?UTF-8?q?print(...)=E5=A4=84=E7=90=86=E7=A9=BA?= =?UTF-8?q?=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/virtualio.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/virtualio.h b/include/virtualio.h index ad61c12..1d6844c 100644 --- a/include/virtualio.h +++ b/include/virtualio.h @@ -28,12 +28,15 @@ public: template OStream& operator<<(const T&t){(*po)<< t; return *this;} template OStream& operator<<(const T*t){(*po)<<*t; return *this;} template OStream& operator<<(const std::vector &v){ + if(v.empty()) return *this; return Out(v.begin(), v.end()); } template OStream&operator<<(const std::list &v){ + if(v.empty()) return *this; return Out(v.begin(), v.end()); } template OStream& operator<<(const std::set &v){ + if(v.empty()) return *this; return Out(v.begin(), v.end()); } template OStream& operator<<(const std::pair & pair){ @@ -43,9 +46,11 @@ public: return *this; } template OStream&operator<<(const std::unordered_map &m){ + if(m.empty()) return *this; return Out(m.begin(), m.end()); } template OStream&operator<<(const std::map &m){ + if(m.empty()) return *this; return Out(m.begin(), m.end()); } protected: @@ -72,4 +77,4 @@ inline void print_any(const Any ...any){ StrStream ss; std::initializer_list{(ss << any, true)...}.size(); std::cout << ss.str(); -} \ No newline at end of file +} -- Gitee From 4765ed6fc8a8108fc06a55ccbb470d70cffeccd0 Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 5 Jul 2021 23:34:23 +0800 Subject: [PATCH 12/77] =?UTF-8?q?leetcode-726.=E5=8E=9F=E5=AD=90=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++ .../main.cpp" | 18 ++++++ .../solution.h" | 58 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 "questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/main.cpp" create mode 100644 "questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/solution.h" diff --git a/README.md b/README.md index 1392411..92eb03e 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,12 @@ [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) [10. 正则表达式匹配](https://leetcode-cn.com/problems/regular-expression-matching/) + ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) + ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) @@ -23,3 +25,6 @@ [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) [9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) + +## 栈 +[726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) diff --git "a/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/main.cpp" "b/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/main.cpp" new file mode 100644 index 0000000..d7ed7f4 --- /dev/null +++ "b/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string formulas[] = { + "H2O", + "Mg(OH)2", + "K4(ON(SO3)2)2", + "Be32", + }; + Solution sln; + for(auto&f:formulas){ + print("formula=", f, "\n") + print("o:", sln.countOfAtoms(f), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/solution.h" "b/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/solution.h" new file mode 100644 index 0000000..81540b0 --- /dev/null +++ "b/questions/726.\345\216\237\345\255\220\347\232\204\346\225\260\351\207\217/solution.h" @@ -0,0 +1,58 @@ +// #define print(...) +#define map_t map +#define get_num(p,tail,num) \ + if(p==tail || !isdigit(*p)) \ + num = 1; \ + while(p!=tail && isdigit(*p)) \ + num = (*p++)-'0' + num*10; + +#define get_atom(p,tail,atom) \ + atom.insert(atom.end(), *p); \ + while(++p > stk(1); + int n = 0; + auto it=formula.begin(); + while(it!=formula.end()){ + switch(*it){ + case '(': + stk.push_front(map_t()); + ++it; + break; + case ')': + n = 0; + ++it; + get_num(it, formula.end(), n) + { + auto tmp = stk.front(); + stk.pop_front(); + for(auto&[atom,count]:tmp) + stk.front()[atom] += count*n; + } + break; + default: + string atom; n = 0; + get_atom(it, formula.end(), atom) + print(atom, "-") + get_num(it, formula.end(), n) + print(n, "\n") + stk.front()[atom] += n; + break; + } + print(stk, "\n") + } + + string s; + s.reserve(formula.size()); + for(auto &[a,n]:stk.front()){ + s.insert(s.size(), a); + if(n>1) + s.insert(s.size(), to_string(n)); + } + return s; + } +}; -- Gitee From 68f354dd000932262c53047b6beeb11334ac6b45 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 6 Jul 2021 13:29:36 +0800 Subject: [PATCH 13/77] =?UTF-8?q?leetcode-1418.=E7=82=B9=E8=8F=9C=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++ .../main.cpp" | 21 ++++++++++++ .../solution.h" | 34 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 "questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/main.cpp" create mode 100644 "questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/solution.h" diff --git a/README.md b/README.md index 92eb03e..62a7303 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,6 @@ ## 栈 [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) + +## Hash +[1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) diff --git "a/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/main.cpp" "b/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/main.cpp" new file mode 100644 index 0000000..ff04bbe --- /dev/null +++ "b/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/main.cpp" @@ -0,0 +1,21 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector> orders = { + {"David","3","Ceviche"}, + {"Corina","10","Beef Burrito"}, + {"David","3","Fried Chicken"}, + {"Carla","5","Water"}, + {"Carla","5","Ceviche"}, + {"Rous","3","Ceviche"}, + }; + Solution sln; + auto tables = sln.displayTable(orders); + for(auto &tbl:tables){ + print(tbl, "\n"); + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/solution.h" "b/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/solution.h" new file mode 100644 index 0000000..fafd7b1 --- /dev/null +++ "b/questions/1418.\347\202\271\350\217\234\345\261\225\347\244\272\350\241\250/solution.h" @@ -0,0 +1,34 @@ +// #define print(...) +#define map_t map +class Solution { +public: + vector> displayTable(vector>& orders) { + map_t menu; /*item, index*/ + map_t > tbl; + for(auto & d: orders){ + menu.insert({d[2], 0}); + } + int i = 0; + for(auto &[item,idx]:menu){ + idx = i++; + } + for(auto & d: orders){ + auto ti = atoi(d[1].c_str()); + tbl[ti].resize(menu.size()); + tbl[ti][menu[d[2]]] ++; + } + + vector> table(1+tbl.size(), vector()); + auto it = table.begin(); + it->push_back("Table"); + for(auto &m:menu) + it->push_back(m.first); + for(auto & [idx,item]:tbl){ + (++it)->push_back(to_string(idx)); + for(auto &n:item) + it->push_back(to_string(n)); + } + + return table; + } +}; -- Gitee From b34c57b020a4d1ed01ac10278202ed1b135c3c96 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 6 Jul 2021 21:41:07 +0800 Subject: [PATCH 14/77] =?UTF-8?q?leetcode-11.=E7=9B=9B=E6=9C=80=E5=A4=9A?= =?UTF-8?q?=E6=B0=B4=E7=9A=84=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../main.cpp" | 20 +++++++++++++++++++ .../solution.h" | 14 +++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 "questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/main.cpp" create mode 100644 "questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/solution.h" diff --git a/README.md b/README.md index 62a7303..45bf516 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,6 @@ ## Hash [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) + +## 指针 +[11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/main.cpp" "b/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/main.cpp" new file mode 100644 index 0000000..98e9fdb --- /dev/null +++ "b/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *arg[]){ + vector< vector > hs = { + {1,8,6,2,5,4,8,3,7}, + {1,1}, + {4,3,2,1,4}, + {1,2,1}, + }; + + Solution sln; + for(auto& h:hs){ + print(h, ":") + print(sln.maxArea(h), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/solution.h" "b/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/solution.h" new file mode 100644 index 0000000..438387d --- /dev/null +++ "b/questions/11.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/solution.h" @@ -0,0 +1,14 @@ +// #define print(...) +class Solution { +public: + int maxArea(vector& height) { + auto front = height.begin(), + back = front + height.size() - 1; + long res = 0; + while(front Date: Tue, 6 Jul 2021 22:30:11 +0800 Subject: [PATCH 15/77] =?UTF-8?q?leetcode-12.=E6=95=B4=E6=95=B0=E8=BD=AC?= =?UTF-8?q?=E7=BD=97=E9=A9=AC=E6=95=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 18 ++++++++++++ .../solution.h" | 29 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 "questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" create mode 100644 "questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/solution.h" diff --git a/README.md b/README.md index 45bf516..e773be2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ## 贪心 [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) +[12. 整数转罗马数字](https://leetcode-cn.com/problems/integer-to-roman/) ## 动态规则 [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git "a/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" new file mode 100644 index 0000000..8e2a327 --- /dev/null +++ "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + int n[] = { + 3, + 4, + 9, + 58, + 1994, + 3999, + }; + Solution sln; + for(auto&i:n) + print(i, "=", sln.intToRoman(i), "\n") + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/solution.h" "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/solution.h" new file mode 100644 index 0000000..fab0d2a --- /dev/null +++ "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/solution.h" @@ -0,0 +1,29 @@ +// #define print(...) +class Solution { +public: + string intToRoman(int num) { + tuple dict[] = { + {1000, "M"}, + {900, "CM"}, + {500, "D"}, + {400, "CD"}, + {100, "C"}, + {90, "XC"}, + {50, "L"}, + {40, "XL"}, + {10, "X"}, + {9, "IX"}, + {5, "V"}, + {4, "IV"}, + {1, "I"}, + }; + string rom; + for(auto&[v,r]:dict){ + while(num >= v){ + rom.append(r); + num -= v; + } + } + return rom; + } +}; -- Gitee From 403d9254cf5a26626a2d2490f77ed01cce81442a Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 6 Jul 2021 22:58:06 +0800 Subject: [PATCH 16/77] =?UTF-8?q?leetcode-13.=E7=BD=97=E9=A9=AC=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E8=BD=AC=E6=95=B4=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main.cpp" | 7 ++++++- .../solution.h" | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git "a/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" index 8e2a327..b8173c6 100644 --- "a/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" +++ "b/questions/12.\346\225\264\346\225\260\350\275\254\347\275\227\351\251\254\346\225\260\345\255\227/main.cpp" @@ -11,8 +11,13 @@ int main(int argc, char *argv[]){ 3999, }; Solution sln; + vector roms; for(auto&i:n) - print(i, "=", sln.intToRoman(i), "\n") + roms.push_back(sln.intToRoman(i)); + for(int i=0; i dict('X'-'C'+1, 0); + r2i('I') = 1; + r2i('V') = 5; + r2i('X') = 10; + r2i('L') = 50; + r2i('C') = 100; + r2i('D') = 500; + r2i('M') = 1000; +// print("dict=", dict, "\n") + if(s.size() == 1) return r2i(s[0]); + int res = 0; + auto it=s.begin(); + while(++it != s.end()) { + res += r2i(*(it-1)) < r2i(*it) ? -r2i(*(it-1)) : r2i(*(it-1)); + }; + return res + r2i(*(it-1)); + } + string intToRoman(int num) { tuple dict[] = { {1000, "M"}, -- Gitee From 9c599b325305aedf1a7892616499f972f2d66f8c Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 7 Jul 2021 13:32:08 +0800 Subject: [PATCH 17/77] =?UTF-8?q?leetcode-1711.=E5=A4=A7=E9=A4=90=E8=AE=A1?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- .../main.cpp" | 16 +++++++++++++++ .../solution.h" | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 "questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/main.cpp" create mode 100644 "questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/solution.h" diff --git a/README.md b/README.md index e773be2..084931d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# leetcode +# 实践是检验真理的唯一标准 ## BFS [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/) @@ -33,5 +33,6 @@ ## Hash [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) +[1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/)「互补 Key , 桶」 ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/main.cpp" "b/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/main.cpp" new file mode 100644 index 0000000..44bf63e --- /dev/null +++ "b/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/main.cpp" @@ -0,0 +1,16 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector tests[] = { + {1,3,5,7,9}, + {1,1,1,3,3,3,7}, + }; + Solution sln; + for(auto&v:tests){ + print("case=", v, "\n") + print("pair:", sln.countPairs(v), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/solution.h" "b/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/solution.h" new file mode 100644 index 0000000..27e25de --- /dev/null +++ "b/questions/1711.\345\244\247\351\244\220\350\256\241\346\225\260/solution.h" @@ -0,0 +1,20 @@ +// #define print(...) +#define map_t unordered_map +class Solution { +public: + int countPairs(vector& deliciousness) { + int res = 0; + map_t cnt; + auto maxSum = *max_element(deliciousness.begin(), deliciousness.end()) << 1; + for(auto &i:deliciousness){ + for(int meal = 1; meal <= maxSum; meal <<= 1){ + if(cnt.count(meal-i)){ + res = (res + cnt[meal-i]) % 1000000007; + print(i, " + ", meal-i, "(", cnt[meal-i], ") = ", meal, "\n") + } + } + cnt[i]++; + } + return res; + } +}; -- Gitee From 02c3099cd02a3c6f3041a5a7028a7cc769cc5eb8 Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 7 Jul 2021 13:50:28 +0800 Subject: [PATCH 18/77] =?UTF-8?q?leetcode-1.=E4=B8=A4=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 +++++++++++++ .../solution.h" | 28 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 "questions/1.\344\270\244\346\225\260\344\271\213\345\222\214/main.cpp" create mode 100644 "questions/1.\344\270\244\346\225\260\344\271\213\345\222\214/solution.h" diff --git a/README.md b/README.md index 084931d..85bd65a 100644 --- a/README.md +++ b/README.md @@ -34,5 +34,7 @@ [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) [1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/)「互补 Key , 桶」 + +[1. 两数之和](https://leetcode-cn.com/problems/two-sum/)「互补 Key」 ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/1.\344\270\244\346\225\260\344\271\213\345\222\214/main.cpp" "b/questions/1.\344\270\244\346\225\260\344\271\213\345\222\214/main.cpp" new file mode 100644 index 0000000..fc64996 --- /dev/null +++ "b/questions/1.\344\270\244\346\225\260\344\271\213\345\222\214/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector nums[] = { + {2,7,11,15}, + {3,2,4}, + {3,3}, + }; + int targets[] = {9, 6, 6}; + Solution sln; + for(int i=0; i twoSum(vector& nums, int target) { + unordered_map tmp; + for(int i=0; i(); + } +}; + +/* // golang +func twoSum(nums []int, target int) []int { + tmp := make(map[int]int, len(nums)) + for i, v := range nums { + if t, ok := tmp[target-v]; ok { + return []int{t, i} + } else { + tmp[v] = i + } + } + return nil +} +*/ -- Gitee From 1cd6727255891a5d04e915bf2595f7843f415c0c Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 7 Jul 2021 22:33:24 +0800 Subject: [PATCH 19/77] =?UTF-8?q?leetcode-14.=E6=9C=80=E9=95=BF=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 16 ++++++++++++++++ .../solution.h" | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 "questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/main.cpp" create mode 100644 "questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/solution.h" diff --git a/README.md b/README.md index 85bd65a..fec614b 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,5 @@ [1. 两数之和](https://leetcode-cn.com/problems/two-sum/)「互补 Key」 ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 + +[14. 最长公共前缀](https://leetcode-cn.com/problems/longest-common-prefix/) diff --git "a/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/main.cpp" "b/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/main.cpp" new file mode 100644 index 0000000..1fa1d4a --- /dev/null +++ "b/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/main.cpp" @@ -0,0 +1,16 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector strs[] = { + { "flower", "flow", "flight" }, + { "dog","racecar","car" }, + }; + Solution sln; + for(auto&s:strs){ + print("strs=", s, "\n") + print(sln.longestCommonPrefix(s), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/solution.h" "b/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/solution.h" new file mode 100644 index 0000000..43077f3 --- /dev/null +++ "b/questions/14.\346\234\200\351\225\277\345\205\254\345\205\261\345\211\215\347\274\200/solution.h" @@ -0,0 +1,19 @@ +// #define print(...) +class Solution { +public: + string longestCommonPrefix(vector& strs) { + if(strs.empty()) return ""; + string::iterator head = strs[0].begin(), + rear = head + strs[0].size(); + for(auto it=strs.begin()+1; it!=strs.end(); it++){ + auto i1 = head; + for(auto i2 = it->begin(); i2!=it->end() && i1!=rear; i2++){ + if(*i1 != *i2) break; + i1++; + } + if(rear > i1) rear = i1; + if(rear == head) return ""; + } + return strs[0].substr(0, rear-head); + } +}; \ No newline at end of file -- Gitee From 361815486a36b1fabce50df87ea9de188f693aff Mon Sep 17 00:00:00 2001 From: sudo Date: Thu, 8 Jul 2021 09:02:10 +0800 Subject: [PATCH 20/77] =?UTF-8?q?leetcode-930.=E5=92=8C=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=E7=9A=84=E4=BA=8C=E5=85=83=E5=AD=90=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ .../main.cpp" | 19 +++++++++++++++++++ .../solution.h" | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 "questions/930.\345\222\214\347\233\270\345\220\214\347\232\204\344\272\214\345\205\203\345\255\220\346\225\260\347\273\204/main.cpp" create mode 100644 "questions/930.\345\222\214\347\233\270\345\220\214\347\232\204\344\272\214\345\205\203\345\255\220\346\225\260\347\273\204/solution.h" diff --git a/README.md b/README.md index fec614b..6b7000c 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,6 @@ [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 [14. 最长公共前缀](https://leetcode-cn.com/problems/longest-common-prefix/) + +## 滑动窗口 +[930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) diff --git "a/questions/930.\345\222\214\347\233\270\345\220\214\347\232\204\344\272\214\345\205\203\345\255\220\346\225\260\347\273\204/main.cpp" "b/questions/930.\345\222\214\347\233\270\345\220\214\347\232\204\344\272\214\345\205\203\345\255\220\346\225\260\347\273\204/main.cpp" new file mode 100644 index 0000000..8f563c6 --- /dev/null +++ "b/questions/930.\345\222\214\347\233\270\345\220\214\347\232\204\344\272\214\345\205\203\345\255\220\346\225\260\347\273\204/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ +// nums = [1,0,1,0,1], goal = 2, ans=4 +// nums = [0,0,0,0,0], goal = 0, ans=15 + vector nums[] = { + { 1,0,1,0,1 }, + { 0,0,0,0,0 }, + }; + int goal[] = {2, 0}; + Solution sln; + for(int i=0; i& nums, int goal) { + auto left = nums.begin(), mid = left; + int sum = 0, sumFromLeft = 0, sumFromMid = 0, ans = 0; + for(auto right=left; right != nums.end(); right++){ + sumFromLeft += *right; + while(left <= right && goal < sumFromLeft) + sumFromLeft -= *left++; + sumFromMid += *right; + while(mid <= right && goal <=sumFromMid) + sumFromMid -= *mid++; + ans += mid - left; + } + return ans; + } +}; -- Gitee From b2933881445b580405e973ee61f8cefe9fcff065 Mon Sep 17 00:00:00 2001 From: sudo Date: Thu, 8 Jul 2021 22:37:13 +0800 Subject: [PATCH 21/77] =?UTF-8?q?leetcode-16.=E6=9C=80=E6=8E=A5=E8=BF=91?= =?UTF-8?q?=E7=9A=84=E4=B8=89=E6=95=B0=E4=B9=8B=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ .../main.cpp" | 22 ++++++++++++++++++ .../solution.h" | 23 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 "questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" create mode 100644 "questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" diff --git a/README.md b/README.md index 6b7000c..100a4ff 100644 --- a/README.md +++ b/README.md @@ -41,5 +41,9 @@ [14. 最长公共前缀](https://leetcode-cn.com/problems/longest-common-prefix/) +[15. 三数之和](https://leetcode-cn.com/problems/3sum/) + +[16. 最接近的三数之和](https://leetcode-cn.com/problems/3sum-closest/) + ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) diff --git "a/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" "b/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" new file mode 100644 index 0000000..383f176 --- /dev/null +++ "b/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" @@ -0,0 +1,22 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector nums[] = { + {-1,2,1,-4}, // 2 + {0,2,1,-3}, // 0 + {1,1,-1,-1,3}, // -1 + {0,0,0}, // 0 + {1,1,48,50,99,100,103,333,333}, // 250 + {3,4,5,5,7}, //13 + }; + int targets[] = {1,1,-1,1,250, 13}; + Solution sln; + for(int i=0; i", targets[i], "\n") + print("clos:", sln.threeSumClosest(nums[i], targets[i]), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" "b/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" new file mode 100644 index 0000000..2f0ef81 --- /dev/null +++ "b/questions/16.\346\234\200\346\216\245\350\277\221\347\232\204\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" @@ -0,0 +1,23 @@ +// #define print(...) + +#define abs(i) ((i)<0 ? -(i) : (i)) +class Solution { +public: +int threeSumClosest(vector& nums, int target) { + sort(nums.begin(), nums.end()); + print(nums, "\n") + int ans = nums[0] + nums[1] + nums[2]; + for(auto s=nums.begin(); s !=nums.end()-2; s++){ + auto m=s+1, b = nums.end()-1; + while(m Date: Thu, 8 Jul 2021 14:04:40 +0800 Subject: [PATCH 22/77] =?UTF-8?q?leetcode-15.=E4=B8=89=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main.cpp" | 21 +++++++++++++++ .../solution.h" | 26 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 "questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" create mode 100644 "questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" diff --git "a/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" "b/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" new file mode 100644 index 0000000..6019446 --- /dev/null +++ "b/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/main.cpp" @@ -0,0 +1,21 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + // 输入:nums = [-1,0,1,2,-1,-4] + // 输出:[[-1,-1,2],[-1,0,1]] + vector nums[] = { + { -1,0,1,2,-1,-4 }, // [[-1,-1,2],[-1,0,1]] + {1,2,-2,-1}, //{} + { 0 }, // {} + {}, // {} + {0,0,0,0}, + }; + Solution sln; + for(auto&n:nums){ + print("nums=", n, "\n") + print("ans:", sln.threeSum(n), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" "b/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" new file mode 100644 index 0000000..fb19f7f --- /dev/null +++ "b/questions/15.\344\270\211\346\225\260\344\271\213\345\222\214/solution.h" @@ -0,0 +1,26 @@ +// #define print(...) +class Solution { +public: + vector> threeSum(vector& nums) { + if(nums.empty()) return {}; + sort(nums.begin(), nums.end()); + print(nums, "\n") + vector> ans; + for(auto s=nums.begin(); s!=nums.end(); s++){ + if(nums.begin() Date: Fri, 9 Jul 2021 12:59:24 +0800 Subject: [PATCH 23/77] =?UTF-8?q?leetcode-169.=E5=A4=9A=E6=95=B0=E5=85=83?= =?UTF-8?q?=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ .../main.cpp" | 20 +++++++++++++++++++ .../solution.h" | 14 +++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 "questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/main.cpp" create mode 100644 "questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" diff --git a/README.md b/README.md index 100a4ff..4e7df3d 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,7 @@ ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) + +## 数组 +[169. 多数元素](https://leetcode-cn.com/problems/majority-element/)「摩尔投票」 +[面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) \ No newline at end of file diff --git "a/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/main.cpp" "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/main.cpp" new file mode 100644 index 0000000..b2da9bc --- /dev/null +++ "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector nums[] = { + { 3,2,3 }, + { 2,2,1,1,1,2,2 }, + { 1,2,5,9,5,9,5,5,5 }, + { 3,2 }, + { 3,3,4}, + }; + Solution sln; + for(auto&n:nums){ + print("nums=", n) + print("maj:", sln.majorityElement(n), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" new file mode 100644 index 0000000..c645cae --- /dev/null +++ "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" @@ -0,0 +1,14 @@ +// #define print(...) + +class Solution { +public: +int majorityElement(vector& nums) { + int cnt = 0, candidate = -1; + for(auto&i:nums){ + if(0 == cnt) candidate = i; + i == candidate ? cnt++ : cnt--; + } + print("\ncnt=", cnt, ", ans=", candidate, "\n") + return candidate; +} +}; \ No newline at end of file -- Gitee From a661edb4c81e92c5093bf73dd3575493d2aa92cd Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 9 Jul 2021 13:02:38 +0800 Subject: [PATCH 24/77] =?UTF-8?q?in-17.10.=E4=B8=BB=E8=A6=81=E5=85=83?= =?UTF-8?q?=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution.h" | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git "a/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" index c645cae..4cde9a5 100644 --- "a/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" +++ "b/questions/169.\345\244\232\346\225\260\345\205\203\347\264\240/solution.h" @@ -9,6 +9,9 @@ int majorityElement(vector& nums) { i == candidate ? cnt++ : cnt--; } print("\ncnt=", cnt, ", ans=", candidate, "\n") - return candidate; + cnt = 0; + for(auto&i:nums) + if(i==candidate) cnt++; + return cnt>nums.size()/2 ? candidate : -1; } }; \ No newline at end of file -- Gitee From d749472dd873c1598b0c824ef1a3a7118cb0d091 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 10 Jul 2021 18:24:59 +0800 Subject: [PATCH 25/77] =?UTF-8?q?leetcode-981.=E5=9F=BA=E4=BA=8E=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E7=9A=84=E9=94=AE=E5=80=BC=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ include/stl.h | 1 + .../main.cpp" | 20 +++++++++++++ .../solution.h" | 30 +++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 "questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/main.cpp" create mode 100644 "questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/solution.h" diff --git a/README.md b/README.md index 4e7df3d..1be7f28 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) +## 查找 +[981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)「二分查找」 ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git a/include/stl.h b/include/stl.h index 0d21a8e..57d67da 100644 --- a/include/stl.h +++ b/include/stl.h @@ -1,3 +1,4 @@ #pragma once +#include #include "virtualio.h" using namespace std; diff --git "a/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/main.cpp" "b/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/main.cpp" new file mode 100644 index 0000000..06cf14f --- /dev/null +++ "b/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + TimeMap kv; + kv.set("foo", "bar", 1); // 存储键 "foo" 和值 "bar" 以及时间戳 timestamp = 1 + print( + // 输出 "bar" + kv.get("foo", 1), "\n", + // 输出 "bar" 因为在时间戳 3 和时间戳 2 处没有对应 "foo" 的值,所以唯一的值位于时间戳 1 处(即 "bar") + kv.get("foo", 3), "\n") + + kv.set("foo", "bar2", 4); + print( + kv.get("foo", 4), "\n", // 输出 "bar2" + kv.get("foo", 5), "\n") // 输出 "bar2" + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/solution.h" "b/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/solution.h" new file mode 100644 index 0000000..15cbef8 --- /dev/null +++ "b/questions/981.\345\237\272\344\272\216\346\227\266\351\227\264\347\232\204\351\224\256\345\200\274\345\255\230\345\202\250/solution.h" @@ -0,0 +1,30 @@ +// #define print(...) +#define map_t unordered_map +class TimeMap { +// ]> +map_t>> tk; + +public: +/** Initialize your data structure here. */ +TimeMap() {} + +void set(string key, string value, int timestamp) { + tk[key].emplace_back(timestamp, value); +} + +string get(string key, int timestamp) { + if(0 == tk.count(key)) return ""; + auto & values = tk[key]; + auto it = upper_bound(values.begin(), values.end(), pair(timestamp,{'z'+1})); + if(it != values.begin()) + return (it-1)->second; + return ""; +} +}; + +/** + * Your TimeMap object will be instantiated and called as such: + * TimeMap* obj = new TimeMap(); + * obj->set(key,value,timestamp); + * string param_2 = obj->get(key,timestamp); + */ -- Gitee From 144786eb89e656c491b6a4c57b8ec566568620cd Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 10 Jul 2021 21:48:27 +0800 Subject: [PATCH 26/77] =?UTF-8?q?leetcode-17.=E7=94=B5=E8=AF=9D=E5=8F=B7?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E5=AD=97=E6=AF=8D=E7=BB=84=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++--- .../main.cpp" | 16 ++++++++++++ .../solution.h" | 26 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 "questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/main.cpp" create mode 100644 "questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/solution.h" diff --git a/README.md b/README.md index 1be7f28..71c0d0a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,5 @@ # 实践是检验真理的唯一标准 -## BFS -[815. 公交路线](https://leetcode-cn.com/problems/bus-routes/) - ## 贪心 [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) @@ -19,6 +16,10 @@ ## 查找 [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)「二分查找」 +## 搜索 +[17. 电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)「回溯」 + +[815. 公交路线](https://leetcode-cn.com/problems/bus-routes/)「BFS」 ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/main.cpp" "b/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/main.cpp" new file mode 100644 index 0000000..0297441 --- /dev/null +++ "b/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/main.cpp" @@ -0,0 +1,16 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string digits[] = { + "23", "", "2", + }; + Solution sln; + for(auto&s:digits){ + print("digits=", s, "\n") + print("ans:", sln.letterCombinations(s), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/solution.h" "b/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/solution.h" new file mode 100644 index 0000000..298b4ba --- /dev/null +++ "b/questions/17.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/solution.h" @@ -0,0 +1,26 @@ +// #define print(...) + +#define kstr(i) keys[ (i)-'2' ] +class Solution { +public: +vector letterCombinations(string digits) { + vector res; + if(digits.empty()) return res; + string keys[] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; + string ans; + function bt; + bt = [&](size_t index){ + if(index == digits.length()){ + res.push_back(ans); + return; + } + for(auto &c:kstr(digits[index])){ + ans.push_back(c); + bt(index+1); + ans.pop_back(); + } + }; + bt(0); + return res; +} +}; -- Gitee From 3eab764d992f4d4bdb36bc848b90f555539c5907 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 10 Jul 2021 23:49:37 +0800 Subject: [PATCH 27/77] =?UTF-8?q?LCP-07.=E4=BC=A0=E9=80=92=E4=BF=A1?= =?UTF-8?q?=E6=81=AF(DFS=E8=A7=A3=E6=B3=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- .../main.cpp" | 21 +++++++++++++++++ .../solution.h" | 23 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 "questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" create mode 100644 "questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" diff --git a/README.md b/README.md index 71c0d0a..e17fa67 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ [17. 电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)「回溯」 [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/)「BFS」 + +[LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS」 ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) @@ -53,4 +55,4 @@ ## 数组 [169. 多数元素](https://leetcode-cn.com/problems/majority-element/)「摩尔投票」 -[面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) \ No newline at end of file +[面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) diff --git "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" new file mode 100644 index 0000000..a85223e --- /dev/null +++ "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" @@ -0,0 +1,21 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + struct{ + int n, k; + vector> r; + } relations[] = { + {5, 3, { {0,2},{2,1},{3,4},{2,3},{1,4},{2,0},{0,4}} }, + {3, 2, { {0,2},{2,1}} }, + }; + Solution sln; + for(auto&s:relations){ + print("n=", s.n, ", k=", s.k, ", relation=", s.r, "\n") + print("ans:", sln.numWays(s.n, s.r, s.k), "\n") + } + + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" new file mode 100644 index 0000000..8075d50 --- /dev/null +++ "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" @@ -0,0 +1,23 @@ +// #define print(...) +class Solution { +public: +int numWays(int n, vector>& relation, int k) { + vector pathMap[n]; + for(auto&line:relation) + pathMap[line[0]].push_back(line[1]); + // dfs + int cntWay = 0; + function dfs = [&](int src, int steps){ + if(k == steps){ + if(n-1 == src) cntWay++; + return; + } + for(auto&dst:pathMap[src]){ + print(steps, ":", src, "->", dst, "\n") + dfs(dst, steps+1); + } + }; + dfs(0, 0); + return cntWay; +} +}; -- Gitee From 8a83b609ec9c313bed4e2145285543b8b854cea8 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 11:38:13 +0800 Subject: [PATCH 28/77] =?UTF-8?q?LCP-07.=E4=BC=A0=E9=80=92=E4=BF=A1?= =?UTF-8?q?=E6=81=AF(DP=E8=A7=A3=E6=B3=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../main.cpp" | 3 ++- .../solution.h" | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e17fa67..61be43b 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/)「BFS」 -[LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS」 +[LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" index a85223e..277e3c2 100644 --- "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" +++ "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/main.cpp" @@ -9,7 +9,8 @@ int main(int argc, char *argv[]){ {5, 3, { {0,2},{2,1},{3,4},{2,3},{1,4},{2,0},{0,4}} }, {3, 2, { {0,2},{2,1}} }, }; - Solution sln; +// Solution sln; + SolutionDP sln; for(auto&s:relations){ print("n=", s.n, ", k=", s.k, ", relation=", s.r, "\n") print("ans:", sln.numWays(s.n, s.r, s.k), "\n") diff --git "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" index 8075d50..7281179 100644 --- "a/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" +++ "b/questions/LCP-07.\344\274\240\351\200\222\344\277\241\346\201\257/solution.h" @@ -21,3 +21,20 @@ int numWays(int n, vector>& relation, int k) { return cntWay; } }; + +// 动态规则解法 +class SolutionDP { +public: +int numWays(int n, vector>& relation, int k) { + vector dpNew(n,0), dpPre(n,0); // 经过 i 步到达各点的方案数 + dpNew[0] = 1; + for(int i=0; i Date: Sun, 11 Jul 2021 13:47:49 +0800 Subject: [PATCH 29/77] =?UTF-8?q?leetcode-18.=E5=9B=9B=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 21 +++++++++++ .../solution.h" | 35 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 "questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/main.cpp" create mode 100644 "questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/solution.h" diff --git a/README.md b/README.md index 61be43b..f0d0a19 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ [16. 最接近的三数之和](https://leetcode-cn.com/problems/3sum-closest/) +[18. 四数之和](https://leetcode-cn.com/problems/4sum/) + ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) diff --git "a/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/main.cpp" "b/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/main.cpp" new file mode 100644 index 0000000..3b9b76d --- /dev/null +++ "b/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/main.cpp" @@ -0,0 +1,21 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + struct { + int target; + vector nums; + } testcases[] = { + {0, {1,0,-1,0,-2,2}}, + {0, {}}, + {8, {2,2,2,2,2}}, + }; + Solution sln; + for(auto&t:testcases){ + print("input=", t.nums, "->", t.target, "\n") + print("ans:", sln.fourSum(t.nums, t.target), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/solution.h" "b/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/solution.h" new file mode 100644 index 0000000..59fc76e --- /dev/null +++ "b/questions/18.\345\233\233\346\225\260\344\271\213\345\222\214/solution.h" @@ -0,0 +1,35 @@ +// #define print(...) +#define sum4(a, d) ( *(a) + *((d)-2) + *((d)-1) + *(d) ) +#define sump(a,b,c,d) ( *(a) + *(b) + *(c) + *(d) ) +class Solution { +public: +vector> fourSum(vector& nums, int target) { + if(nums.size() < 4) return {}; + sort(nums.begin(), nums.end()); + print("ordered=", nums, "\n") + if(sum4(nums.end()-4, nums.end()-1) < target) return {}; + + vector> res; + for(auto a=nums.begin(); a!=nums.end()-3; a++){ + if(a > nums.begin() && *a == *(a-1)) continue; + if(target < sum4(a, a+3)) break; + if(target > sum4(a, nums.end()-1)) continue; + for(auto b=a+1; b!=nums.end()-2; b++){ + if(b > a+1 && *b == *(b-1)) continue; + if(target < sum4(a,b+2)) break; + if(target > sump(a,b,nums.end()-2,nums.end()-1)) continue; + + auto p1 = b+1, p2 = nums.end()-1; + while(p1 < p2){ + auto s = sump(a,b,p1,p2); + if(s == target){ + res.push_back({*a, *b, *p1, *p2}); + do{p1++;}while(p1 Date: Sun, 11 Jul 2021 15:07:43 +0800 Subject: [PATCH 30/77] =?UTF-8?q?leetcode-274.H=E6=8C=87=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../274.H\346\214\207\346\225\260/main.cpp" | 17 +++++++++++++++++ .../274.H\346\214\207\346\225\260/solution.h" | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 "questions/274.H\346\214\207\346\225\260/main.cpp" create mode 100644 "questions/274.H\346\214\207\346\225\260/solution.h" diff --git a/README.md b/README.md index f0d0a19..8305046 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) +[274. H 指数](https://leetcode-cn.com/problems/h-index/)「计数(桶)排序」 ## 查找 [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)「二分查找」 ## 搜索 diff --git "a/questions/274.H\346\214\207\346\225\260/main.cpp" "b/questions/274.H\346\214\207\346\225\260/main.cpp" new file mode 100644 index 0000000..527bb55 --- /dev/null +++ "b/questions/274.H\346\214\207\346\225\260/main.cpp" @@ -0,0 +1,17 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector citations[] = { + {3,0,6,1,5}, + {1}, + }; + Solution sln; + for(auto&c:citations){ + print("ci=", c, "\n") + print("h:", sln.hIndex(c), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/274.H\346\214\207\346\225\260/solution.h" "b/questions/274.H\346\214\207\346\225\260/solution.h" new file mode 100644 index 0000000..26b6892 --- /dev/null +++ "b/questions/274.H\346\214\207\346\225\260/solution.h" @@ -0,0 +1,17 @@ +// #define print(...) +class Solution { +public: +int hIndex(vector& citations) { + vector cnt(citations.size()+1, 0); + for(auto&c:citations) + cnt[c>=cnt.size()?cnt.size()-1:c]++; + print("cnt=", cnt, "\n") + + for(int i=(int)cnt.size()-1; i>=0;){ + if(*cnt.rbegin() >= i) + return i; + *cnt.rbegin() += cnt[--i]; + } + return 0; +} +}; -- Gitee From 726de0e75bc5e11104f6ac8450955bc1793b2048 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 16:58:14 +0800 Subject: [PATCH 31/77] =?UTF-8?q?leetcode-19.=E5=88=A0=E9=99=A4=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E5=80=92=E6=95=B0=E7=AC=ACN=E4=B8=AA?= =?UTF-8?q?=E7=BB=93=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 53 +++++++++++++++++++ .../solution.h" | 18 +++++++ 3 files changed, 72 insertions(+) create mode 100644 "questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" create mode 100644 "questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/solution.h" diff --git a/README.md b/README.md index 8305046..4039d52 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ [18. 四数之和](https://leetcode-cn.com/problems/4sum/) +[19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) diff --git "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" new file mode 100644 index 0000000..81834f4 --- /dev/null +++ "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" @@ -0,0 +1,53 @@ +#include "stl.h" +/** + * Definition for singly-linked list. + */ +struct ListNode { + int val; + ListNode *next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode *next) : val(x), next(next) {} +}; +ostream & operator << (ostream & out, const ListNode & node){ + return out << node.val; +} +ostream & operator << (ostream & out, const ListNode * node){ + while(node){ + out << "\n" << hex << (long)node << ":" << node->val << "->" << (long)node->next; + node = node->next; + } + return out; +} +#include "solution.h" + +int main(int argc, char *argv[]){ + struct { + int n; + vector vals; + } testcases[] = { + {2, {1,2,3,4,5}}, + {1, {1}}, + {1, {1,2}}, + {2, {1,2}}, + }; + Solution sln; + for(auto &t:testcases){ + vector list; + list.reserve(t.vals.size()); + ListNode *head = NULL; + for(auto&v:t.vals){ + list.push_back(ListNode(v)); + if(head) head->next = &*(list.rbegin()); + head = &*(list.rbegin()); + + } + head = &*list.begin(); + print("list=", list, "\n"); + print(t.n, "th<-{", sln.removeNthFromEnd(head, t.n), "}\n") + print("listAfter=", list, "\n\n"); + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/solution.h" "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/solution.h" new file mode 100644 index 0000000..47ed8c8 --- /dev/null +++ "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/solution.h" @@ -0,0 +1,18 @@ +// #define print(...) +class Solution { +public: +ListNode* removeNthFromEnd(ListNode* head, int n) { + ListNode *pn=head, *pd=head, *pre=NULL; + for(int i=0; inext; + while(pn){ + pn = pn->next; + pre = pd; + pd = pd->next; + } + if(pre && pre->next) + pre->next = pre->next->next; + print("delete ", pd->val, ", set ", pd->val = -1, "\n") + return pd != head ? head : head->next; +} +}; -- Gitee From 1bed21f06b40589cdb62de14efc45a2b7f4c58bb Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 20:02:57 +0800 Subject: [PATCH 32/77] =?UTF-8?q?leetcode-20.=E6=9C=89=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=8B=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 22 +++++++++++++++++ .../solution.h" | 24 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 "questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/main.cpp" create mode 100644 "questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/solution.h" diff --git a/README.md b/README.md index 4039d52..213d86e 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ ## 栈 [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) +[20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) ## Hash [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) diff --git "a/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/main.cpp" "b/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/main.cpp" new file mode 100644 index 0000000..e7e3b4f --- /dev/null +++ "b/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/main.cpp" @@ -0,0 +1,22 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + string testcases[] = { + "()", + "()[]{}", + "(]", + "([)]", + "{[]}", + "[", + "((", + }; + Solution sln; + for(auto&t:testcases){ + print("case=", t, "\n") + print("ans:", sln.isValid(t), "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/solution.h" "b/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/solution.h" new file mode 100644 index 0000000..a665f70 --- /dev/null +++ "b/questions/20.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/solution.h" @@ -0,0 +1,24 @@ +// #define print(...) + +class Solution { +public: +bool isValid(string s) { + if(s.size()%2) return false; + list stk; + unordered_map match = { + {'(', ')'}, + {'[', ']'}, + {'{', '}'}, + }; + for(auto &c:s){ + if(match.count(c)){ + stk.push_back(c); + }else{ + if(stk.empty() || match[stk.back()] != c) + return false; + stk.pop_back(); + } + } + return stk.empty(); +} +}; -- Gitee From bb62f7d7c695e45c6924dae3b894e09e4109aafe Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 21:37:16 +0800 Subject: [PATCH 33/77] =?UTF-8?q?leetcode-21.=E5=90=88=E5=B9=B6=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=9C=89=E5=BA=8F=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++- include/linkedlist.h | 40 +++++++++++++++++++ .../main.cpp" | 31 +------------- .../main.cpp" | 24 +++++++++++ .../solution.h" | 16 ++++++++ 5 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 include/linkedlist.h create mode 100644 "questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" create mode 100644 "questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/solution.h" diff --git a/README.md b/README.md index 213d86e..0f5e4e5 100644 --- a/README.md +++ b/README.md @@ -53,11 +53,14 @@ [16. 最接近的三数之和](https://leetcode-cn.com/problems/3sum-closest/) [18. 四数之和](https://leetcode-cn.com/problems/4sum/) - -[19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) ## 数组 [169. 多数元素](https://leetcode-cn.com/problems/majority-element/)「摩尔投票」 [面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) + +## 链表 +[19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 + +[21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) \ No newline at end of file diff --git a/include/linkedlist.h b/include/linkedlist.h new file mode 100644 index 0000000..479c9a0 --- /dev/null +++ b/include/linkedlist.h @@ -0,0 +1,40 @@ +#ifndef linkedlist_h +#define linkedlist_h + +/** + * leetcode's Definition for singly-linked list. + */ +struct ListNode { + int val; + ListNode *next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode *next) : val(x), next(next) {} + + static ListNode* Link(vector &vals, vector *list){ + list->reserve(vals.size()); + ListNode *p = NULL; + for(auto&v:vals){ + list->push_back(ListNode(v)); + if(p) p->next = &*(list->rbegin()); + p = &*(list->rbegin()); + } + return list->size() ? &((*list)[0]) : NULL; + } +}; +ostream & operator << (ostream & out, const ListNode & node){ + return out << node.val; +} +ostream & operator << (ostream & out, const ListNode * node){ + out << "["; + while(node){ out + << " 0x" << hex << (long)node + << "=\"" << node->val << "\"" + << " → 0x" << (long)node->next + << "\n"; + node = node->next; + } out << "]"; + return out; +} + +#endif /* linkedlist_h */ diff --git "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" index 81834f4..a21f925 100644 --- "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" +++ "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" @@ -1,24 +1,5 @@ #include "stl.h" -/** - * Definition for singly-linked list. - */ -struct ListNode { - int val; - ListNode *next; - ListNode() : val(0), next(nullptr) {} - ListNode(int x) : val(x), next(nullptr) {} - ListNode(int x, ListNode *next) : val(x), next(next) {} -}; -ostream & operator << (ostream & out, const ListNode & node){ - return out << node.val; -} -ostream & operator << (ostream & out, const ListNode * node){ - while(node){ - out << "\n" << hex << (long)node << ":" << node->val << "->" << (long)node->next; - node = node->next; - } - return out; -} +#include "linkedlist.h" #include "solution.h" int main(int argc, char *argv[]){ @@ -34,15 +15,7 @@ int main(int argc, char *argv[]){ Solution sln; for(auto &t:testcases){ vector list; - list.reserve(t.vals.size()); - ListNode *head = NULL; - for(auto&v:t.vals){ - list.push_back(ListNode(v)); - if(head) head->next = &*(list.rbegin()); - head = &*(list.rbegin()); - - } - head = &*list.begin(); + auto head = ListNode::Link(t.vals, &list); print("list=", list, "\n"); print(t.n, "th<-{", sln.removeNthFromEnd(head, t.n), "}\n") print("listAfter=", list, "\n\n"); diff --git "a/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" new file mode 100644 index 0000000..7fe3ada --- /dev/null +++ "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" @@ -0,0 +1,24 @@ +#include "stl.h" +#include "linkedlist.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector testcases[][2] = { + {{1,2,4},{1,3,4}}, + {{},{0}}, + {{},{}}, + }; + Solution sln; + for(auto&t:testcases){ + vector L[2]; + ListNode* list[2]; + for(int i=0; ival <= l2->val ? &l1 : &l2); + pre->next = *s; + pre = *s; + *s = (*s)->next; + } + pre->next = (l1 ? l1 : l2); + return emptyHead.next; +} +}; -- Gitee From fd8e13887446e58db1494c6227264e7f4b4f327a Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 23:31:36 +0800 Subject: [PATCH 34/77] =?UTF-8?q?leetcode-22.=E6=8B=AC=E5=8F=B7=E7=94=9F?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- .../main.cpp" | 18 ++++++++++++++ .../solution.h" | 24 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 "questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/main.cpp" create mode 100644 "questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/solution.h" diff --git a/README.md b/README.md index 0f5e4e5..ada45da 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ ## 搜索 [17. 电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)「回溯」 +[22. 括号生成](https://leetcode-cn.com/problems/generate-parentheses/)「回溯」 + [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/)「BFS」 [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 @@ -63,4 +65,4 @@ ## 链表 [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 -[21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) \ No newline at end of file +[21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) diff --git "a/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/main.cpp" "b/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/main.cpp" new file mode 100644 index 0000000..07de8eb --- /dev/null +++ "b/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + int testcases[] = { + 3, + 1, + }; + Solution sln; + for(auto&t:testcases){ + print("n=", t, "\n") + auto res = sln.generateParenthesis(t); + print("res[", res.size(), "]:", res, "\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/solution.h" "b/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/solution.h" new file mode 100644 index 0000000..f2b17dd --- /dev/null +++ "b/questions/22.\346\213\254\345\217\267\347\224\237\346\210\220/solution.h" @@ -0,0 +1,24 @@ +// #define print(...) + +class Solution { +public: +vector generateParenthesis(int n) { + vector res; + string ans; + function bt = [&](size_t left, size_t right){ + if(ans.size() == n*2) res.push_back(ans); + if(left < n){ // 左括号数少于总长度(2n)一半 + ans.push_back('('); + bt(left+1, right); + ans.pop_back(); + } + if(right < left){ // 右括号数少于左括号 + ans.push_back(')'); + bt(left, right+1); + ans.pop_back(); + } + }; + bt(0,0); + return res; +} +}; -- Gitee From 18a20a0cec539199dc5e316fb66c0d05a79de446 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 11 Jul 2021 23:52:03 +0800 Subject: [PATCH 35/77] =?UTF-8?q?leetcode-23.=E5=90=88=E5=B9=B6K=E4=B8=AA?= =?UTF-8?q?=E5=8D=87=E5=BA=8F=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 24 +++++++++++++++++++ .../solution.h" | 7 ++++++ 3 files changed, 33 insertions(+) create mode 100644 "questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" create mode 100644 "questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/solution.h" diff --git a/README.md b/README.md index ada45da..556eff7 100644 --- a/README.md +++ b/README.md @@ -66,3 +66,5 @@ [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 [21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) + +[23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/) diff --git "a/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" new file mode 100644 index 0000000..ea22419 --- /dev/null +++ "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" @@ -0,0 +1,24 @@ +#include "stl.h" +#include "linkedlist.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector> testcases[] = { + { {1,4,5}, {1,3,4}, {2,6} }, + {}, + { {}, } + }; + Solution sln; + for(auto&t:testcases){ + vector lists; + vector< vector > vecs(t.size()); + for(int i=0; i& lists) { + return NULL; +} +}; -- Gitee From 675ace9594fe37ba09718b4af4a11f405c0653fc Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 12 Jul 2021 21:42:35 +0800 Subject: [PATCH 36/77] =?UTF-8?q?leetcode-23.=E5=90=88=E5=B9=B6K=E4=B8=AA?= =?UTF-8?q?=E5=8D=87=E5=BA=8F=E9=93=BE=E8=A1=A8(=E5=88=86=E6=B2=BB?= =?UTF-8?q?=E8=A7=A3=E6=B3=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- include/linkedlist.h | 16 ++++++++++++++++ .../solution.h" | 10 +--------- .../main.cpp" | 1 + .../solution.h" | 14 +++++++++++++- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 556eff7..5d4ad07 100644 --- a/README.md +++ b/README.md @@ -67,4 +67,4 @@ [21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) -[23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/) +[23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/)「分治」 diff --git a/include/linkedlist.h b/include/linkedlist.h index 479c9a0..0228c1a 100644 --- a/include/linkedlist.h +++ b/include/linkedlist.h @@ -37,4 +37,20 @@ ostream & operator << (ostream & out, const ListNode * node){ return out; } +// 链表相关函数命名空间 +namespace LinkedList{ + +ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + ListNode emptyHead, *pre = &emptyHead; + while(l1 && l2){ + auto s = (l1->val <= l2->val ? &l1 : &l2); + pre->next = *s; + pre = *s; + *s = (*s)->next; + } + pre->next = (l1 ? l1 : l2); + return emptyHead.next; +} + +}; // namespace LinkedList #endif /* linkedlist_h */ diff --git "a/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/solution.h" "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/solution.h" index 8596f2d..ac15820 100644 --- "a/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/solution.h" +++ "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/solution.h" @@ -3,14 +3,6 @@ class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { - ListNode emptyHead, *pre = &emptyHead; - while(l1 && l2){ - auto s = (l1->val <= l2->val ? &l1 : &l2); - pre->next = *s; - pre = *s; - *s = (*s)->next; - } - pre->next = (l1 ? l1 : l2); - return emptyHead.next; + return LinkedList::mergeTwoLists(l1, l2); } }; diff --git "a/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" index ea22419..d823497 100644 --- "a/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" +++ "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/main.cpp" @@ -1,5 +1,6 @@ #include "stl.h" #include "linkedlist.h" +using namespace LinkedList; #include "solution.h" int main(int argc, char *argv[]){ diff --git "a/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/solution.h" "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/solution.h" index 69ea741..0d14aa4 100644 --- "a/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/solution.h" +++ "b/questions/23.\345\220\210\345\271\266K\344\270\252\345\215\207\345\272\217\351\223\276\350\241\250/solution.h" @@ -1,7 +1,19 @@ // #define print(...) +using Iterator = vector::iterator; class Solution { public: ListNode* mergeKLists(vector& lists) { - return NULL; + if(lists.empty()) return NULL; + return DivideAndConquer(lists.begin(), + lists.begin()+lists.size()-1); +} +// 分治 +ListNode * DivideAndConquer(Iterator begin, Iterator end){ + if(begin == end) return *begin; + auto mid = begin + (end-begin)/2; + return mergeTwoLists( + DivideAndConquer(begin, mid), + DivideAndConquer(mid+1, end) + ); } }; -- Gitee From 4cdd1289f48a1df624531d8d82485a3b0c22b01e Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 12 Jul 2021 22:52:54 +0800 Subject: [PATCH 37/77] =?UTF-8?q?leetcode-24.=E4=B8=A4=E4=B8=A4=E4=BA=A4?= =?UTF-8?q?=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ include/linkedlist.h | 22 +++++++++---------- .../main.cpp" | 3 ++- .../main.cpp" | 3 ++- .../main.cpp" | 2 +- .../main.cpp" | 22 +++++++++++++++++++ .../solution.h" | 18 +++++++++++++++ 7 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 "questions/24.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271/main.cpp" create mode 100644 "questions/24.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271/solution.h" diff --git a/README.md b/README.md index 5d4ad07..ec06659 100644 --- a/README.md +++ b/README.md @@ -68,3 +68,5 @@ [21. 合并两个有序链表](https://leetcode-cn.com/problems/merge-two-sorted-lists/) [23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/)「分治」 + +[24. 两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) \ No newline at end of file diff --git a/include/linkedlist.h b/include/linkedlist.h index 0228c1a..553fa44 100644 --- a/include/linkedlist.h +++ b/include/linkedlist.h @@ -10,17 +10,6 @@ struct ListNode { ListNode() : val(0), next(nullptr) {} ListNode(int x) : val(x), next(nullptr) {} ListNode(int x, ListNode *next) : val(x), next(next) {} - - static ListNode* Link(vector &vals, vector *list){ - list->reserve(vals.size()); - ListNode *p = NULL; - for(auto&v:vals){ - list->push_back(ListNode(v)); - if(p) p->next = &*(list->rbegin()); - p = &*(list->rbegin()); - } - return list->size() ? &((*list)[0]) : NULL; - } }; ostream & operator << (ostream & out, const ListNode & node){ return out << node.val; @@ -39,6 +28,17 @@ ostream & operator << (ostream & out, const ListNode * node){ // 链表相关函数命名空间 namespace LinkedList{ + +ListNode* Link(vector &vals, vector *list){ + list->reserve(vals.size()); + ListNode *p = NULL; + for(auto&v:vals){ + list->push_back(ListNode(v)); + if(p) p->next = &*(list->rbegin()); + p = &*(list->rbegin()); + } + return list->size() ? &((*list)[0]) : NULL; +} ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode emptyHead, *pre = &emptyHead; diff --git "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" index a21f925..22ee095 100644 --- "a/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" +++ "b/questions/19.\345\210\240\351\231\244\351\223\276\350\241\250\347\232\204\345\200\222\346\225\260\347\254\254N\344\270\252\347\273\223\347\202\271/main.cpp" @@ -1,5 +1,6 @@ #include "stl.h" #include "linkedlist.h" +using namespace LinkedList; #include "solution.h" int main(int argc, char *argv[]){ @@ -15,7 +16,7 @@ int main(int argc, char *argv[]){ Solution sln; for(auto &t:testcases){ vector list; - auto head = ListNode::Link(t.vals, &list); + auto head = Link(t.vals, &list); print("list=", list, "\n"); print(t.n, "th<-{", sln.removeNthFromEnd(head, t.n), "}\n") print("listAfter=", list, "\n\n"); diff --git "a/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" index 7fe3ada..e4568e1 100644 --- "a/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" +++ "b/questions/21.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/main.cpp" @@ -1,5 +1,6 @@ #include "stl.h" #include "linkedlist.h" +using namespace LinkedList; #include "solution.h" int main(int argc, char *argv[]){ @@ -13,7 +14,7 @@ int main(int argc, char *argv[]){ vector L[2]; ListNode* list[2]; for(int i=0; i lists; vector< vector > vecs(t.size()); for(int i=0; i testcases[] = { + { 1,2,3,4 }, + {}, + {1}, + }; + Solution sln; + for(auto&t:testcases){ + vector list; + auto head = Link(t, &list); + print("before=", head, "\n") + print("after:", sln.swapPairs(head), "\n\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/24.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271/solution.h" "b/questions/24.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271/solution.h" new file mode 100644 index 0000000..07209ad --- /dev/null +++ "b/questions/24.\344\270\244\344\270\244\344\272\244\346\215\242\351\223\276\350\241\250\344\270\255\347\232\204\350\212\202\347\202\271/solution.h" @@ -0,0 +1,18 @@ +// #define print(...) +class Solution { +public: +ListNode* swapPairs(ListNode* head) { + if(!head || !head->next) return head; + ListNode ans(0, head); + auto t = &ans; + while(t->next && t->next->next){ + auto h2 = t->next->next; // h2 := 2 + t->next->next = h2->next; // 1->next := 3 + h2->next = t->next; // 2->next := 1 + t->next = h2; // t->next := 2 + t = h2->next; // t := 1 + print("t=", t, "\n", "ans=", ans.next, "\n"); + } + return ans.next; +} +}; -- Gitee From 9ad72cb00d5f8c548c7dc86de67a02a36b7d9b58 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 13 Jul 2021 09:28:21 +0800 Subject: [PATCH 38/77] =?UTF-8?q?leetcode-218.=E5=A4=A9=E9=99=85=E7=BA=BF?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 13 +++++++++++++ .../solution.h" | 7 +++++++ 3 files changed, 22 insertions(+) create mode 100644 "questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" create mode 100644 "questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" diff --git a/README.md b/README.md index ec06659..bc7bf3f 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ [815. 公交路线](https://leetcode-cn.com/problems/bus-routes/)「BFS」 [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 + +[218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/) ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" new file mode 100644 index 0000000..63e47f4 --- /dev/null +++ "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" @@ -0,0 +1,13 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector> testcases[] = { + {{2,9,10},{3,7,15},{5,12,12},{15,20,10},{19,24,8}}, + {{2,10},{3,15},{7,12},{12,0},{15,10},{20,8},{24,0}}, + } + Solution sln; + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" new file mode 100644 index 0000000..261d17d --- /dev/null +++ "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" @@ -0,0 +1,7 @@ +// #define print(...) + +class Solution { +public: +vector> getSkyline(vector>& buildings) { +} +}; -- Gitee From 6d7bce5785333d59d06932b68f66e1223e8c5390 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 13 Jul 2021 20:54:45 +0800 Subject: [PATCH 39/77] =?UTF-8?q?leetcode-218.=E5=A4=A9=E9=99=85=E7=BA=BF?= =?UTF-8?q?=E9=97=AE=E9=A2=98(maxheap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- include/virtualio.h | 4 ++++ .../main.cpp" | 8 +++++-- .../solution.h" | 23 ++++++++++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bc7bf3f..9cffe87 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 -[218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/) ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) @@ -37,6 +36,8 @@ [9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) +## 堆 +[218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/)「maxheap」 ## 栈 [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) diff --git a/include/virtualio.h b/include/virtualio.h index 1d6844c..cf69bed 100644 --- a/include/virtualio.h +++ b/include/virtualio.h @@ -39,6 +39,10 @@ public: if(v.empty()) return *this; return Out(v.begin(), v.end()); } + template OStream& operator<<(const std::multiset &v){ + if(v.empty()) return *this; + return Out(v.begin(), v.end()); + } template OStream& operator<<(const std::pair & pair){ (*this) << pair.first; (*po) << '='; diff --git "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" index 63e47f4..a412855 100644 --- "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" +++ "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/main.cpp" @@ -4,9 +4,13 @@ int main(int argc, char *argv[]){ vector> testcases[] = { {{2,9,10},{3,7,15},{5,12,12},{15,20,10},{19,24,8}}, - {{2,10},{3,15},{7,12},{12,0},{15,10},{20,8},{24,0}}, - } + {{0,2,3},{2,5,3}}, + }; Solution sln; + for(auto&t:testcases){ + print("building=", t, "\n") + print("skyline:", sln.getSkyline(t), "\n\n") + } print("\n------ main exit ------\n") return 0; diff --git "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" index 261d17d..ce913a0 100644 --- "a/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" +++ "b/questions/218.\345\244\251\351\231\205\347\272\277\351\227\256\351\242\230/solution.h" @@ -1,7 +1,28 @@ // #define print(...) - +using maxheap_t = multiset< int, greater >; class Solution { public: vector> getSkyline(vector>& buildings) { + vector> skyLn; // 天际线 + // 建筑左右两侧竖线 + vector> vLn; + vLn.reserve(buildings.size()*2); + for(auto&b:buildings){ + vLn.push_back({b[0],-b[2]}); // 左侧竖线 x_left, -h + vLn.push_back({b[1], b[2]}); // 右侧竖线 x_right, h + } + sort(vLn.begin(), vLn.end()); // 所有竖线沿 x 轴升序排列 + print("vLn=", vLn, "\n") + // 用大顶堆存沿线经过的建筑高度 + maxheap_t heights({0}); + for(auto &[x,h] : vLn){ + if(h < 0) heights.insert(-h); // 遇到左边,沿线进入建筑上空 + else heights.erase(heights.find(h)); // 遇到右边,沿线离开建筑上空 + if(skyLn.empty() || (*skyLn.rbegin())[1] != *heights.begin()){ + skyLn.push_back({x, *heights.begin()}); + print("(",x,",",*heights.begin(),") heights=", heights, "\n") + } + } + return skyLn; } }; -- Gitee From 1af54dd56bf51a7533002eeedc647b2cb2db87d8 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 13 Jul 2021 23:22:05 +0800 Subject: [PATCH 40/77] =?UTF-8?q?leetcode-206.=E5=8F=8D=E8=BD=AC=E9=93=BE?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- include/linkedlist.h | 14 +++++++++++++ .../main.cpp" | 21 +++++++++++++++++++ .../solution.h" | 8 +++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 "questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/main.cpp" create mode 100644 "questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/solution.h" diff --git a/README.md b/README.md index 9cffe87..5cefd2a 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,6 @@ [23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/)「分治」 -[24. 两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) \ No newline at end of file +[24. 两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) + +[206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/) diff --git a/include/linkedlist.h b/include/linkedlist.h index 553fa44..75603c0 100644 --- a/include/linkedlist.h +++ b/include/linkedlist.h @@ -52,5 +52,19 @@ ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { return emptyHead.next; } +ListNode* reverseList(ListNode* head) { + if(!head || !head->next) return head; + auto r = head->next; + head->next = NULL; + + while(r->next){ + auto N = r->next; r->next = head; + head = r; r = N; + } + + r->next = head; + return r; +} + }; // namespace LinkedList #endif /* linkedlist_h */ diff --git "a/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/main.cpp" "b/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/main.cpp" new file mode 100644 index 0000000..a1dd4df --- /dev/null +++ "b/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/main.cpp" @@ -0,0 +1,21 @@ +#include "stl.h" +#include "linkedlist.h" +using namespace LinkedList; +#include "solution.h" + +int main(int argc, char *argv[]){ + vector testcases[] = { + { 1,2,3,4,5 }, + { 1,2 }, + {}, + }; + Solution sln; + for(auto&t:testcases){ + vector vec; + auto list = Link(t, &vec); + print("list=", list, "\n") + print("reverse:", sln.reverseList(list), "\n\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/solution.h" "b/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/solution.h" new file mode 100644 index 0000000..e1de4f2 --- /dev/null +++ "b/questions/206.\345\217\215\350\275\254\351\223\276\350\241\250/solution.h" @@ -0,0 +1,8 @@ +// #define print(...) + +class Solution { +public: +ListNode* reverseList(ListNode* head) { + return LinkedList::reverseList(head); +} +}; -- Gitee From dcf0f4af7091bc405d13be278530dc3c326e9521 Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 14 Jul 2021 12:56:43 +0800 Subject: [PATCH 41/77] =?UTF-8?q?leetcode-1818.=E7=BB=9D=E5=AF=B9=E5=B7=AE?= =?UTF-8?q?=E5=80=BC=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++++---- .../main.cpp" | 18 ++++++++++++++++ .../solution.h" | 21 +++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 "questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/main.cpp" create mode 100644 "questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/solution.h" diff --git a/README.md b/README.md index 5cefd2a..8eaa208 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) [8. 字符串转换整数 (atoi)](https://leetcode-cn.com/problems/string-to-integer-atoi/) +## 数组 +[169. 多数元素](https://leetcode-cn.com/problems/majority-element/)「摩尔投票」 +[面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) + +[1818. 绝对差值和](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/)「二分查找」 ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) @@ -61,10 +66,6 @@ ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) -## 数组 -[169. 多数元素](https://leetcode-cn.com/problems/majority-element/)「摩尔投票」 -[面试题 17.10. 主要元素](https://leetcode-cn.com/problems/find-majority-element-lcci/) - ## 链表 [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 diff --git "a/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/main.cpp" "b/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/main.cpp" new file mode 100644 index 0000000..bdb37e5 --- /dev/null +++ "b/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + vector< vector > testcases[] = { + { {1,7,5}, {2,3,5} }, // 3 + { {2,4,6,8,10}, {2,4,6,8,10} }, // 0 + { {1,10,4,4,2,7}, {9,3,5,1,7,4}}, // 20 + { {5,4,7}, {10,8,10} }, // 9 + }; + Solution sln; + for(auto & t : testcases){ + print("case=", t, "\n") + print("ans:", sln.minAbsoluteSumDiff(t[0], t[1]), "\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/solution.h" "b/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/solution.h" new file mode 100644 index 0000000..e45040a --- /dev/null +++ "b/questions/1818.\347\273\235\345\257\271\345\267\256\345\200\274\345\222\214/solution.h" @@ -0,0 +1,21 @@ +// #define print(...) + +class Solution { + static constexpr int mod = 1'000'000'007; +public: +int minAbsoluteSumDiff(vector& nums1, vector& nums2) { + auto rec(nums1); + sort(rec.begin(), rec.end()); + int diffsum = 0, maxChg = 0; + for(int i=0; i Date: Wed, 14 Jul 2021 19:42:03 +0800 Subject: [PATCH 42/77] =?UTF-8?q?leetcode-25.K=E4=B8=AA=E4=B8=80=E7=BB=84?= =?UTF-8?q?=E7=BF=BB=E8=BD=AC=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ include/linkedlist.h | 17 ++++++++++-- .../main.cpp" | 26 +++++++++++++++++++ .../solution.h" | 26 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 "questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/main.cpp" create mode 100644 "questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/solution.h" diff --git a/README.md b/README.md index 8eaa208..668756c 100644 --- a/README.md +++ b/README.md @@ -76,3 +76,5 @@ [24. 两两交换链表中的节点](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/) + +[25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) \ No newline at end of file diff --git a/include/linkedlist.h b/include/linkedlist.h index 75603c0..9e3bc60 100644 --- a/include/linkedlist.h +++ b/include/linkedlist.h @@ -1,5 +1,6 @@ #ifndef linkedlist_h #define linkedlist_h +#include /** * leetcode's Definition for singly-linked list. @@ -17,9 +18,9 @@ ostream & operator << (ostream & out, const ListNode & node){ ostream & operator << (ostream & out, const ListNode * node){ out << "["; while(node){ out - << " 0x" << hex << (long)node + << " 0x" << hex << (int64_t)node << "=\"" << node->val << "\"" - << " → 0x" << (long)node->next + << " → 0x" << (int64_t)node->next << "\n"; node = node->next; } out << "]"; @@ -66,5 +67,17 @@ ListNode* reverseList(ListNode* head) { return r; } +std::pair reverseList(ListNode* head, ListNode* tail) { + if(!tail) return {head, NULL}; + auto ok = tail->next, todo = head; + while(todo){ + auto ntd = todo->next; + todo->next = ok; + ok = todo; + todo = ntd; + } + return {tail, head}; +} + }; // namespace LinkedList #endif /* linkedlist_h */ diff --git "a/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/main.cpp" "b/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/main.cpp" new file mode 100644 index 0000000..f584f18 --- /dev/null +++ "b/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/main.cpp" @@ -0,0 +1,26 @@ +#include "stl.h" +#include "linkedlist.h" +using namespace LinkedList; +#include "solution.h" + +int main(int argc, char *argv[]){ + struct { + int k; + vector head; + } testcases[] = { + {2, {1,2,3,4,5}}, + {3, {1,2,3,4,5}}, + {1, {1,2,3,4,5}}, + {1, {1}}, + }; + Solution sln; + for(auto & t: testcases){ + vector vec; + auto head = Link(t.head, &vec); + print("k=", t.k, ", list=", head, "\n") + print("reserved:", sln.reverseKGroup(head, t.k), "\n\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/solution.h" "b/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/solution.h" new file mode 100644 index 0000000..38f488b --- /dev/null +++ "b/questions/25.K\344\270\252\344\270\200\347\273\204\347\277\273\350\275\254\351\223\276\350\241\250/solution.h" @@ -0,0 +1,26 @@ +// #define print(...) + +class Solution { +public: +ListNode* reverseKGroup(ListNode* head, int k) { + if(k<=1) return head; + ListNode emptyHead(0, head); + auto before = &emptyHead; // 左边界 + while(auto after = before->next){ + for(int i=1;inext)) + return emptyHead.next; + auto front = before->next, back = after; + after = after->next; // 右边界 + back->next = NULL; + tie(front, back) = reverseList(front, back); + print("krev=", front, "\n") + // 插入原链表 + before->next = front; + back->next = after; + // 调整左边界 + before = back; + } + return emptyHead.next; +} +}; -- Gitee From cb81584be89331e17afae5503db6d4027ea30b24 Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 16 Jul 2021 13:24:15 +0800 Subject: [PATCH 43/77] =?UTF-8?q?leetcode-29.=E4=B8=A4=E6=95=B0=E7=9B=B8?= =?UTF-8?q?=E9=99=A4(=E5=80=8D=E5=A2=9E)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- .../main.cpp" | 27 +++++++++++++++++++ .../solution.h" | 26 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 "questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/main.cpp" create mode 100644 "questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/solution.h" diff --git a/README.md b/README.md index 668756c..7f373c0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 实践是检验真理的唯一标准 +# 日拱一卒,功不唐捐 ## 贪心 [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) @@ -41,6 +41,7 @@ [9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) +[29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers/) ## 堆 [218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/)「maxheap」 ## 栈 diff --git "a/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/main.cpp" "b/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/main.cpp" new file mode 100644 index 0000000..32920f5 --- /dev/null +++ "b/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/main.cpp" @@ -0,0 +1,27 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + struct { + int dividend; + int divisor; + } testcases[] = { + {10, 3}, + {7, -3}, + {0, 1}, + {1, 1}, + {-1,-1}, + {-1,1}, + {1,-1}, + {-2147483648, 1}, + {-2147483648, -2147483648}, + }; + Solution sln; + for(auto & t : testcases){ + auto ans = sln.divide(t.dividend, t.divisor); + print(t.dividend, "/", t.divisor, "=", ans, "\n\n") + } + + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/solution.h" "b/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/solution.h" new file mode 100644 index 0000000..d2aeaae --- /dev/null +++ "b/questions/29.\344\270\244\346\225\260\347\233\270\351\231\244/solution.h" @@ -0,0 +1,26 @@ +// #define print(...) +#define SIGN(a,b) ( ((a)^(b)) ) +class Solution { +public: + int divide(int dividend, int divisor) { + if(!dividend||!divisor) return 0; + if(INT_MIN==dividend && -1==divisor) return INT_MAX; + int64_t d = dividend, r = divisor, ans = 0, i = 0; + if(d<0) d=-d; if(r<0) r=-r; + while(SIGN(d, r)>=0){ + d -= (r<0 && SIGN(r, d+(r<=0) + i--; + // print("d(", d, ")+=", r< Date: Sat, 17 Jul 2021 22:48:13 +0800 Subject: [PATCH 44/77] =?UTF-8?q?=E5=BC=95=E5=85=A5=20vscode=20=E5=88=B7?= =?UTF-8?q?=E9=A2=98=E6=8F=92=E4=BB=B6supperchong.algorithm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/algm/ListNode.h | 12 + include/algm/TreeNode.h | 14 ++ include/algm/algm.h | 2 + include/algm/parse.h | 512 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 540 insertions(+) create mode 100755 include/algm/ListNode.h create mode 100755 include/algm/TreeNode.h create mode 100755 include/algm/algm.h create mode 100755 include/algm/parse.h diff --git a/include/algm/ListNode.h b/include/algm/ListNode.h new file mode 100755 index 0000000..384b628 --- /dev/null +++ b/include/algm/ListNode.h @@ -0,0 +1,12 @@ + +//Definition for singly-linked list. +#ifndef _LISTNODE +#define _LISTNODE +struct ListNode { + int val; + ListNode *next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode *next) : val(x), next(next) {} +}; +#endif \ No newline at end of file diff --git a/include/algm/TreeNode.h b/include/algm/TreeNode.h new file mode 100755 index 0000000..9676e14 --- /dev/null +++ b/include/algm/TreeNode.h @@ -0,0 +1,14 @@ + +// Definition for a binary tree node. +#ifndef _TREENODE +#define _TREENODE +struct TreeNode +{ + int val; + TreeNode *left; + TreeNode *right; + TreeNode() : val(0), left(nullptr), right(nullptr) {} + TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} +}; +#endif \ No newline at end of file diff --git a/include/algm/algm.h b/include/algm/algm.h new file mode 100755 index 0000000..b385bb4 --- /dev/null +++ b/include/algm/algm.h @@ -0,0 +1,2 @@ +#include "ListNode.h" +#include "TreeNode.h" \ No newline at end of file diff --git a/include/algm/parse.h b/include/algm/parse.h new file mode 100755 index 0000000..25a9aa8 --- /dev/null +++ b/include/algm/parse.h @@ -0,0 +1,512 @@ +#include +#include +#include +#include +#include +#include "algm.h" +// #include "ListNode.h" +// #include "TreeNode.h" +using namespace std; + +void split(string param, char seg, vector &arr) +{ + string temp = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (*it == seg) + { + arr.push_back(temp); + temp = ""; + } + else + { + temp += *it; + } + } + arr.push_back(temp); +} +int parseInteger(string param) +{ + return atoi(param.data()); +} +double parseFloat(string param) +{ + string::size_type size; + return stod(param, &size); +} +string serializeFloat(double param) +{ + string str = to_string(param); + return str.substr(0, str.length() - 1); +} +string serializeBool(bool t) +{ + if (t == true) + { + return "true"; + } + return "false"; +} +vector parseIntegerArr(string param) +{ + vector nums; + if (param.length() <= 2) + { + return nums; + } + string temp = ""; + string::iterator it; + for (it = param.begin() + 1; it != param.end() - 1; it++) + { + if (*it == ',') + { + nums.push_back(stoi(temp)); + temp = ""; + } + else + { + temp += *it; + } + } + if (temp != "") + { + nums.push_back(stoi(temp)); + } + return nums; +} +vector> parseIntegerArrArr(string param) +{ + vector> nums; + auto len = param.length(); + if (len <= 4) + { + return nums; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + vector arr = parseIntegerArr(temp); + nums.push_back(arr); + } + } + return nums; +} +string parseString(string param) +{ + if (param.length() <= 2) + { + return ""; + } + string out = ""; + string::iterator it; + for (int i = 1; i < param.length(); i++) + { + char c = param[i]; + if (c == '\\') + { + char n = param[i + 1]; + if (n == 'u') + { + string unicodeStr = param.substr(i + 2, 4); + char16_t num = strtol(unicodeStr.data(), NULL, 16); + out += num; + i += 5; + } + else + { + char echars[8] = {'"', '\\', '/', 'b', 'f', 'n', 'r', 't'}; + char realChars[8] = {'"', '\\', '/', '\b', '\f', '\n', '\r', '\t'}; + bool has = false; + for (int j = 0; j < 8; j++) + { + if (echars[j] == n) + { + has = true; + out += realChars[j]; + i++; + break; + } + } + if (!has) + { + throw "parse string error in " + param.substr(0, i + 1); + } + } + } + else if (c == '"') + { + return out; + } + else + { + out += c; + } + } + throw "parse string error in " + param; +} +vector parseStringArr(string param) +{ + vector strs; + auto len = param.length(); + + if (len <= 2) + { + return strs; + } + regex e("\"(\\\\.|[^\"\\\\])*\""); + std::regex_iterator rit(param.begin(), param.end(), e); + std::regex_iterator rend; + + while (rit != rend) + { + string str = rit->str(); + strs.push_back(parseString(str)); + ++rit; + } + return strs; +} +vector> parseStringArrArr(string param) +{ + vector> strs; + auto len = param.length(); + if (len <= 4) + { + return strs; + } + regex e("\"(\\\\.|[^\"\\\\])*\""); + regex_iterator rit(param.begin(), param.end(), e); + regex_iterator rend; + for (size_t i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + char nextChar = param[i + 1]; + string temp = "["; + i++; + while ((i < len - 1) && nextChar != ']') + { + + auto start = rit->position(); + auto end = start + rit->length(); + i = end; + nextChar = param[end]; + temp += param.substr(start, +rit->length()); + rit++; + } + i++; + temp += "]"; + + vector arr = parseStringArr(temp); + strs.push_back(arr); + } + } + return strs; +} + +TreeNode *parseTreeNode(string param) +{ + auto len = param.length(); + if (len <= 2) + { + return nullptr; + } + vector nodeData; + split(param.substr(1, len - 2), ',', nodeData); + if (nodeData.size() == 0) + { + return nullptr; + } + + int i = 0; + int val = stoi(nodeData[i++]); + TreeNode *root = new TreeNode(val); + queue q; + q.push(root); + while (q.size() > 0) + { + TreeNode *node = q.front(); + q.pop(); + if (i == nodeData.size()) + { + return root; + } + + string leftVal = nodeData[i++]; + if (leftVal != "null") + { + + node->left = new TreeNode(stoi(leftVal)); + q.push(node->left); + } + if (i == nodeData.size()) + { + return root; + } + string rightVal = nodeData[i++]; + if (rightVal != "null") + { + + node->right = new TreeNode(stoi(rightVal)); + q.push(node->right); + } + } + return root; +} +ListNode *parseListNode(string param) +{ + auto len = param.length(); + if (len <= 2) + { + return nullptr; + } + vector arr; + split(param.substr(1, len - 2), ',', arr); + ListNode *head = new ListNode(); + ListNode *p = head; + + for (auto it = arr.begin(); it != arr.end(); it++) + { + p->next = new ListNode(stoi(*it)); + p = p->next; + } + + return head->next; +} +vector parseListNodeArr(string param) +{ + vector result; + auto len = param.length(); + if (len <= 4) + { + return result; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + ListNode *arr = parseListNode(temp); + result.push_back(arr); + } + } + return result; +} +vector parseTreeNodeArr(string param) +{ + vector result; + auto len = param.length(); + if (len <= 4) + { + return result; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + TreeNode *arr = parseTreeNode(temp); + result.push_back(arr); + } + } + return result; +} + +string serializeInteger(int param) +{ + string str = to_string(param); + return str; +} +string serializeIntegerArr(vector &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeInteger(*it); + } + else + { + out += serializeInteger(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeIntegerArrArr(vector> &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeIntegerArr(*it); + } + else + { + out += serializeIntegerArr(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeString(string param) +{ + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (*it == '\\' || *it == '"') + { + out = out + "\\" + *it; + } + else + { + out += *it; + } + } + return "\"" + out + "\""; +} +string serializeStringArr(vector ¶m) +{ + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it == param.end() - 1) + { + out += serializeString(*it); + } + else + { + out += serializeString(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeStringArrArr(vector> ¶m) +{ + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it == param.end() - 1) + { + out += serializeStringArr(*it); + } + else + { + out += serializeStringArr(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeListNode(ListNode *head) +{ + string out = ""; + while (head != nullptr) + { + out += to_string(head->val); + head = head->next; + if (head != nullptr) + { + out += ","; + } + } + return "[" + out + "]"; +} +string serializeTreeNode(TreeNode *root) +{ + if (root == nullptr) + { + return "[]"; + } + + vector arr; + queue q; + q.push(root); + while (q.size() > 0) + { + + TreeNode *node = q.front(); + q.pop(); + if (node == nullptr) + { + arr.push_back("null"); + } + else + { + arr.push_back(to_string(node->val)); + q.push(node->left); + q.push(node->right); + } + } + + while (arr.back() == "null") + { + arr.pop_back(); + } + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += *it; + } + else + { + out += *it + ","; + } + } + return "[" + out + "]"; +} +string serializeListNodeArr(vector &lists) +{ + string out = ""; + for (auto it = lists.begin(); it != lists.end(); it++) + { + if (it == lists.end() - 1) + { + out += serializeListNode(*it); + } + else + { + out += serializeListNode(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeTreeNodeArr(vector &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeTreeNode(*it); + } + else + { + out += serializeTreeNode(*it) + ","; + } + } + return "[" + out + "]"; +} -- Gitee From 5f2fe1e013bed2d82451206b8a1fafd739208070 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 17 Jul 2021 23:31:45 +0800 Subject: [PATCH 45/77] =?UTF-8?q?JZ-42.=E8=BF=9E=E7=BB=AD=E5=AD=90?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E7=9A=84=E6=9C=80=E5=A4=A7=E5=92=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 18 ++++++++++++++++++ .../solution.h" | 17 +++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 "questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/main.cpp" create mode 100644 "questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/solution.h" diff --git a/README.md b/README.md index 7f373c0..0043265 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [10. 正则表达式匹配](https://leetcode-cn.com/problems/regular-expression-matching/) +[剑指 Offer 42.连续子数组的最大和](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/) ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 diff --git "a/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/main.cpp" "b/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/main.cpp" new file mode 100644 index 0000000..066bc91 --- /dev/null +++ "b/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[-2,1,-3,4,-1,2,1,-5,4]\"],[\"[1]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int result=s->maxSubArray(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/solution.h" "b/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/solution.h" new file mode 100644 index 0000000..e24b29b --- /dev/null +++ "b/questions/\345\211\221\346\214\207 Offer 42.\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/solution.h" @@ -0,0 +1,17 @@ +// @algorithm @lc id=100304 lang=cpp +// @title lian-xu-zi-shu-zu-de-zui-da-he-lcof + +// @test([-2,1,-3,4,-1,2,1,-5,4])=6 +// @test([1])=1 +class Solution { +public: + int maxSubArray(vector& nums) { + auto it=nums.begin(); + int dpMax = *it; + while(++it!=nums.end()){ + if(0<*(it-1)) *it+=*(it-1); + if(dpMax<*it) dpMax=*it; + } + return dpMax; + } +}; -- Gitee From cdc86a2afce9c8c6caf5c6d8c681cbb757086880 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 18 Jul 2021 12:12:50 +0800 Subject: [PATCH 46/77] =?UTF-8?q?LC-49.=E5=AD=97=E6=AF=8D=E5=BC=82?= =?UTF-8?q?=E4=BD=8D=E8=AF=8D=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++----- .../main.cpp" | 18 +++++++++++++++ .../solution.h" | 23 +++++++++++++++++++ .../main.cpp" | 18 +++++++++++++++ .../solution.h" | 20 ++++++++++++++++ 5 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 "questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/main.cpp" create mode 100644 "questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/solution.h" create mode 100644 "questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/main.cpp" create mode 100644 "questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/solution.h" diff --git a/README.md b/README.md index 0043265..a7778bc 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,14 @@ [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 +## Hash +[1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) + +[1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/)「互补 Key , 桶」 + +[1. 两数之和](https://leetcode-cn.com/problems/two-sum/)「互补 Key」 + +[49. 字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) 同 [面试题 10.02. 变位词组](https://leetcode-cn.com/problems/group-anagrams-lcci/) ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) @@ -49,12 +57,6 @@ [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) -## Hash -[1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) - -[1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/)「互补 Key , 桶」 - -[1. 两数之和](https://leetcode-cn.com/problems/two-sum/)「互补 Key」 ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/main.cpp" "b/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/main.cpp" new file mode 100644 index 0000000..19e0215 --- /dev/null +++ "b/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[\\\"eat\\\",\\\"tea\\\",\\\"tan\\\",\\\"ate\\\",\\\"nat\\\",\\\"bat\\\"]\"],[\"[\\\"\\\"]\"],[\"[\\\"a\\\"]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseStringArr(args[0]); + vector> result=s->groupAnagrams(arg0); + string resultabc =serializeStringArrArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/solution.h" "b/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/solution.h" new file mode 100644 index 0000000..8cfabb4 --- /dev/null +++ "b/questions/49.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/solution.h" @@ -0,0 +1,23 @@ +// @algorithm @lc id=49 lang=cpp +// @title group-anagrams + + +#define print(...) +// @test(["eat","tea","tan","ate","nat","bat"])=[["bat"],["nat","tan"],["ate","eat","tea"]] +// @test([""])=[[""]] +// @test(["a"])=[["a"]] +class Solution { +public: + vector> groupAnagrams(vector& strs) { + unordered_map> sameDist; + for(auto & original : strs){ + string ordered(original); + sort(ordered.begin(), ordered.end()); + sameDist[ordered].push_back(original); + } + vector< vector > ans; + for(auto & dists : sameDist) + ans.emplace_back(dists.second); + return ans; + } +}; \ No newline at end of file diff --git "a/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/main.cpp" "b/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/main.cpp" new file mode 100644 index 0000000..e94b43c --- /dev/null +++ "b/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[\\\"eat\\\",\\\"tea\\\",\\\"tan\\\",\\\"ate\\\",\\\"nat\\\",\\\"bat\\\"]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseStringArr(args[0]); + vector> result=s->groupAnagrams(arg0); + string resultabc =serializeStringArrArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/solution.h" "b/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/solution.h" new file mode 100644 index 0000000..dc1f18c --- /dev/null +++ "b/questions/\351\235\242\350\257\225\351\242\230 10.02.\345\217\230\344\275\215\350\257\215\347\273\204/solution.h" @@ -0,0 +1,20 @@ +// @algorithm @lc id=1000040 lang=cpp +// @title group-anagrams-lcci + + +// @test(["eat","tea","tan","ate","nat","bat"])=[["ate","eat","tea"],["nat","tan"],["bat"]] +class Solution { +public: + vector> groupAnagrams(vector& strs) { + unordered_map> sameDist; + for(auto & original : strs){ + string ordered(original); + sort(ordered.begin(), ordered.end()); + sameDist[ordered].push_back(original); + } + vector< vector > ans; + for(auto & dists : sameDist) + ans.emplace_back(dists.second); + return ans; + } +}; \ No newline at end of file -- Gitee From 04fa9414ca4515456278d3f0196db32a1719f15b Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 18 Jul 2021 12:53:56 +0800 Subject: [PATCH 47/77] =?UTF-8?q?=E5=AE=9A=E5=88=B6=20supperchong.algorith?= =?UTF-8?q?m-0.0.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/supperchong.algorithm/out/api/api.cn.js | 486 ++++++++++++ tools/supperchong.algorithm/out/api/api.js | 469 +++++++++++ tools/supperchong.algorithm/out/api/index.js | 163 ++++ .../supperchong.algorithm/out/babelPlugin.js | 119 +++ tools/supperchong.algorithm/out/cache.js | 118 +++ .../out/child_process/execTestCode.js | 160 ++++ tools/supperchong.algorithm/out/commands.js | 440 +++++++++++ .../supperchong.algorithm/out/common/lang.js | 5 + .../out/common/langConfig.js | 263 +++++++ .../out/common/parseContent.js | 279 +++++++ .../out/common/transformCode.js | 47 ++ .../supperchong.algorithm/out/common/util.js | 731 ++++++++++++++++++ .../out/common/website.js | 21 + tools/supperchong.algorithm/out/config.js | 351 +++++++++ tools/supperchong.algorithm/out/db.js | 37 + .../supperchong.algorithm/out/debug/launch.js | 97 +++ .../out/debugTask/index.js | 99 +++ .../supperchong.algorithm/out/execTestCode.js | 39 + tools/supperchong.algorithm/out/extension.js | 59 ++ .../out/fileStorage/crc32_table.js | 38 + .../out/fileStorage/db.js | 261 +++++++ .../out/fileStorage/util.js | 30 + .../out/history/answer.js | 121 +++ .../out/history/answerStorage.js | 19 + .../out/history/index.js | 176 +++++ .../out/history/storage.js | 129 ++++ .../out/history/submitStorage.js | 108 +++ .../out/lang/.common.js.swp | Bin 0 -> 12288 bytes .../out/lang/.cpp.js.swp | Bin 0 -> 24576 bytes tools/supperchong.algorithm/out/lang/base.js | 247 ++++++ tools/supperchong.algorithm/out/lang/bash.js | 60 ++ tools/supperchong.algorithm/out/lang/c.js | 375 +++++++++ .../supperchong.algorithm/out/lang/common.js | 68 ++ tools/supperchong.algorithm/out/lang/cpp.js | 395 ++++++++++ .../out/lang/database.js | 60 ++ .../supperchong.algorithm/out/lang/golang.js | 343 ++++++++ tools/supperchong.algorithm/out/lang/java.js | 385 +++++++++ .../out/lang/javascript.js | 158 ++++ .../supperchong.algorithm/out/lang/python.js | 400 ++++++++++ .../out/lang/typescript.js | 165 ++++ .../supperchong.algorithm/out/login/index.js | 251 ++++++ .../supperchong.algorithm/out/login/input.js | 287 +++++++ tools/supperchong.algorithm/out/memo/index.js | 81 ++ .../out/model/command.js | 3 + .../supperchong.algorithm/out/model/common.js | 47 ++ tools/supperchong.algorithm/out/model/memo.js | 3 + .../out/model/question.cn.js | 3 + .../out/model/question.js | 3 + tools/supperchong.algorithm/out/process.js | 37 + .../out/provider/codelensProvider.js | 125 +++ .../out/provider/completionProvider.js | 27 + .../out/provider/memoProvider.js | 185 +++++ .../out/provider/questionsProvider.js | 94 +++ .../out/provider/resolver.cn.js | 180 +++++ .../out/provider/resolver.js | 179 +++++ .../out/provider/snippetProvider.js | 43 ++ .../out/submitHistory/storage.js | 90 +++ .../out/submitHistory/util.js | 20 + tools/supperchong.algorithm/out/util.js | 249 ++++++ .../out/webview/buildCodeWebview.js | 133 ++++ .../out/webview/questionPreview.js | 301 ++++++++ .../out/webview/submitHistory.js | 194 +++++ 62 files changed, 10056 insertions(+) create mode 100644 tools/supperchong.algorithm/out/api/api.cn.js create mode 100644 tools/supperchong.algorithm/out/api/api.js create mode 100644 tools/supperchong.algorithm/out/api/index.js create mode 100644 tools/supperchong.algorithm/out/babelPlugin.js create mode 100644 tools/supperchong.algorithm/out/cache.js create mode 100644 tools/supperchong.algorithm/out/child_process/execTestCode.js create mode 100644 tools/supperchong.algorithm/out/commands.js create mode 100644 tools/supperchong.algorithm/out/common/lang.js create mode 100644 tools/supperchong.algorithm/out/common/langConfig.js create mode 100644 tools/supperchong.algorithm/out/common/parseContent.js create mode 100644 tools/supperchong.algorithm/out/common/transformCode.js create mode 100644 tools/supperchong.algorithm/out/common/util.js create mode 100644 tools/supperchong.algorithm/out/common/website.js create mode 100644 tools/supperchong.algorithm/out/config.js create mode 100644 tools/supperchong.algorithm/out/db.js create mode 100644 tools/supperchong.algorithm/out/debug/launch.js create mode 100644 tools/supperchong.algorithm/out/debugTask/index.js create mode 100644 tools/supperchong.algorithm/out/execTestCode.js create mode 100644 tools/supperchong.algorithm/out/extension.js create mode 100644 tools/supperchong.algorithm/out/fileStorage/crc32_table.js create mode 100644 tools/supperchong.algorithm/out/fileStorage/db.js create mode 100644 tools/supperchong.algorithm/out/fileStorage/util.js create mode 100644 tools/supperchong.algorithm/out/history/answer.js create mode 100644 tools/supperchong.algorithm/out/history/answerStorage.js create mode 100644 tools/supperchong.algorithm/out/history/index.js create mode 100644 tools/supperchong.algorithm/out/history/storage.js create mode 100644 tools/supperchong.algorithm/out/history/submitStorage.js create mode 100644 tools/supperchong.algorithm/out/lang/.common.js.swp create mode 100644 tools/supperchong.algorithm/out/lang/.cpp.js.swp create mode 100644 tools/supperchong.algorithm/out/lang/base.js create mode 100644 tools/supperchong.algorithm/out/lang/bash.js create mode 100644 tools/supperchong.algorithm/out/lang/c.js create mode 100644 tools/supperchong.algorithm/out/lang/common.js create mode 100644 tools/supperchong.algorithm/out/lang/cpp.js create mode 100644 tools/supperchong.algorithm/out/lang/database.js create mode 100644 tools/supperchong.algorithm/out/lang/golang.js create mode 100644 tools/supperchong.algorithm/out/lang/java.js create mode 100644 tools/supperchong.algorithm/out/lang/javascript.js create mode 100644 tools/supperchong.algorithm/out/lang/python.js create mode 100644 tools/supperchong.algorithm/out/lang/typescript.js create mode 100644 tools/supperchong.algorithm/out/login/index.js create mode 100644 tools/supperchong.algorithm/out/login/input.js create mode 100644 tools/supperchong.algorithm/out/memo/index.js create mode 100644 tools/supperchong.algorithm/out/model/command.js create mode 100644 tools/supperchong.algorithm/out/model/common.js create mode 100644 tools/supperchong.algorithm/out/model/memo.js create mode 100644 tools/supperchong.algorithm/out/model/question.cn.js create mode 100644 tools/supperchong.algorithm/out/model/question.js create mode 100644 tools/supperchong.algorithm/out/process.js create mode 100644 tools/supperchong.algorithm/out/provider/codelensProvider.js create mode 100644 tools/supperchong.algorithm/out/provider/completionProvider.js create mode 100644 tools/supperchong.algorithm/out/provider/memoProvider.js create mode 100644 tools/supperchong.algorithm/out/provider/questionsProvider.js create mode 100644 tools/supperchong.algorithm/out/provider/resolver.cn.js create mode 100644 tools/supperchong.algorithm/out/provider/resolver.js create mode 100644 tools/supperchong.algorithm/out/provider/snippetProvider.js create mode 100644 tools/supperchong.algorithm/out/submitHistory/storage.js create mode 100644 tools/supperchong.algorithm/out/submitHistory/util.js create mode 100644 tools/supperchong.algorithm/out/util.js create mode 100644 tools/supperchong.algorithm/out/webview/buildCodeWebview.js create mode 100644 tools/supperchong.algorithm/out/webview/questionPreview.js create mode 100644 tools/supperchong.algorithm/out/webview/submitHistory.js diff --git a/tools/supperchong.algorithm/out/api/api.cn.js b/tools/supperchong.algorithm/out/api/api.cn.js new file mode 100644 index 0000000..3990346 --- /dev/null +++ b/tools/supperchong.algorithm/out/api/api.cn.js @@ -0,0 +1,486 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getQuestionsByDifficult = exports.getQuestionsByTag = exports.getTags = exports.getQuestionsByCategory = exports.getCategories = exports.saveQuestionDetail = exports.getQuestionDetailById = exports.refreshQuestions = exports.getAllQuestions = exports.api = exports.MAPIDQUESTION = void 0; +const axios_1 = require("axios"); +const cache_1 = require("../cache"); +const common_1 = require("../model/common"); +const index_1 = require("../login/index"); +const db_1 = require("../db"); +const config_1 = require("../config"); +const util_1 = require("../util"); +exports.MAPIDQUESTION = 'MapIdQuestion'; +const monthEns = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december', +]; +const curCategories = [ + { + label: '面试题', + category_slug: 'lcci', + }, + { + label: '剑指 Offer', + category_slug: 'lcof', + }, +]; +function getHeaders() { + return __awaiter(this, void 0, void 0, function* () { + const cookie = yield cache_1.cache.getCookie(); + return Object.assign({ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36' }, cookie); + }); +} +// export async function fetchAllQuestions() { +// const url = 'https://leetcode-cn.com/graphql' +// const headers = await getHeaders() +// axios.request({ +// url, +// headers, +// data: { +// operationName: "getQuestionTranslation", +// query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, +// variables: {} +// } +// }) +// } +function request(config) { + return __awaiter(this, void 0, void 0, function* () { + const headers = yield getHeaders(); + return axios_1.default + .request(Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, config.headers), headers) })) + .then((res) => res.data) + .catch((err) => __awaiter(this, void 0, void 0, function* () { + if (err.response) { + if (err.response.status === common_1.ErrorStatus.Unlogin) { + index_1.showLoginMessage(); + } + else if (err.response.status === common_1.ErrorStatus.InvalidCookie) { + index_1.showLoginMessage(); + } + } + if (err.message) { + config_1.log.appendLine(err.message); + } + return Promise.reject(err); + })); + }); +} +function graphql(data) { + return __awaiter(this, void 0, void 0, function* () { + const headers = yield getHeaders(); + return request({ + url: 'https://leetcode-cn.com/graphql', + data, + method: 'POST', + headers: Object.assign({ origin: 'https://leetcode-cn.com', referer: 'https://leetcode-cn.com/problemset/all/' }, headers), + }).then((res) => { + if (res.errors) { + return Promise.reject(res.errors); + } + return res.data; + }); + }); +} +const config = { + allQuestions: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + getQuestionsByCategory(category) { + return { + url: `https://leetcode-cn.com/api/problems/${category}/`, + method: 'GET', + }; + }, + tags: { + url: 'https://leetcode-cn.com/problems/api/tags/', + referer: 'https://leetcode-cn.com/problemset/all/', + }, + contests: { + operationName: null, + variables: {}, + query: '{\n brightTitle\n allContests {\n title\n titleSlug\n startTime\n duration\n originStartTime\n isVirtual\n __typename\n }\n}\n', + }, + getChapters() { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChapters', + variables: { cardSlug: cardSlug }, + query: 'query GetChapters($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n descriptionText\n id\n title\n slug\n __typename\n }\n}\n', + }; + }, + getChapter(chapterId) { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChapter', + variables: { chapterId: chapterId, cardSlug: cardSlug }, + query: 'query GetChapter($chapterId: String, $cardSlug: String) {\n chapter(chapterId: $chapterId, cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n description\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + }; + }, + todayRecord: { + operationName: 'questionOfToday', + variables: {}, + query: 'query questionOfToday {\n todayRecord {\n question {\n questionFrontendId\n titleSlug\n translatedTitle\n __typename\n }\n lastSubmission {\n id\n __typename\n }\n date\n userStatus\n __typename\n }\n}\n', + }, + getDailyQuestionRecords() { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChaptersWithItems', + variables: { cardSlug: cardSlug }, + query: 'query GetChaptersWithItems($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n descriptionText\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + }; + }, + getContest(titleSlug) { + return { + url: `https://leetcode-cn.com/contest/api/info/${titleSlug}/`, + method: 'GET', + }; + }, + getQuestionDetail(titleSlug) { + return { + operationName: 'questionData', + variables: { titleSlug: titleSlug }, + query: 'query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\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 __typename\n }\n}\n', + }; + }, + getQuestionContest(titleSlug, weekname) { + return { + url: `https://leetcode-cn.com/contest/${weekname}/problems/${titleSlug}/`, + method: 'GET', + headers: { + referer: `https://leetcode-cn.com/contest/${weekname}/`, + }, + }; + }, + getSubmitContest(options) { + const { titleSlug, weekname, question_id, typed_code } = options; + common_1.checkParams(options, ['titleSlug', 'weekname', 'question_id', 'typed_code']); + return { + url: `https://leetcode-cn.com/contest/api/${weekname}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + 'x-requested-with': 'XMLHttpRequest', + origin: 'https://leetcode-cn.com', + referer: `https://leetcode-cn.com/contest/${weekname}/problems/${titleSlug}/`, + }, + data: { + question_id: question_id, + data_input: '', + lang: 'javascript', + typed_code: typed_code, + test_mode: false, + judge_type: 'large', + }, + }; + }, + getSubmit(options) { + const { titleSlug, question_id, typed_code, lang = 'javascript' } = options; + common_1.checkParams(options, ['titleSlug', 'question_id', 'typed_code']); + return { + url: `https://leetcode-cn.com/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + referer: `https://leetcode-cn.com/problems/${titleSlug}/submissions/`, + origin: 'https://leetcode-cn.com', + }, + data: { + question_id, + lang, + typed_code, + test_mode: false, + test_judger: '', + questionSlug: titleSlug, + }, + }; + }, + getCheck(options) { + const { submission_id, titleSlug } = options; + common_1.checkParams(options, ['submission_id', 'titleSlug']); + return { + url: `https://leetcode-cn.com/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `https://leetcode-cn.com/problems/${titleSlug}/submissions/`, + }, + }; + }, + getContestCheck(options) { + const { submission_id, titleSlug, weekname } = options; + common_1.checkParams(options, ['submission_id', 'titleSlug', 'weekname']); + return { + url: `https://leetcode-cn.com/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `https://leetcode-cn.com/contest/${weekname}/problems/${titleSlug}/`, + 'x-requested-with': 'XMLHttpRequest', + }, + }; + }, + getSubmissions(options) { + const { titleSlug, limit = 40, offset = 0, lastKey = null } = options; + return { + operationName: 'submissions', + variables: { + offset: offset, + limit: limit, + lastKey: lastKey, + questionSlug: titleSlug, + }, + query: 'query submissions($offset: Int!, $limit: Int!, $lastKey: String, $questionSlug: String!, $markedOnly: Boolean, $lang: String) {\n submissionList(offset: $offset, limit: $limit, lastKey: $lastKey, questionSlug: $questionSlug, markedOnly: $markedOnly, lang: $lang) {\n lastKey\n hasNext\n submissions {\n id\n statusDisplay\n lang\n runtime\n timestamp\n url\n isPending\n memory\n submissionComment {\n comment\n flagType\n __typename\n }\n __typename\n }\n __typename\n }\n}\n', + }; + }, + getUpdateComment(options) { + const { submissionId, flagType = common_1.FlagType.BLUE, comment } = options; + return { + operationName: 'submissionCreateOrUpdateSubmissionComment', + variables: { + submissionId: submissionId, + flagType: flagType, + comment: comment, + }, + query: 'mutation submissionCreateOrUpdateSubmissionComment($submissionId: ID!, $flagType: SubmissionFlagTypeEnum!, $comment: String!) {\n submissionCreateOrUpdateSubmissionComment(comment: $comment, flagType: $flagType, submissionId: $submissionId) {\n ok\n __typename\n }\n}\n', + }; + }, + getSubmissionDetail(options) { + const { id } = options; + return { + operationName: 'mySubmissionDetail', + variables: { id: id }, + query: 'query mySubmissionDetail($id: ID!) {\n submissionDetail(submissionId: $id) {\n id\n code\n runtime\n memory\n rawMemory\n statusDisplay\n timestamp\n lang\n passedTestCaseCnt\n totalTestCaseCnt\n sourceUrl\n question {\n titleSlug\n title\n translatedTitle\n questionId\n __typename\n }\n ... on GeneralSubmissionNode {\n outputDetail {\n codeOutput\n expectedOutput\n input\n compileError\n runtimeError\n lastTestcase\n __typename\n }\n __typename\n }\n submissionComment {\n comment\n flagType\n __typename\n }\n __typename\n }\n}\n', + }; + }, +}; +exports.api = { + refreshQuestions, + getAllQuestions, + fetchTranslations() { + return graphql(config.allQuestions).then((data) => data.translations); + }, + fetchCategorieQuestions(categorie) { + return request(config.getQuestionsByCategory(categorie)); + }, + fetchContests() { + return graphql(config.contests).then((data) => data.allContests); + }, + fetchTags() { + return request(config.tags); + }, + fetchContest(titleSlug) { + return request(config.getContest(titleSlug)); + }, + fetchTodayRecord() { + return graphql(config.todayRecord).then((data) => data.todayRecord); + }, + fetchDailyQuestionRecords() { + return graphql(config.getDailyQuestionRecords()).then((data) => data.dailyQuestionRecords); + }, + fetchQuestionDetail(titleSlug) { + if (cache_1.cache.get(titleSlug)) { + return cache_1.cache.get(titleSlug); + } + return graphql(config.getQuestionDetail(titleSlug)).then((data) => { + if (data && data.question && data.question.titleSlug === titleSlug) { + cache_1.cache.set(titleSlug, data.question); + } + return cache_1.cache.get(titleSlug); + }); + }, + fetchContestQuestionDetail(titleSlug, weekname) { + return request(config.getQuestionContest(titleSlug, weekname)); + }, + submit(options) { + return request(config.getSubmit(options)); + }, + submitContest(options) { + return request(config.getSubmitContest(options)); + }, + check(options) { + return request(config.getCheck(options)); + }, + checkContest(options) { + return request(config.getContestCheck(options)); + }, + fetchSubmissions(options) { + return graphql(config.getSubmissions(options)); + }, + updateComment(options) { + return graphql(config.getUpdateComment(options)); + }, + fetchSubmissionDetail(options) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const submissionDetail = yield graphql(config.getSubmissionDetail(options)); + if (submissionDetail.submissionDetail) { + return (_a = submissionDetail.submissionDetail) === null || _a === void 0 ? void 0 : _a.code; + } + else { + return 'can not query'; + } + }); + }, +}; +function getAllQuestions() { + return __awaiter(this, void 0, void 0, function* () { + const questions = cache_1.cache.getQuestions(); + if (questions.length) { + return questions; + } + yield refreshQuestions(); + return cache_1.cache.getQuestions(); + }); +} +exports.getAllQuestions = getAllQuestions; +function refreshQuestions() { + return __awaiter(this, void 0, void 0, function* () { + let questions = []; + const data = yield exports.api.fetchCategorieQuestions('all'); + questions = handleCategorieQuestions(data); + yield setTranslations(questions); + util_1.sortQuestions(questions); + cache_1.cache.setQuestions(questions); + }); +} +exports.refreshQuestions = refreshQuestions; +function getMapIdQuestion() { + return __awaiter(this, void 0, void 0, function* () { + if (cache_1.cache.has(exports.MAPIDQUESTION)) { + return cache_1.cache.get(exports.MAPIDQUESTION); + } + const questions = yield getAllQuestions(); + const map = {}; + for (let i = 0; i < questions.length; i++) { + const question = questions[i]; + map[question.id] = question; + } + cache_1.cache.set(exports.MAPIDQUESTION, map); + return map; + }); +} +function getQuestionDetailById(id) { + return __awaiter(this, void 0, void 0, function* () { + const db = yield db_1.getDb(); + const out = yield db.read(parseInt(id)); + if (out) { + return JSON.parse(out); + } + }); +} +exports.getQuestionDetailById = getQuestionDetailById; +function saveQuestionDetail(question) { + return __awaiter(this, void 0, void 0, function* () { + const db = yield db_1.getDb(); + yield db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)); + }); +} +exports.saveQuestionDetail = saveQuestionDetail; +function getCategories() { + return curCategories; +} +exports.getCategories = getCategories; +function getQuestionsByCategory(category) { + return __awaiter(this, void 0, void 0, function* () { + const c = curCategories.find((c) => c.category_slug === category); + if (!c) { + return []; + } + const label = c.label; + const questions = yield getAllQuestions(); + return questions.filter((q) => q.fid.startsWith(label)); + }); +} +exports.getQuestionsByCategory = getQuestionsByCategory; +function getTags() { + return __awaiter(this, void 0, void 0, function* () { + let tags = cache_1.cache.getTags(); + if (!tags) { + const data = yield exports.api.fetchTags(); + tags = data.topics; + cache_1.cache.setTags(tags); + } + return tags.map((tag) => tag.translatedName || tag.name); + }); +} +exports.getTags = getTags; +function getQuestionsByTag(translatedName) { + return __awaiter(this, void 0, void 0, function* () { + const tags = cache_1.cache.getTags() || []; + const tag = tags.find((tag) => tag.translatedName === translatedName || tag.name === translatedName); + if (tag && tag.questions) { + const map = yield getMapIdQuestion(); + return tag.questions.map((id) => map[id]).filter((v) => !!v); + } + return []; + }); +} +exports.getQuestionsByTag = getQuestionsByTag; +function getQuestionsByDifficult(difficult) { + return __awaiter(this, void 0, void 0, function* () { + const mapDifficultLevel = { + easy: 1, + medium: 2, + hard: 3, + }; + const questions = yield getAllQuestions(); + return questions.filter((q) => q.level === mapDifficultLevel[difficult]); + }); +} +exports.getQuestionsByDifficult = getQuestionsByDifficult; +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data; + const questions = stat_status_pairs.map((v) => ({ + fid: v.stat.frontend_question_id, + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })); + return questions; +} +function setTranslations(questions) { + return __awaiter(this, void 0, void 0, function* () { + const translationsQuestions = yield exports.api.fetchTranslations(); + const mapIdTitle = {}; + for (let i = 0; i < translationsQuestions.length; i++) { + const { questionId, title } = translationsQuestions[i]; + mapIdTitle[questionId] = title; + } + for (let i = 0; i < questions.length; i++) { + const question = questions[i]; + question.name = mapIdTitle[question.id] || question.title; + } + }); +} +//# sourceMappingURL=api.cn.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/api/api.js b/tools/supperchong.algorithm/out/api/api.js new file mode 100644 index 0000000..5c710f2 --- /dev/null +++ b/tools/supperchong.algorithm/out/api/api.js @@ -0,0 +1,469 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getQuestionsByDifficult = exports.getQuestionsByTag = exports.getTags = exports.saveQuestionDetail = exports.getQuestionDetailById = exports.refreshQuestions = exports.getAllQuestions = exports.fetchAllQuestions = exports.api = void 0; +const axios_1 = require("axios"); +const cache_1 = require("../cache"); +const common_1 = require("../model/common"); +const db_1 = require("../db"); +const common_2 = require("../model/common"); +const index_1 = require("../login/index"); +const config_1 = require("../config"); +const util_1 = require("../util"); +const util_2 = require("../common/util"); +const api_cn_1 = require("./api.cn"); +const monthEns = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december', +]; +function getHeaders() { + return __awaiter(this, void 0, void 0, function* () { + const cookie = yield cache_1.cache.getCookie(); + return Object.assign({ 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36' }, cookie); + }); +} +function request(config) { + return __awaiter(this, void 0, void 0, function* () { + const headers = yield getHeaders(); + return axios_1.default + .request(Object.assign(Object.assign({}, config), { headers: Object.assign(Object.assign({}, config.headers), headers) })) + .then((res) => res.data) + .catch((err) => __awaiter(this, void 0, void 0, function* () { + if (err.response) { + if (err.response.status === common_2.ErrorStatus.Unlogin) { + index_1.showLoginMessage(); + } + else if (err.response.status === common_2.ErrorStatus.InvalidCookie) { + index_1.showLoginMessage(); + } + } + if (err.message) { + config_1.log.appendLine(err.message); + } + return Promise.reject(err); + })); + }); +} +function graphql(data) { + return __awaiter(this, void 0, void 0, function* () { + const headers = yield getHeaders(); + return request({ + url: 'https://leetcode.com/graphql', + data, + method: 'POST', + headers: Object.assign({ origin: 'https://leetcode.com', referer: 'https://leetcode.com/problemset/all/' }, headers), + }).then((res) => { + if (res.errors) { + return Promise.reject(res.errors); + } + return res.data; + }); + }); +} +const config = { + allQuestions: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + getQuestionsByCategory(category) { + return { + url: `https://leetcode.com/api/problems/${category}/`, + method: 'GET', + }; + }, + tags: { + url: 'https://leetcode.com/problems/api/tags/', + referer: 'https://leetcode.com/problemset/all/', + }, + contests: { + operationName: null, + variables: {}, + query: '{\n brightTitle\n allContests {\n title\n titleSlug\n startTime\n duration\n originStartTime\n isVirtual\n __typename\n }\n}\n', + }, + getChapters() { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChapters', + variables: { cardSlug: cardSlug }, + query: 'query GetChapters($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n descriptionText\n id\n title\n slug\n __typename\n }\n}\n', + }; + }, + getChapter(chapterId) { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChapter', + variables: { chapterId: chapterId, cardSlug: cardSlug }, + query: 'query GetChapter($chapterId: String, $cardSlug: String) {\n chapter(chapterId: $chapterId, cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n description\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + }; + }, + getChapterItem(itemId) { + return { + operationName: 'GetItem', + variables: { itemId: itemId }, + query: 'query GetItem($itemId: String!) {\n item(id: $itemId) {\n id\n title\n type\n paidOnly\n lang\n isEligibleForCompletion\n hasAppliedTimeTravelTicket\n question {\n questionId\n title\n titleSlug\n __typename\n }\n article {\n id\n title\n __typename\n }\n video {\n id\n __typename\n }\n htmlArticle {\n id\n __typename\n }\n webPage {\n id\n __typename\n }\n __typename\n }\n isCurrentUserAuthenticated\n validTimeTravelTicketCount\n}\n', + }; + }, + getChaptersProgress() { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetOrCreateExploreSession', + variables: { cardSlug: cardSlug }, + query: 'mutation GetOrCreateExploreSession($cardSlug: String!) {\n getOrCreateExploreSession(cardSlug: $cardSlug) {\n ok\n errors\n progress\n cardId\n __typename\n }\n}\n', + }; + }, + getDailyQuestionRecords() { + const monthIndex = new Date().getMonth(); + const year = new Date().getFullYear(); + const monthEn = monthEns[monthIndex]; + const cardSlug = `${monthEn}-leetcoding-challenge-${year}`; + return { + operationName: 'GetChaptersWithItems', + variables: { cardSlug: cardSlug }, + query: 'query GetChaptersWithItems($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n descriptionText\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + }; + }, + getContest(titleSlug) { + return { + url: `https://leetcode.com/contest/api/info/${titleSlug}/`, + method: 'GET', + }; + }, + getQuestionDetail(titleSlug) { + return { + operationName: 'questionData', + variables: { titleSlug: titleSlug }, + query: 'query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\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 exampleTestcases\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\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 paidOnly\n hasVideoSolution\n paidOnlyVideo\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n enableTestMode\n enableDebugger\n envInfo\n libraryUrl\n adminUrl\n __typename\n }\n}\n', + }; + }, + getQuestionContest(titleSlug, weekname) { + return { + url: `https://leetcode.com/contest/${weekname}/problems/${titleSlug}/`, + method: 'GET', + headers: { + referer: `https://leetcode.com/contest/${weekname}/`, + }, + }; + }, + getSubmitContest(options) { + const { titleSlug, weekname, question_id, typed_code } = options; + common_1.checkParams(options, ['titleSlug', 'weekname', 'question_id', 'typed_code']); + return { + url: `https://leetcode.com/contest/api/${weekname}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + 'x-requested-with': 'XMLHttpRequest', + origin: 'https://leetcode.com', + referer: `https://leetcode.com/contest/${weekname}/problems/${titleSlug}/`, + }, + data: { + question_id: question_id, + data_input: '', + lang: 'javascript', + typed_code: typed_code, + test_mode: false, + judge_type: 'large', + }, + }; + }, + getSubmit(options) { + const { titleSlug, question_id, typed_code, lang = 'javascript' } = options; + common_1.checkParams(options, ['titleSlug', 'question_id', 'typed_code']); + return { + url: `https://leetcode.com/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + referer: `https://leetcode.com/problems/${titleSlug}/submissions/`, + origin: 'https://leetcode.com', + }, + data: { + question_id, + lang, + typed_code, + test_mode: false, + test_judger: '', + questionSlug: titleSlug, + }, + }; + }, + getCheck(options) { + const { submission_id, titleSlug } = options; + common_1.checkParams(options, ['submission_id', 'titleSlug']); + return { + url: `https://leetcode.com/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `https://leetcode.com/problems/${titleSlug}/submissions/`, + }, + }; + }, + getContestCheck(options) { + const { submission_id, titleSlug, weekname } = options; + common_1.checkParams(options, ['submission_id', 'titleSlug', 'weekname']); + return { + url: `https://leetcode.com/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `https://leetcode.com/contest/${weekname}/problems/${titleSlug}/`, + 'x-requested-with': 'XMLHttpRequest', + }, + }; + }, + getSubmissions(options) { + const { titleSlug, limit = 40, offset = 0, lastKey = null } = options; + return { + operationName: 'Submissions', + variables: { + questionSlug: titleSlug, + offset: offset, + limit: limit, + lastKey: lastKey, + }, + query: 'query Submissions($offset: Int!, $limit: Int!, $lastKey: String, $questionSlug: String!) {\n submissionList(offset: $offset, limit: $limit, lastKey: $lastKey, questionSlug: $questionSlug) {\n lastKey\n hasNext\n submissions {\n id\n statusDisplay\n lang\n runtime\n timestamp\n url\n isPending\n memory\n __typename\n }\n __typename\n }\n}\n', + }; + }, + getSubmissionDetail(options) { + const { id: submission_id } = options; + return { + url: `https://leetcode.com/submissions/detail/${submission_id}/`, + method: 'GET', + headers: { + 'x-requested-with': 'XMLHttpRequest', + }, + }; + }, +}; +exports.api = { + refreshQuestions, + getAllQuestions, + fetchCategorieQuestions(categorie) { + return request(config.getQuestionsByCategory(categorie)); + }, + fetchContests() { + return graphql(config.contests).then((data) => data.allContests); + }, + fetchTags() { + return request(config.tags); + }, + fetchContest(titleSlug) { + return request(config.getContest(titleSlug)); + }, + fetchChapters() { + return graphql(config.getChapters()); + }, + fetchChapter(chapterId) { + return graphql(config.getChapter(chapterId)); + }, + fetchChapterProgress() { + return graphql(config.getChaptersProgress()); + }, + fetchDailyQuestionRecords() { + return graphql(config.getDailyQuestionRecords()).then((data) => data.dailyQuestionRecords); + }, + fetchChapterItem(id) { + return graphql(config.getChapterItem(id)); + }, + fetchQuestionDetailByItemId(id) { + return __awaiter(this, void 0, void 0, function* () { + const { item } = yield exports.api.fetchChapterItem(id); + return exports.api.fetchQuestionDetail(item.question.titleSlug); + }); + }, + fetchQuestionDetail(titleSlug) { + if (cache_1.cache.get(titleSlug)) { + return cache_1.cache.get(titleSlug); + } + return graphql(config.getQuestionDetail(titleSlug)).then((data) => { + if (data && data.question && data.question.titleSlug === titleSlug) { + cache_1.cache.set(titleSlug, data.question); + } + return cache_1.cache.get(titleSlug); + }); + }, + fetchContestQuestionDetail(titleSlug, weekname) { + return request(config.getQuestionContest(titleSlug, weekname)); + }, + submit(options) { + return request(config.getSubmit(options)); + }, + submitContest(options) { + return request(config.getSubmitContest(options)); + }, + check(options) { + return request(config.getCheck(options)); + }, + checkContest(options) { + return request(config.getContestCheck(options)); + }, + fetchSubmissions(options) { + return graphql(config.getSubmissions(options)); + }, + fetchSubmissionDetail(options) { + return __awaiter(this, void 0, void 0, function* () { + const html = yield request(config.getSubmissionDetail(options)); + const detail = handleSubmissionDetail(html); + if (typeof detail === 'undefined') { + return Promise.reject('can not query'); + } + return detail; + }); + }, +}; +function fetchAllQuestions() { + return __awaiter(this, void 0, void 0, function* () { + const url = 'https://leetcode.com/graphql'; + const headers = yield getHeaders(); + axios_1.default.request({ + url, + headers, + data: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + }); + }); +} +exports.fetchAllQuestions = fetchAllQuestions; +function getAllQuestions() { + return __awaiter(this, void 0, void 0, function* () { + const questions = cache_1.cache.getQuestions(); + if (questions.length) { + return questions; + } + yield refreshQuestions(); + return cache_1.cache.getQuestions(); + }); +} +exports.getAllQuestions = getAllQuestions; +function refreshQuestions() { + return __awaiter(this, void 0, void 0, function* () { + let questions = []; + const data = yield exports.api.fetchCategorieQuestions('all'); + questions = handleCategorieQuestions(data); + util_1.sortQuestions(questions); + cache_1.cache.setQuestions(questions); + }); +} +exports.refreshQuestions = refreshQuestions; +function getMapIdQuestion() { + return __awaiter(this, void 0, void 0, function* () { + if (cache_1.cache.has(api_cn_1.MAPIDQUESTION)) { + return cache_1.cache.get(api_cn_1.MAPIDQUESTION); + } + const questions = yield getAllQuestions(); + const map = {}; + for (let i = 0; i < questions.length; i++) { + const question = questions[i]; + map[question.id] = question; + } + cache_1.cache.set(api_cn_1.MAPIDQUESTION, map); + return map; + }); +} +function getQuestionDetailById(id) { + return __awaiter(this, void 0, void 0, function* () { + const db = yield db_1.getDb(); + const out = yield db.read(parseInt(id)); + if (out) { + return JSON.parse(out); + } + }); +} +exports.getQuestionDetailById = getQuestionDetailById; +function saveQuestionDetail(question) { + return __awaiter(this, void 0, void 0, function* () { + const db = yield db_1.getDb(); + yield db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)); + }); +} +exports.saveQuestionDetail = saveQuestionDetail; +function getTags() { + return __awaiter(this, void 0, void 0, function* () { + let tags = cache_1.cache.getTags() || []; + if (!tags) { + const data = yield exports.api.fetchTags(); + tags = data.topics; + cache_1.cache.setTags(tags); + } + return tags.map((tag) => tag.translatedName || tag.name); + }); +} +exports.getTags = getTags; +function getQuestionsByTag(translatedName) { + return __awaiter(this, void 0, void 0, function* () { + const tags = cache_1.cache.getTags() || []; + const tag = tags.find((tag) => tag.translatedName === translatedName || tag.name === translatedName); + if (tag && tag.questions) { + const map = yield getMapIdQuestion(); + return tag.questions.map((id) => map[id]).filter((v) => !!v); + } + return []; + }); +} +exports.getQuestionsByTag = getQuestionsByTag; +function getQuestionsByDifficult(difficult) { + return __awaiter(this, void 0, void 0, function* () { + const mapDifficultLevel = { + easy: 1, + medium: 2, + hard: 3, + }; + const questions = yield getAllQuestions(); + return questions.filter((q) => q.level === mapDifficultLevel[difficult]); + }); +} +exports.getQuestionsByDifficult = getQuestionsByDifficult; +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data; + const questions = stat_status_pairs.map((v) => ({ + fid: String(v.stat.frontend_question_id), + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })); + return questions; +} +function handleSubmissionDetail(html) { + const question = util_2.parseSubmissionDetailHtml(html); + if (question) { + return question.submissionCode; + } + else { + return; + } +} +//# sourceMappingURL=api.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/api/index.js b/tools/supperchong.algorithm/out/api/index.js new file mode 100644 index 0000000..39b08af --- /dev/null +++ b/tools/supperchong.algorithm/out/api/index.js @@ -0,0 +1,163 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.apiCn = exports.apiEn = exports.refreshQuestions = exports.api = void 0; +const config_1 = require("../config"); +const apiCn = require("./api.cn"); +exports.apiCn = apiCn; +const apiEn = require("./api"); +exports.apiEn = apiEn; +const db_1 = require("../db"); +exports.api = { + fetchQuestionDetailById(id) { + return __awaiter(this, void 0, void 0, function* () { + if (typeof id === 'string') { + id = parseInt(id); + } + const db = yield db_1.getDb(); + const out = yield db.read(id); + if (out) { + return JSON.parse(out); + } + }); + }, + fetchQuestionDetail(titleSlug) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.fetchQuestionDetail(titleSlug); + } + else { + return apiCn.api.fetchQuestionDetail(titleSlug); + } + }); + }, + fetchContestQuestionDetail(titleSlug, weekname) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.fetchContestQuestionDetail(titleSlug, weekname); + } + else { + return apiCn.api.fetchContestQuestionDetail(titleSlug, weekname); + } + }); + }, + fetchQuestionByItemId(id) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + const res = yield apiEn.api.fetchChapterItem(id); + return res.item.question; + } + }); + }, + saveQuestionDetail(question) { + return __awaiter(this, void 0, void 0, function* () { + const db = yield db_1.getDb(); + yield db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)); + }); + }, + submitContest(options) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.submitContest(options); + } + else { + return apiCn.api.submitContest(options); + } + }); + }, + submit(options) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.submit(options); + } + else { + return apiCn.api.submit(options); + } + }); + }, + check(options) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.check(options); + } + else { + return apiCn.api.check(options); + } + }); + }, + checkContest(options) { + if (config_1.config.lang === 'en') { + return apiEn.api.checkContest(options); + } + else { + return apiCn.api.checkContest(options); + } + }, + getAllQuestions() { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.getAllQuestions(); + } + else { + return apiCn.api.getAllQuestions(); + } + }); + }, + fetchSubmissions(options) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.fetchSubmissions(options); + } + else { + return apiCn.api.fetchSubmissions(options); + } + }); + }, + fetchSubmissionDetail(options) { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + return apiEn.api.fetchSubmissionDetail(options); + } + else { + return apiCn.api.fetchSubmissionDetail(options); + } + }); + }, +}; +function refreshQuestions() { + return __awaiter(this, void 0, void 0, function* () { + if (config_1.config.lang === 'en') { + yield apiEn.api.refreshQuestions(); + } + else { + yield apiCn.api.refreshQuestions(); + } + }); +} +exports.refreshQuestions = refreshQuestions; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data; + const questions = stat_status_pairs.map((v) => ({ + fid: String(v.stat.frontend_question_id), + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })); + return questions; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/babelPlugin.js b/tools/supperchong.algorithm/out/babelPlugin.js new file mode 100644 index 0000000..a7f974b --- /dev/null +++ b/tools/supperchong.algorithm/out/babelPlugin.js @@ -0,0 +1,119 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.removeExtraTypePlugin = exports.generateAddTestCommentPlugin = exports.outBoundArrayPlugin = void 0; +const core_1 = require("@babel/core"); +const regexp = /^@get\((-?\d+|Infinity|-Infinity)\)$/; +function generatelogicalExpression(arr) { + if (arr.length === 2) { + return core_1.types.logicalExpression('&&', arr[0], arr[1]); + } + else if (arr.length > 2) { + return core_1.types.logicalExpression('&&', arr[0], generatelogicalExpression(arr.slice(1))); + } + else { + return arr[0]; + } +} +function toBinaryExpression(node) { + return core_1.types.binaryExpression('>=', node, core_1.types.numericLiteral(0)); +} +function isValidNumberProperty(property) { + return property.type === 'Identifier' || property.type === 'NumericLiteral' || property.type === 'BinaryExpression'; +} +function isValidComputeProperty(property) { + return property.type === 'Identifier' || property.type === 'BinaryExpression'; +} +function outBoundArrayPlugin() { + return { + visitor: { + VariableDeclaration(path) { + if (core_1.types.isVariableDeclaration(path.node) && + path.node.leadingComments && + path.node.leadingComments.find((v) => regexp.test(v.value))) { + const comment = path.node.leadingComments.find((v) => regexp.test(v.value)); + const regexpResult = regexp.exec(comment.value); + const numStr = regexpResult[1]; + let numNode; + if (numStr === 'Infinity') { + numNode = core_1.types.identifier('Infinity'); + } + else if (numStr === '-Infinity') { + numNode = core_1.types.unaryExpression('-', core_1.types.identifier('Infinity')); + } + else { + numNode = core_1.types.numericLiteral(parseInt(numStr)); + } + const declaration = path.node.declarations[0]; + const id = declaration.id; + if (!core_1.types.isIdentifier(id)) { + return; + } + const name = id.name; + const bind = path.scope.bindings[name]; + const referencePaths = bind.referencePaths; + referencePaths.forEach((r) => { + let nodes = []; + while (r.parentPath.node.type === 'MemberExpression' && r.parentPath.node.computed) { + const node = r.parentPath.node; + if (!isValidNumberProperty(node.property)) { + return; + } + if (isValidComputeProperty(node.property)) { + nodes.push(node.property); + } + r = r.parentPath; + } + if (nodes.length && !(r.key === 'left' && r.parentPath.type === 'AssignmentExpression')) { + nodes = nodes.map((node) => toBinaryExpression(node)); + r.replaceWith(core_1.types.conditionalExpression(generatelogicalExpression(nodes), r.node, numNode)); + } + }); + } + }, + }, + }; +} +exports.outBoundArrayPlugin = outBoundArrayPlugin; +function generateAddTestCommentPlugin(funcName, comment) { + return function addTestCommentPlugin() { + return { + visitor: { + VariableDeclaration(path) { + const funcDeclaration = path.node.declarations.find((dec) => { + var _a; + return (dec.id.type === 'Identifier' && + dec.id.name === funcName && + ((_a = dec.init) === null || _a === void 0 ? void 0 : _a.type) === 'FunctionExpression'); + }); + if (funcDeclaration) { + path.addComment('leading', comment, true); + path.stop(); + } + }, + FunctionDeclaration(path) { + var _a; + const name = (_a = path.node.id) === null || _a === void 0 ? void 0 : _a.name; + if (name === funcName) { + path.addComment('leading', comment, true); + path.stop(); + } + }, + }, + }; + }; +} +exports.generateAddTestCommentPlugin = generateAddTestCommentPlugin; +function removeExtraTypePlugin() { + return { + visitor: { + ClassDeclaration(path) { + const extraTypes = ['ListNode', 'TreeNode']; + if (path.node.id && extraTypes.includes(path.node.id.name)) { + path.remove(); + } + }, + }, + }; +} +exports.removeExtraTypePlugin = removeExtraTypePlugin; +//# sourceMappingURL=babelPlugin.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/cache.js b/tools/supperchong.algorithm/out/cache.js new file mode 100644 index 0000000..6007218 --- /dev/null +++ b/tools/supperchong.algorithm/out/cache.js @@ -0,0 +1,118 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cache = exports.MAPIDQUESTION = exports.ALLQUESTIONS = void 0; +const fs = require("fs"); +const config_1 = require("./config"); +const util_1 = require("./util"); +const COOKIE = 'cookie'; +const TAG = 'tag'; +exports.ALLQUESTIONS = 'allQuestions'; +exports.MAPIDQUESTION = 'MapIdQuestion'; +class Cache { + constructor() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + this.cacheMap = {}; + this.config = config_1.config; + } + removeCache() { + this.cacheMap = {}; + } + get(key) { + return this.cacheMap[key]; + } + set(key, value) { + this.cacheMap[key] = value; + } + has(key) { + return key in this.cacheMap; + } + getCookie() { + return __awaiter(this, void 0, void 0, function* () { + const { cookiePath } = config_1.config; + if (this.has(COOKIE)) { + return this.get(COOKIE); + } + try { + const cookie = util_1.reRequire(cookiePath); + this.set(COOKIE, cookie); + return this.get(COOKIE); + } + catch (err) { + return null; + } + }); + } + getQuestions() { + const { questionPath } = config_1.config; + if (this.has(exports.ALLQUESTIONS)) { + return this.get(exports.ALLQUESTIONS) || []; + } + try { + const allQuestions = util_1.reRequire(questionPath); + const filterPrivilegeQuestions = allQuestions.filter((v) => !v.paid_only); + this.set(exports.ALLQUESTIONS, filterPrivilegeQuestions); + return this.get(exports.ALLQUESTIONS) || []; + } + catch (err) { + return []; + } + } + setQuestions(questions) { + const { questionPath } = config_1.config; + const filterPrivilegeQuestions = questions.filter((v) => !v.paid_only); + this.set(exports.ALLQUESTIONS, filterPrivilegeQuestions); + fs.writeFile(questionPath, JSON.stringify(filterPrivilegeQuestions), { + encoding: 'utf8', + }, (err) => { + if (err) { + config_1.log.append(err.message); + } + }); + } + updateQuestion(id, params) { + const questions = this.get(exports.ALLQUESTIONS); + if (questions) { + const question = questions.find((q) => q.id === id); + if (question) { + Object.assign(question, params); + this.setQuestions(questions); + } + } + } + getTags() { + const { tagPath } = config_1.config; + if (this.has(TAG)) { + return this.get(TAG); + } + try { + const tags = util_1.reRequire(tagPath); + this.set(TAG, tags); + return this.get(TAG); + } + catch (err) { + return null; + } + } + setTags(tags) { + const { tagPath } = config_1.config; + this.set(TAG, tags); + fs.writeFile(tagPath, JSON.stringify(tags), { + encoding: 'utf8', + }, (err) => { + if (err) { + config_1.log.append(err.message); + } + }); + } +} +exports.cache = new Cache(); +//# sourceMappingURL=cache.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/child_process/execTestCode.js b/tools/supperchong.algorithm/out/child_process/execTestCode.js new file mode 100644 index 0000000..ca596cc --- /dev/null +++ b/tools/supperchong.algorithm/out/child_process/execTestCode.js @@ -0,0 +1,160 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const rollup = require("rollup"); +const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve"); +const plugin_babel_1 = require("@rollup/plugin-babel"); +const core_1 = require("@babel/core"); +const virtual = require("@rollup/plugin-virtual"); +const path = require("path"); +const fs = require("fs"); +const sourceMap = require("source-map"); +const util_1 = require("../common/util"); +const babelPlugin_1 = require("../babelPlugin"); +const vm_1 = require("vm"); +const util_2 = require("../common/util"); +const langConfig_1 = require("../common/langConfig"); +const presetTs = require("@babel/preset-typescript"); +const defaultTimeout = 10000; +const supportCodeLang = [langConfig_1.CodeLang.JavaScript, langConfig_1.CodeLang.TypeScript]; +let options = ''; +process.stdin.on('data', (data) => { + options += data; +}); +process.stdin.on('end', () => __awaiter(void 0, void 0, void 0, function* () { + try { + const msg = yield execTestCase(JSON.parse(options.toString())); + console.log(msg); + } + catch (err) { + console.log(err); + } +})); +function execTestCase(options) { + return __awaiter(this, void 0, void 0, function* () { + const { caseList, filePath, metaData } = options; + const lang = langConfig_1.getFileLang(filePath); + if (!supportCodeLang.includes(lang)) { + return `${lang} is currently not supported`; + } + const output = yield buildCode(filePath, lang); + const code = output[0].code; + const list = []; + for (const { args, result: expect } of caseList) { + const originArgs = [...args]; + const finalCode = util_1.handleArgsType(metaData, code, args); + const script = new vm_1.Script(finalCode, {}); + try { + const result = script.runInNewContext({ + console, + }, { + timeout: defaultTimeout, + displayErrors: true, + lineOffset: 0, + }); + list.push({ + args: originArgs.join(','), + expect: expect, + result: result, + }); + } + catch (err) { + return handleErrPosition(err, output[0].map, originArgs); + } + } + return util_2.handleMsg(list); + }); +} +function buildCode(filePath, lang) { + return __awaiter(this, void 0, void 0, function* () { + if (lang === langConfig_1.CodeLang.TypeScript) { + return buildTsCode(filePath); + } + return buildJsCode(filePath); + }); +} +function buildJsCode(filePath) { + return __awaiter(this, void 0, void 0, function* () { + const plugins = [ + plugin_node_resolve_1.default(), + plugin_babel_1.default({ + babelHelpers: 'bundled', + comments: false, + plugins: [babelPlugin_1.outBoundArrayPlugin], + }), + ]; + const bundle = yield rollup.rollup({ + input: filePath, + treeshake: false, + plugins, + }); + const { output } = yield bundle.generate({ + sourcemap: true, + sourcemapPathTransform: (r, s) => { + return path.join(path.parse(s).dir, r); + }, + }); + return output; + }); +} +function buildTsCode(filePath) { + return __awaiter(this, void 0, void 0, function* () { + const code = fs.readFileSync(filePath, { encoding: 'utf8' }); + const fileDir = path.parse(filePath).dir; + const entry = core_1.transformSync(code, { + filename: filePath, + comments: false, + cwd: fileDir, + presets: [[presetTs, { onlyRemoveTypeImports: true }]], + plugins: [babelPlugin_1.outBoundArrayPlugin], + }); + const bundle = yield rollup.rollup({ + input: 'entry', + treeshake: false, + plugins: [ + virtual({ + entry: entry === null || entry === void 0 ? void 0 : entry.code, + }), + plugin_node_resolve_1.default({ rootDir: fileDir, browser: false }), + ], + }); + const { output } = yield bundle.generate({}); + return output; + }); +} +function handleErrPosition(err, map, args) { + return __awaiter(this, void 0, void 0, function* () { + const consumer = yield new sourceMap.SourceMapConsumer(map); + const regexp = /evalmachine\.:(\d+):?(\d+)?/g; + let msg = `× @test(${args.join(',')})\n`; + const stack = err.stack; + msg += stack.replace(regexp, (_, line, column) => { + line = parseInt(line); + column = parseInt(column) || 0; + const originPosition = consumer.originalPositionFor({ + line: line, + column: column, + }); + if (originPosition.source) { + if (column) { + return originPosition.source + ':' + originPosition.line + ':' + originPosition.column; + } + else { + return originPosition.source + ':' + originPosition.line; + } + } + return _; + }); + consumer.destroy(); + return msg; + }); +} +//# sourceMappingURL=execTestCode.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/commands.js b/tools/supperchong.algorithm/out/commands.js new file mode 100644 index 0000000..801dd9b --- /dev/null +++ b/tools/supperchong.algorithm/out/commands.js @@ -0,0 +1,440 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.newAnswerCommand = exports.viewSubmitHistoryCommand = exports.removeMemoFileCommand = exports.addMemoFileCommand = exports.memoFilePreviewCommand = exports.addFolderCommand = exports.searchCommand = exports.switchDataBaseCommand = exports.switchCodeLangCommand = exports.switchEndpointCommand = exports.signInCommand = exports.refreshCommand = exports.getDescriptionCommand = exports.submitCommand = exports.buildCodeCommand = exports.debugCodeCommand = exports.buildCode = exports.testCodeCommand = void 0; +const util_1 = require("./common/util"); +const util_2 = require("./util"); +const config_1 = require("./config"); +const vscode_1 = require("vscode"); +const buildCodeWebview_1 = require("./webview/buildCodeWebview"); +const index_1 = require("./api/index"); +const vscode = require("vscode"); +const cache_1 = require("./cache"); +const common_1 = require("./model/common"); +const config_2 = require("./config"); +const input_1 = require("./login/input"); +const questionPreview_1 = require("./webview/questionPreview"); +const langConfig_1 = require("./common/langConfig"); +const util_3 = require("./common/util"); +const index_2 = require("./memo/index"); +const memoProvider_1 = require("./provider/memoProvider"); +const common_2 = require("./lang/common"); +const database_1 = require("./lang/database"); +const bash_1 = require("./lang/bash"); +const submitHistory_1 = require("./webview/submitHistory"); +const storage_1 = require("./history/storage"); +const answer_1 = require("./history/answer"); +function testCodeCommand(...args) { + return __awaiter(this, void 0, void 0, function* () { + const [{ filePath, testCaseParam: { testCase }, },] = args; + try { + const service = new common_2.Service(filePath); + const promise = service.execTest(testCase); + const msg = yield util_2.execWithProgress(promise, 'wait test'); + if (msg) { + config_1.log.appendLine(msg); + } + config_1.log.show(); + } + catch (err) { + console.log(err); + vscode_1.window.showInformationMessage(`parse params err: ${err}`); + } + }); +} +exports.testCodeCommand = testCodeCommand; +function openFolder() { + return __awaiter(this, void 0, void 0, function* () { + const items = [ + 'open questions folder in new window', + 'open questions folder in current window', + 'add questions folder at the start of workspace folders', + ]; + const uri = vscode.Uri.file(config_2.config.baseDir); + const pickItem = yield vscode_1.window.showQuickPick(items); + if (pickItem === items[0]) { + const uri = vscode.Uri.file(config_2.config.baseDir); + return vscode.commands.executeCommand('vscode.openFolder', uri, { + forceNewWindow: true, + }); + } + else if (pickItem === items[1]) { + return vscode.commands.executeCommand('vscode.openFolder', uri, { + forceNewWindow: false, + }); + } + else if (pickItem === items[2]) { + return vscode.workspace.updateWorkspaceFolders(0, 0, { uri }); + } + }); +} +function buildCode(text, filePath) { + return __awaiter(this, void 0, void 0, function* () { + if (langConfig_1.isDataBase(filePath)) { + const parse = new database_1.DataBaseParse(filePath, text); + return parse.buildCode(); + } + else if (langConfig_1.isShell(filePath)) { + const parse = new bash_1.BashParse(filePath, text); + return parse.buildCode(); + } + const service = new common_2.Service(filePath, text); + return service.buildCode(); + }); +} +exports.buildCode = buildCode; +// TODO +function submitAsync(code, questionMeta) { + return __awaiter(this, void 0, void 0, function* () { + common_1.checkParams(questionMeta, ['titleSlug', 'id']); + const { titleSlug, id } = questionMeta; + const res = yield index_1.api.submit({ + titleSlug: titleSlug, + question_id: id, + typed_code: code, + lang: questionMeta.lang, + }); + if (!res.submission_id) { + config_1.log.appendLine(JSON.stringify(res)); + config_1.log.show(); + return Promise.reject(new Error('submit error')); + } + const fn = () => __awaiter(this, void 0, void 0, function* () { + const res2 = yield index_1.api.check({ + submission_id: res.submission_id, + titleSlug: titleSlug, + }); + if (['PENDING', 'STARTED', 'SUCCESS'].includes(res2.state)) { + return res2; + } + else { + console.log('check res', res2); + config_1.log.appendLine(JSON.stringify(res2)); + return Promise.reject(new Error('submit error')); + } + }); + const verifyFn = (res) => res.state === 'SUCCESS'; + const result = yield util_1.retry({ fn, verifyFn, time: 6 }); + return result; + }); +} +function submitCode(text, filePath) { + return __awaiter(this, void 0, void 0, function* () { + const buildResult = yield buildCode(text, filePath); + const code = buildResult.code; + const questionMeta = buildResult.questionMeta; + const result = yield submitAsync(code, questionMeta); + return { + result, + code, + questionMeta, + }; + }); +} +function debugCodeCommand(filePath) { + return __awaiter(this, void 0, void 0, function* () { + const uri = vscode.Uri.file(config_2.config.baseDir); + const p = vscode.workspace.getWorkspaceFolder(uri); + const workspaceFolders = vscode.workspace.workspaceFolders; + if (!(workspaceFolders === null || workspaceFolders === void 0 ? void 0 : workspaceFolders.find((w) => w.uri === (p === null || p === void 0 ? void 0 : p.uri)))) { + return openFolder(); + } + const breaks = vscode.debug.breakpoints; + if (!breaks.find((b) => { var _a; return ((_a = b === null || b === void 0 ? void 0 : b.location) === null || _a === void 0 ? void 0 : _a.uri.fsPath) === filePath; })) { + console.log('breakpoint not found'); + vscode_1.window.showErrorMessage('please set breakpoint'); + return; + } + if (!util_2.checkBeforeDebug(filePath)) { + return; + } + const service = new common_2.Service(filePath); + service.debugCodeCommand(p, breaks); + }); +} +exports.debugCodeCommand = debugCodeCommand; +function buildCodeCommand(...args) { + return __awaiter(this, void 0, void 0, function* () { + const [context, { text, filePath, langSlug }] = args; + const { code } = yield buildCode(text, filePath); + buildCodeWebview_1.createPanel(context, code, langSlug); + }); +} +exports.buildCodeCommand = buildCodeCommand; +// export async function buildCodeCommand(context: ExtensionContext, text: string, filePath: string, langSlug: string) { +// const { code } = await buildCode(text, filePath) +// createPanel(context, code, langSlug) +// } +function submitCommand(...args) { + var _a, _b; + return __awaiter(this, void 0, void 0, function* () { + const [questionsProvider, { text, filePath }] = args; + let message = ''; + try { + const { result, questionMeta } = yield util_2.execWithProgress(submitCode(text, filePath), 'wait submit'); + message = result.status_msg; + storage_1.submitStorage.saveSubmit({ + filePath: filePath, + text, + result, + desc: questionMeta.desc, + }); + if (message === 'Accepted') { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + cache_1.cache.updateQuestion(parseInt(questionMeta.id), { status: 'ac' }); + questionsProvider.refresh(); + } + else { + if (result.status_code === 11) { + //'Wrong Answer' + const inputLength = ((_a = result === null || result === void 0 ? void 0 : result.input_formatted) === null || _a === void 0 ? void 0 : _a.length) || 0; + const maxLength = 300; + if (inputLength <= maxLength) { + const msg = `× @test(${result.input_formatted})\n expect: ${result.expected_output}\n\n result: ${result.code_output}`; + config_1.log.appendLine(msg); + config_1.log.show(); + const codeLang = langConfig_1.getFileLang(filePath); + if (questionMeta.id && langConfig_1.isAlgorithm(codeLang)) { + const questionDetail = yield index_1.api.fetchQuestionDetailById(questionMeta.id); + try { + if (questionDetail) { + const metaData = JSON.parse(questionDetail.metaData); + const funcName = metaData.name; + const comment = ` @test(${result.input_formatted})=${result.expected_output}`; + const s = new common_2.Service(filePath); + const newCode = s.addComment(text, comment, funcName); + yield util_3.writeFileAsync(filePath, newCode); + } + } + catch (err) { + console.log('parse questionDetail error', questionDetail); + } + } + } + } + } + console.log(result); + vscode_1.window.showInformationMessage(message); + } + catch (err) { + if ([common_1.ErrorStatus.InvalidCookie, common_1.ErrorStatus.Unlogin].includes((_b = err === null || err === void 0 ? void 0 : err.response) === null || _b === void 0 ? void 0 : _b.status)) { + return; + } + console.log(err); + message = err.message; + } + vscode_1.window.showInformationMessage(message); + }); +} +exports.submitCommand = submitCommand; +function getDescriptionCommand(...args) { + return __awaiter(this, void 0, void 0, function* () { + const [extensionPath, { text, filePath }] = args; + //extensionPath: string, text: string, filePath: string + const { questionMeta } = util_1.getFuncNames(text, filePath); + questionPreview_1.getQuestionDescription(extensionPath, { + questionId: questionMeta.id, + titleSlug: questionMeta.titleSlug, + weekname: questionMeta.weekname, + }); + }); +} +exports.getDescriptionCommand = getDescriptionCommand; +function refreshCommand(questionsProvider) { + return __awaiter(this, void 0, void 0, function* () { + const promise = index_1.refreshQuestions(); + yield util_2.execWithProgress2(promise, ''); + questionsProvider.refresh(); + }); +} +exports.refreshCommand = refreshCommand; +function signInCommand(questionsProvider) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield input_1.selectLogin(questionsProvider); + } + catch (err) { + if (err.code !== 2) { + vscode_1.window.showInformationMessage(err.message); + } + } + }); +} +exports.signInCommand = signInCommand; +class LangItem { + constructor(label, description, detail) { + this.label = label; + this.description = description; + this.detail = detail; + } +} +function switchEndpointCommand() { + return __awaiter(this, void 0, void 0, function* () { + const LangConfigs = [ + { + lang: common_1.Lang.en, + label: 'Leetcode', + description: 'leetcode.com', + detail: 'Enable Leetcode US', + }, + { + lang: common_1.Lang.cn, + label: '力扣', + description: 'leetcode-cn.com', + detail: '启用中国版Leetcode', + }, + ]; + const items = LangConfigs.map((langConfig) => { + if (langConfig.lang === config_2.config.lang) { + return new LangItem('$(check)' + langConfig.label, langConfig.description, langConfig.detail); + } + return new LangItem(langConfig.label, langConfig.description, langConfig.detail); + }); + const [itemEN, itemCN] = items; + const result = yield vscode_1.window.showQuickPick(items); + if (result === itemEN) { + config_1.updateConfig('lang', common_1.Lang.en); + } + else if (result === itemCN) { + config_1.updateConfig('lang', common_1.Lang.cn); + } + }); +} +exports.switchEndpointCommand = switchEndpointCommand; +class CodeLangItem { + constructor(label, description) { + this.label = label; + this.description = description; + } +} +function switchCodeLangCommand() { + return __awaiter(this, void 0, void 0, function* () { + // const langs: CodeLang[] = [CodeLang.JavaScript, CodeLang.TypeScript, CodeLang.Python3, CodeLang.Go] + const curLang = config_2.config.codeLang; + const langLabels = langConfig_1.enableLang.map((lang) => { + if (lang === curLang) { + return new CodeLangItem(lang, '$(check)'); + } + return new CodeLangItem(lang, ''); + }); + const pickItem = yield vscode_1.window.showQuickPick(langLabels); + const pickIndex = langLabels.findIndex((v) => v === pickItem); + if (pickIndex !== -1) { + const pickLang = langConfig_1.enableLang[pickIndex]; + config_1.updateConfig('codeLang', pickLang); + } + }); +} +exports.switchCodeLangCommand = switchCodeLangCommand; +function switchDataBaseCommand() { + return __awaiter(this, void 0, void 0, function* () { + const curDataBase = config_2.config.database; + const langLabels = langConfig_1.databases.map((lang) => { + if (lang === curDataBase) { + return new CodeLangItem(lang, '$(check)'); + } + return new CodeLangItem(lang, ''); + }); + const pickItem = yield vscode_1.window.showQuickPick(langLabels); + const pickIndex = langLabels.findIndex((v) => v === pickItem); + if (pickIndex !== -1) { + const pickLang = langConfig_1.databases[pickIndex]; + config_1.updateConfig('database', pickLang); + } + }); +} +exports.switchDataBaseCommand = switchDataBaseCommand; +function searchCommand() { + return __awaiter(this, void 0, void 0, function* () { + const questions = yield index_1.api.getAllQuestions(); + const items = questions.map((v) => util_3.normalizeQuestionLabel(v)); + const pickItem = yield vscode_1.window.showQuickPick(items); + const index = items.findIndex((item) => item === pickItem); + if (index !== -1) { + const question = questions[index]; + const param = { + id: question.id, + titleSlug: question.slug, + }; + vscode.commands.executeCommand('algorithm.questionPreview', param); + } + }); +} +exports.searchCommand = searchCommand; +function addFolderCommand(memoProvider) { + return __awaiter(this, void 0, void 0, function* () { + const folderName = yield vscode_1.window.showInputBox(); + if (folderName) { + try { + index_2.addFolder(folderName); + memoProvider.refresh(); + } + catch (err) { + config_1.log.appendLine(err); + config_1.log.show(); + } + } + }); +} +exports.addFolderCommand = addFolderCommand; +function memoFilePreviewCommand(memoFile) { + return __awaiter(this, void 0, void 0, function* () { + if (memoFile.type === 'question') { + vscode.commands.executeCommand('algorithm.questionPreview', memoFile.param); + } + }); +} +exports.memoFilePreviewCommand = memoFilePreviewCommand; +function addMemoFileCommand(memoProvider, questionTree) { + return __awaiter(this, void 0, void 0, function* () { + const folderNames = config_2.config.env.memo.map((v) => v.name); + const folderName = yield vscode_1.window.showQuickPick(folderNames); + if (folderName) { + try { + index_2.addQuestion(folderName, questionTree.label, questionTree.param); + memoProvider.refresh(); + } + catch (err) { + config_1.log.appendLine(err); + config_1.log.show(); + } + } + }); +} +exports.addMemoFileCommand = addMemoFileCommand; +function removeMemoFileCommand(memoProvider, param) { + return __awaiter(this, void 0, void 0, function* () { + const isRemove = yield memoProvider_1.MemoProvider.remove(param); + if (isRemove) { + memoProvider.refresh(); + } + }); +} +exports.removeMemoFileCommand = removeMemoFileCommand; +function viewSubmitHistoryCommand(...args) { + return __awaiter(this, void 0, void 0, function* () { + const [context, { text, filePath }] = args; + const { questionMeta } = util_1.getFuncNames(text, filePath); + if (!questionMeta.id) { + return; + } + submitHistory_1.createSubmitHistoryPanel(context, questionMeta.id); + }); +} +exports.viewSubmitHistoryCommand = viewSubmitHistoryCommand; +function newAnswerCommand(uri) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = uri.fsPath; + answer_1.answerStorage.newAnswer(filePath); + }); +} +exports.newAnswerCommand = newAnswerCommand; +//# sourceMappingURL=commands.js.map diff --git a/tools/supperchong.algorithm/out/common/lang.js b/tools/supperchong.algorithm/out/common/lang.js new file mode 100644 index 0000000..65311f9 --- /dev/null +++ b/tools/supperchong.algorithm/out/common/lang.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultTimeout = void 0; +exports.defaultTimeout = 10000; +//# sourceMappingURL=lang.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/common/langConfig.js b/tools/supperchong.algorithm/out/common/langConfig.js new file mode 100644 index 0000000..01f2a54 --- /dev/null +++ b/tools/supperchong.algorithm/out/common/langConfig.js @@ -0,0 +1,263 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isSupportFile = exports.transformToHightlightLang = exports.highlightLangMap = exports.ExtraType = exports.enNameLangs = exports.databases = exports.enableLang = exports.otherLang = exports.builtInLang = exports.getFileComment = exports.isAlgorithm = exports.isShell = exports.isDataBase = exports.getFileLangSlug = exports.getFileLang = exports.DataBase = exports.CodeLang = exports.langExtMap = exports.langMap = void 0; +const path = require("path"); +const langsConfig = { + algorithms: [ + { + lang: 'C++', + langSlug: 'cpp', + ext: '.h', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Java', + langSlug: 'java', + ext: '.java', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Python', + langSlug: 'python', + ext: '.py', + comment: '#', + fileNameSep: '_', + }, + { + lang: 'Python3', + langSlug: 'python3', + ext: '.py', + comment: '#', + fileNameSep: '_', + }, + { + lang: 'C', + langSlug: 'c', + ext: '.c', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'C#', + langSlug: 'csharp', + ext: '.cs', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'JavaScript', + langSlug: 'javascript', + ext: '.js', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Ruby', + langSlug: 'ruby', + ext: '.rb', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'Swift', + langSlug: 'swift', + ext: '.swift', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Go', + langSlug: 'golang', + ext: '.go', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Scala', + langSlug: 'scala', + ext: '.scala', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Kotlin', + langSlug: 'kotlin', + ext: '.kt', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Rust', + langSlug: 'rust', + ext: '.rs', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'PHP', + langSlug: 'php', + ext: '.php', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'TypeScript', + langSlug: 'typescript', + ext: '.ts', + comment: '//', + fileNameSep: '.', + }, + ], + database: [ + { + lang: 'MySQL', + langSlug: 'mysql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'MS SQL Server', + langSlug: 'mssql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'Oracle', + langSlug: 'oraclesql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + ], + shell: [ + { + lang: 'Bash', + langSlug: 'bash', + ext: '.sh', + comment: '#', + fileNameSep: '.', + }, + ], +}; +var LangBaseComment; +(function (LangBaseComment) { + LangBaseComment["Slash"] = "//"; + LangBaseComment["Pound"] = "#"; +})(LangBaseComment || (LangBaseComment = {})); +const allLangs = Object.values(langsConfig).reduce((prev, cur) => prev.concat(cur)); +exports.langMap = allLangs.reduce((prev, cur) => (prev[cur.langSlug] = cur) && prev, {}); +exports.langExtMap = allLangs.reduce((prev, cur) => (prev[cur.ext] = cur) && prev, {}); +var CodeLang; +(function (CodeLang) { + CodeLang["C++"] = "C++"; + CodeLang["C#"] = "C#"; + CodeLang["Java"] = "Java"; + CodeLang["Python"] = "Python"; + CodeLang["Python3"] = "Python3"; + CodeLang["C"] = "C"; + CodeLang["JavaScript"] = "JavaScript"; + CodeLang["Ruby"] = "Ruby"; + CodeLang["Swift"] = "Swift"; + CodeLang["Go"] = "Go"; + CodeLang["Scala"] = "Scala"; + CodeLang["Kotlin"] = "Kotlin"; + CodeLang["Rust"] = "Rust"; + CodeLang["PHP"] = "PHP"; + CodeLang["TypeScript"] = "TypeScript"; +})(CodeLang = exports.CodeLang || (exports.CodeLang = {})); +var DataBase; +(function (DataBase) { + DataBase["MySQL"] = "MySQL"; + DataBase["MS SQL Server"] = "MS SQL Server"; + DataBase["Oracle"] = "Oracle"; +})(DataBase = exports.DataBase || (exports.DataBase = {})); +function getFileLang(filePath) { + const ext = path.extname(filePath); + const langItem = exports.langExtMap[ext]; + if (!langItem) { + throw new Error('file extname invalid'); + } + return langItem.lang; +} +exports.getFileLang = getFileLang; +function getFileLangSlug(filePath) { + const ext = path.extname(filePath); + const langItem = exports.langExtMap[ext]; + if (!langItem) { + throw new Error('file extname invalid'); + } + return langItem.langSlug; +} +exports.getFileLangSlug = getFileLangSlug; +function isDataBase(filePath) { + const ext = path.extname(filePath); + return ext === '.sql'; +} +exports.isDataBase = isDataBase; +function isShell(filePath) { + const ext = path.extname(filePath); + return ext === '.sh'; +} +exports.isShell = isShell; +function isAlgorithm(lang) { + return !!langsConfig.algorithms.find((alg) => alg.lang === lang); +} +exports.isAlgorithm = isAlgorithm; +function getFileComment(filePath) { + const ext = path.extname(filePath); + const langItem = exports.langExtMap[ext]; + if (!langItem) { + throw new Error('file extname invalid'); + } + return langItem.comment; +} +exports.getFileComment = getFileComment; +exports.builtInLang = [CodeLang.JavaScript, CodeLang.TypeScript]; +exports.otherLang = [CodeLang.Python3, CodeLang.Go, CodeLang.Java, CodeLang['C++']]; +exports.enableLang = [...exports.builtInLang, ...exports.otherLang]; +exports.databases = [DataBase['MS SQL Server'], DataBase.MySQL, DataBase.Oracle]; +exports.enNameLangs = [CodeLang.Java, CodeLang['C++']]; +var ExtraType; +(function (ExtraType) { + ExtraType["ListNode"] = "ListNode"; + ExtraType["TreeNode"] = "TreeNode"; +})(ExtraType = exports.ExtraType || (exports.ExtraType = {})); +exports.highlightLangMap = { + cpp: 'cpp', + java: 'java', + python: 'python', + python3: 'python', + c: 'c', + csharp: 'csharp', + javascript: 'javascript', + ruby: 'ruby', + swift: 'swift', + golang: 'go', + scala: 'scala', + kotlin: 'kotlin', + rust: 'rust', + php: 'php', + typescript: 'typescript', +}; +function transformToHightlightLang(lang) { + return exports.highlightLangMap[lang] || lang; +} +exports.transformToHightlightLang = transformToHightlightLang; +function isSupportFile(filePath) { + if (isShell(filePath) || isDataBase(filePath)) { + return true; + } + const ext = path.extname(filePath); + const langItem = exports.langExtMap[ext]; + if (!langItem) { + return false; + } + const lang = langItem.lang; + return exports.enableLang.includes(lang); +} +exports.isSupportFile = isSupportFile; +//# sourceMappingURL=langConfig.js.map diff --git a/tools/supperchong.algorithm/out/common/parseContent.js b/tools/supperchong.algorithm/out/common/parseContent.js new file mode 100644 index 0000000..76a233a --- /dev/null +++ b/tools/supperchong.algorithm/out/common/parseContent.js @@ -0,0 +1,279 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ParseContent = void 0; +const pretty_object_string_1 = require("pretty-object-string"); +const util_1 = require("./util"); +const isSpace = (c) => /\s/.test(c); +const isWord = (c) => /\w/.test(c); +function delComment(src) { + const commentRegExp = /(\/\*([\s\S]*?)\*\/|('.*?')|(".*?")|\/\/(.*)$)/gm; + return src.replace(commentRegExp, commentReplace); +} +function commentReplace(_match, _multi, _multiText, singlePrefix, double) { + return singlePrefix || double || ''; +} +var Kind; +(function (Kind) { + Kind[Kind["scanContinue"] = 0] = "scanContinue"; + Kind[Kind["scanBeginTag"] = 1] = "scanBeginTag"; + Kind[Kind["scanTagText"] = 2] = "scanTagText"; + Kind[Kind["scanEndTag"] = 3] = "scanEndTag"; + Kind[Kind["scanWord"] = 4] = "scanWord"; + Kind[Kind["scanSpace"] = 5] = "scanSpace"; + Kind[Kind["scanInputFlag"] = 6] = "scanInputFlag"; + Kind[Kind["Identify"] = 7] = "Identify"; + Kind[Kind["scanEqual"] = 8] = "scanEqual"; + Kind[Kind["scanParam"] = 9] = "scanParam"; + Kind[Kind["scanResult"] = 10] = "scanResult"; +})(Kind || (Kind = {})); +//TODO refactor +class ParseContent { + constructor(content) { + this.content = content; + this.step = this.stateBegin; + this.prevStep = this.stateBegin; + this.word = ''; + this.words = []; + this.tagStatus = 0; + this.exampleState = 0; + this.demos = []; + this.content = delComment(util_1.escape2html(content.replace(/<[^>]*>/g, ''))); + this.init(); + } + init() { + this.step = this.stateBegin; + let input = []; + const linkReg = /^\s*-?\d+->/; + const demos = []; + let identify; + let i = 0; + try { + for (; i < this.content.length; i++) { + const c = this.content[i]; + const n = this.content[i + 1]; + const out = this.step(c, n, i); + if (out === Kind.Identify) { + identify = this.word; + this.word = ''; + } + else if (out === Kind.scanParam) { + let value = this.content.slice(i, i + 10); + let index, output; + if (linkReg.test(value)) { + const result = this.parseLink(i); + index = result.index; + output = result.output; + } + else { + value = this.content.slice(i); + const result = pretty_object_string_1.parse(value, { + partialIndex: true, + compress: true, + }); + index = result.index; + output = result.output; + } + input.push({ + key: identify, + value: output, + }); + i = i + index - 1; + this.step = this.stateInputIdentity2; + } + else if (out === Kind.scanResult) { + let value = this.content.slice(i, i + 10); + let index, output; + if (linkReg.test(value)) { + const result = this.parseLink(i); + index = result.index; + output = result.output; + } + else { + value = this.content.slice(i); + const result = pretty_object_string_1.parse(value, { + partialIndex: true, + compress: true, + }); + index = result.index; + output = result.output; + } + i = i + index - 1; + demos.push({ + input, + output: output, + }); + input = []; + this.word = ''; + identify = ''; + this.step = this.stateWord; + } + } + } + catch (err) { + console.log('content', this.content); + console.log(this.content.slice(i - 20, i)); + console.log(err); + } + this.demos = demos; + } + static getTestCases(content) { + const p = new ParseContent(content); + return p.demos; + } + parseLink(index) { + let numStr = ''; + const output = []; + const start = index; + while (index < this.content.length && isSpace(this.content[index])) { + index++; + } + while (index < this.content.length && /[\d->N]/.test(this.content[index])) { + const char = this.content[index]; + if (/\d/.test(char)) { + numStr += char; + } + else if (char === '-') { + const nextChar = this.content[index + 1]; + if (nextChar === '>') { + output.push(parseInt(numStr)); + numStr = ''; + } + else if (/\d/.test(nextChar)) { + numStr = char; + } + } + else if (char === 'N') { + if (this.content.slice(index, index + 4) !== 'NULL') { + throw new Error('parse link error'); + } + return { + index: index + 4 - start, + output: JSON.stringify(output), + }; + } + index++; + } + output.push(parseInt(numStr)); + return { + index: index - start, + output: JSON.stringify(output), + }; + } + lineEndAt(position) { + let i = position; + while (this.content[i++]) { + if (this.content[i] === '\n') { + return i; + } + } + return i; + } + stateBegin(char) { + if (isSpace(char)) { + return Kind.scanContinue; + } + this.step = this.stateWord; + return this.stateWord(char); + } + stateWord(char) { + if (isSpace(char)) { + this.word = ''; + return Kind.scanSpace; + } + this.word += char; + if (this.exampleState === 1 && this.word === 'Input:') { + this.word = ''; + this.exampleState = 0; + this.step = this.stateInputIdentityOrValue; + } + else if (this.word === 'Example') { + this.exampleState = 1; + } + return Kind.scanWord; + } + stateInputIdentityOrValue(char, n, i) { + if (isSpace(char)) { + return Kind.scanSpace; + } + if (!/[a-zA-Z_]/.test(char) || /(true|false|null)/.test(this.content.slice(i, i + 6))) { + return Kind.scanParam; + } + if (this.content.slice(i, i + 7) === 'Output:') { + //Compatibility Special Conditions id:53 + /** + * content Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + + Example: + + + Input: [-2,1,-3,4,-1,2,1,-5,4], + Output: 6 + Explanation: [4,-1,2,1] has the largest sum = 6. + + */ + this.step = this.stateOut; + return this.step(char, n, i); + } + this.step = this.stateInputIdentity; + return this.step(char, n, i); + } + stateInputIdentity(char, _n, _i) { + if (isSpace(char)) { + if (!this.word) { + return Kind.scanSpace; + } + this.step = this.stateEqual; + return Kind.Identify; + } + if (!isWord(char)) { + throw new Error('input identity invalid'); + } + this.word += char; + return Kind.scanWord; + } + stateEqual(char) { + if (isSpace(char)) { + return Kind.scanSpace; + } + if (char === '=') { + this.step = this.stateParam; + return Kind.scanEqual; + } + throw new Error('parse equal error'); + } + stateParam(char) { + if (isSpace(char)) { + return Kind.scanSpace; + } + return Kind.scanParam; + } + stateInputIdentity2(char, n, i) { + if (isSpace(char)) { + return Kind.scanSpace; + } + if (char === ',') { + this.step = this.stateInputIdentityOrValue; + return Kind.scanContinue; + } + this.step = this.stateOut; + return this.step(char, n, i); + } + stateOut(char) { + if (isSpace(char)) { + return Kind.scanSpace; + } + this.word += char; + if (this.word === 'Output:') { + this.word = ''; + this.step = this.stateResult; + return Kind.scanContinue; + } + return Kind.scanContinue; + } + stateResult(char) { + this.word += char; + return Kind.scanResult; + } +} +exports.ParseContent = ParseContent; +//# sourceMappingURL=parseContent.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/common/transformCode.js b/tools/supperchong.algorithm/out/common/transformCode.js new file mode 100644 index 0000000..6c96588 --- /dev/null +++ b/tools/supperchong.algorithm/out/common/transformCode.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addComment = void 0; +const recast = require("recast"); +const acorn = require("acorn"); +const ast_types_1 = require("ast-types"); +function addAstComment(ast, comment, funName) { + const visitor = { + FunctionDeclaration: (node) => { + if (node.id && node.id.name === funName) { + insertLineComment(node, comment); + } + }, + VariableDeclaration: (node) => { + if (node.declarations.find((declaration) => { + return (declaration.type === 'VariableDeclarator' && + declaration.id.type === 'Identifier' && + declaration.id.name === funName); + })) { + insertLineComment(node, comment); + } + }, + }; + const body = ast.program.body; + for (const node of body) { + const fn = visitor[node.type]; + if (fn) { + fn(node); + } + } +} +function insertLineComment(node, comment) { + const commentNode = ast_types_1.builders.commentLine(comment, true); + const originComments = node.comments || []; + const mergeComments = [commentNode, ...originComments]; + node.comments = mergeComments; +} +function addComment(source, comment, funName) { + const ast = recast.parse(source, { + parser: acorn, + }); + addAstComment(ast, comment, funName); + const output = recast.print(ast).code; + return output; +} +exports.addComment = addComment; +//# sourceMappingURL=transformCode.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/common/util.js b/tools/supperchong.algorithm/out/common/util.js new file mode 100644 index 0000000..5f17252 --- /dev/null +++ b/tools/supperchong.algorithm/out/common/util.js @@ -0,0 +1,731 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.generateId = exports.handleArgsType = exports.returnRegExp = exports.paramMetaRegExp = exports.execFileAsync = exports.readFileAsync = exports.writeFileAsync = exports.getFuncNames = exports.parseTestCase = exports.getTsTestCaseList = exports.getTestCaseList = exports.detectEnableExt = exports.handleMsg = exports.unionArr = exports.uniqueArrByKey = exports.downloadNpm = exports.setLinePrefix = exports.getResultType = exports.deserializeParam = exports.normalize = exports.parseCommentTest = exports.retry = exports.escape2html = exports.parseSubmissionDetailHtml = exports.parseHtml = exports.existFile = exports.existDirSync = exports.existDir = exports.getDesc = exports.parseTsFunctionType = exports.normalizeQuestions = exports.normalizeQuestionLabel = exports.writeFileSync = exports.mkdirSync = exports.writeFile = exports.isVersionGte = exports.isListNode = exports.isTreeNode = exports.tsFunctionRegExp = exports.funcNameRegExp = void 0; +const pretty_object_string_1 = require("pretty-object-string"); +const fs = require("fs"); +const fse = require("fs-extra"); +const util_1 = require("util"); +const vm = require("vm"); +const path = require("path"); +const axios_1 = require("axios"); +const compressing = require("compressing"); +const langConfig_1 = require("./langConfig"); +const cp = require("child_process"); +const pretty_tag_1 = require("pretty-tag"); +const rimraf = require("rimraf"); +const cheerio = require("cheerio"); +const access = util_1.promisify(fs.access); +const mkdir = util_1.promisify(fs.mkdir); +const writeFileAsync = util_1.promisify(fs.writeFile); +exports.writeFileAsync = writeFileAsync; +const readFileAsync = util_1.promisify(fs.readFile); +exports.readFileAsync = readFileAsync; +const execFileAsync = util_1.promisify(cp.execFile); +exports.execFileAsync = execFileAsync; +const isSpace = (s) => /\s/.test(s); +const testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; +const funcRegExp = /^(?:(\s*function)|(.*=\s*function))/; +const paramMetaRegExp = /@param {([^}]+)}/; +exports.paramMetaRegExp = paramMetaRegExp; +const returnRegExp = /@return {([^}]+)}/; +exports.returnRegExp = returnRegExp; +exports.funcNameRegExp = /^(?:\s*function\s*([\w]+)\s*|\s*(?:(?:var|let|const)\s+([\w]+)\s*=\s*)?function)/; +exports.tsFunctionRegExp = /function\s+(\w+)\((.*)\)\s*(?::(.+))?{/; +const isTreeNode = (str) => /^TreeNode\s*(\|\s*null)?$/.test(str); +exports.isTreeNode = isTreeNode; +const isListNode = (str) => /^ListNode\s*(\|\s*null)?$/.test(str); +exports.isListNode = isListNode; +function isVersionGte(v1, v2) { + const arr1 = v1.split('.'); + const arr2 = v2.split('.'); + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] > arr2[i]) { + return true; + } + else if (arr1[i] < arr2[i]) { + return false; + } + } + return true; +} +exports.isVersionGte = isVersionGte; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function writeFile(filepath, data) { + return __awaiter(this, void 0, void 0, function* () { + const dir = path.dirname(filepath); + yield fs.promises.mkdir(dir, { recursive: true }); + return writeFileAsync(filepath, data); + }); +} +exports.writeFile = writeFile; +function mkdirSync(dir) { + fs.mkdirSync(dir, { recursive: true }); +} +exports.mkdirSync = mkdirSync; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function writeFileSync(filepath, data, options) { + fs.mkdirSync(path.dirname(filepath), { recursive: true }); + fs.writeFileSync(filepath, data, options); +} +exports.writeFileSync = writeFileSync; +function normalizeQuestionLabel(question) { + return question.fid + '. ' + question.name; +} +exports.normalizeQuestionLabel = normalizeQuestionLabel; +function normalizeQuestions(questions, type) { + return questions.map((question) => { + const isAC = question.status === 'ac'; + return { + type: 'Question', + label: normalizeQuestionLabel(question), + id: type + question.id, + isLast: true, + isAC, + param: { + titleSlug: question.slug, + questionId: question.id, + }, + }; + }); +} +exports.normalizeQuestions = normalizeQuestions; +function detectEnableExt(text, filePath) { + const commentToken = langConfig_1.getFileComment(filePath); + const algorithmToken = `${commentToken} @algorithm`; + let point = 0; + while (isSpace(text[point])) { + point++; + } + for (let i = 0; i < algorithmToken.length; i++) { + if (text[point++] !== algorithmToken[i]) { + return false; + } + } + return true; +} +exports.detectEnableExt = detectEnableExt; +function getJsTestCaseList(text) { + const testCaseList = []; + const lines = text.split(/\n/); + let isTest = false; + let testCase = []; + let paramsTypes = []; + let resultType = ''; + for (let i = 0; i < lines.length; i++) { + if (testRegExp.test(lines[i])) { + isTest = true; + testCase.push(lines[i]); + } + else if (funcRegExp.test(lines[i])) { + if (isTest) { + const match = lines[i].match(exports.funcNameRegExp); + if (match) { + const funcName = match[1] || match[2]; + testCaseList.push({ + line: i, + testCase, + funcName, + paramsTypes: [...paramsTypes], + resultType: resultType, + }); + paramsTypes = []; + resultType = ''; + } + isTest = false; + testCase = []; + } + } + else if (paramMetaRegExp.test(lines[i])) { + const match = lines[i].match(paramMetaRegExp); + if (match) { + paramsTypes.push(match[1]); + } + } + else if (returnRegExp.test(lines[i])) { + const match = lines[i].match(returnRegExp); + if (match) { + resultType = match[1]; + } + } + } + return testCaseList; +} +exports.getTestCaseList = getJsTestCaseList; +function trimParams(param) { + return param + .split(',') + .map((v) => v.split(':')[1]) + .map((str) => str && str.trim()); +} +function trimResultType(resultType) { + return resultType && resultType.trim(); +} +function parseTsFunctionType(line) { + const match = line.match(exports.tsFunctionRegExp); + if (match) { + return { + funcName: match[1], + paramsTypes: trimParams(match[2]), + resultType: trimResultType(match[3]) || '', + }; + } + return null; +} +exports.parseTsFunctionType = parseTsFunctionType; +function getTsTestCaseList(text) { + const testCaseList = []; + let testCase = []; + let isTest = false; + const lines = text.split(/\n/); + for (let i = 0; i < lines.length; i++) { + if (testRegExp.test(lines[i])) { + isTest = true; + testCase.push(lines[i]); + } + else { + if (isTest) { + const tsFunctionType = parseTsFunctionType(lines[i]); + if (tsFunctionType) { + const { funcName, paramsTypes, resultType } = tsFunctionType; + testCaseList.push({ + line: i, + testCase, + funcName, + paramsTypes: [...paramsTypes], + resultType: resultType, + }); + isTest = false; + testCase = []; + } + } + } + } + return testCaseList; +} +exports.getTsTestCaseList = getTsTestCaseList; +function parseCode(text, filePath) { + const lines = text.split(/\n/); + const funcNames = []; + const comment = langConfig_1.getFileComment(filePath); + const lcToken = comment === '//' + ? /^\/\/ @algorithm @lc id=(\d+) lang=([\w+#]+)(?:\sweekname=([\w-]+))?/ + : /^# @algorithm @lc id=(\d+) lang=([\w+#]+)(?:\sweekname=([\w-]+))?/; + const titleSlugToken = comment === '//' ? /^\/\/ @title ([\w-]+)/ : /^# @title ([\w-]+)/; + const descToken = comment === '//' ? /^\/\/ @desc (.+)/ : /^# @desc (.+)/; + const questionMeta = {}; + for (let i = 0; i < lines.length; i++) { + if (lcToken.test(lines[i])) { + const match = lines[i].match(lcToken); + const id = match[1]; + const lang = match[2]; + const weekname = match[3]; + questionMeta.id = id; + questionMeta.lang = lang; + questionMeta.weekname = weekname; + } + else if (titleSlugToken.test(lines[i])) { + const match = lines[i].match(titleSlugToken); + questionMeta.titleSlug = match[1]; + } + else if (descToken.test(lines[i])) { + const match = lines[i].match(descToken); + questionMeta.desc = match[1]; + } + else { + const match = lines[i].match(exports.funcNameRegExp); + if (match) { + const funcName = match[1] || match[2]; + funcNames.push(funcName); + } + } + } + return { + funcNames, + questionMeta, + }; +} +exports.getFuncNames = parseCode; +function getDesc(text, filePath) { + const lines = text.split(/\n/); + const comment = langConfig_1.getFileComment(filePath); + const descToken = comment === '//' ? /^\/\/ @desc (.+)/ : /^# @desc (.+)/; + for (let i = 0; i < lines.length; i++) { + if (descToken.test(lines[i])) { + const match = lines[i].match(descToken); + return match[1]; + } + } +} +exports.getDesc = getDesc; +function existDir(dir) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield access(dir, fs.constants.F_OK | fs.constants.W_OK); + return true; + } + catch (err) { + if (err.code === 'ENOENT') { + yield mkdir(dir); + return false; + } + throw err; + } + }); +} +exports.existDir = existDir; +function existDirSync(dir) { + try { + fs.accessSync(dir, fs.constants.F_OK | fs.constants.W_OK); + return true; + } + catch (err) { + if (err.code === 'ENOENT') { + fs.mkdirSync(dir); + return false; + } + throw err; + } +} +exports.existDirSync = existDirSync; +function existFile(filepath) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield access(filepath, fs.constants.F_OK | fs.constants.W_OK); + return true; + } + catch (err) { + if (err.code === 'ENOENT') { + yield writeFile(filepath, Buffer.alloc(0)); + return true; + } + throw err; + } + }); +} +exports.existFile = existFile; +function parseHtml(html) { + var _a; + const $ = cheerio.load(html, { decodeEntities: false }); + const translatedContent = ((_a = $('.question-content.default-content').html()) === null || _a === void 0 ? void 0 : _a.trim()) || ''; + const content = translatedContent || ''; + const scripts = $('script').filter(function () { + const text = $(this).html(); + return !!((text === null || text === void 0 ? void 0 : text.includes('pageData')) && text.includes('questionId')); + }); + const questionFrontendId = parseInt($('.question-title h3').html() || '-1').toString(); + let question = null; + if (scripts.length === 1) { + const text = scripts.html(); + const Script = vm.Script; + const script = new Script(text + ';pageData'); + const result = script.runInNewContext(); + if (result) { + question = Object.assign(Object.assign({}, result), { translatedContent, + questionFrontendId, metaData: JSON.stringify(result.metaData), title: result.questionSourceTitle, translatedTitle: result.questionTitle, content, titleSlug: result.questionTitleSlug, codeSnippets: result.codeDefinition.map((v) => ({ + code: v.defaultCode, + lang: v.text, + langSlug: v.value, + })) }); + } + } + return question; +} +exports.parseHtml = parseHtml; +function parseSubmissionDetailHtml(html) { + const $ = cheerio.load(html, { decodeEntities: false }); + const scripts = $('script').filter(function () { + const text = $(this).html(); + return !!((text === null || text === void 0 ? void 0 : text.includes('pageData')) && text.includes('questionId')); + }); + let pageData = null; + if (scripts.length === 1) { + const text = scripts.html(); + const Script = vm.Script; + const script = new Script(text + ';pageData'); + pageData = script.runInNewContext(); + } + return pageData; +} +exports.parseSubmissionDetailHtml = parseSubmissionDetailHtml; +function escape2html(str) { + const map = { lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"', '#39': "'" }; + return str.replace(/&(lt|gt|nbsp|amp|quot|#39);/g, (_, key) => map[key]); +} +exports.escape2html = escape2html; +function sleep(ms) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => { + return setTimeout(resolve, ms); + }); + }); +} +function retry({ fn, time = 1, delay = 1000, verifyFn, }) { + return __awaiter(this, void 0, void 0, function* () { + let count = time | 0; + while (count > 0) { + count--; + yield sleep(delay); + const result = yield fn(); + if (verifyFn(result)) { + return result; + } + } + return Promise.reject(new Error('retry timeout')); + }); +} +exports.retry = retry; +function parseTestCase(testCase) { + const caseList = []; + for (const argsLiteral of testCase) { + caseList.push(parseCommentTest(argsLiteral)); + } + return caseList; +} +exports.parseTestCase = parseTestCase; +function parseCommentTest(testComment) { + let index = testComment.indexOf('@test') + 4; + const params = []; + let result = ''; + while (testComment[++index]) { + if (testComment[index] === '(') { + index++; + break; + } + } + let { index: pos } = pretty_object_string_1.parse(testComment.slice(index), { partialIndex: true }); + while (pos) { + pos = pos + index; + const param = testComment.slice(index, pos); + // param = JSON.parse(param) + params.push(param.trim()); + if (testComment[pos] === ',') { + index = pos + 1; + pos = pretty_object_string_1.parse(testComment.slice(index), { partialIndex: true }).index; + } + else if (testComment[pos] === ')') { + index = pos; + break; + } + else { + console.log(testComment.slice(pos - 10, pos)); + throw new Error('parse CommentTest error:' + testComment); + } + } + while (testComment[++index]) { + if (testComment[index] === '=') { + index++; + break; + } + } + pos = pretty_object_string_1.parse(testComment.slice(index), { partialIndex: true }).index; + if (pos) { + result = testComment.slice(index, pos + index); + } + return { + args: params, + result, + }; +} +exports.parseCommentTest = parseCommentTest; +function normalize(result, returnType) { + if (['TreeNode', 'ListNode'].includes(returnType)) { + return result; + } + else { + return JSON.stringify(result); + } +} +exports.normalize = normalize; +/** + * + * @param args the params of function + * @param paramsTypes the type of params + * @param includeFunctionCall whether the building step contains function call + */ +function deserializeParam(args, paramsTypes, includeFunctionCall) { + let hasTree = false; + let hasList = false; + for (let i = 0; i < paramsTypes.length; i++) { + const paramType = paramsTypes[i]; + if (exports.isTreeNode(paramType)) { + hasTree = true; + if (includeFunctionCall) { + args[i] = `a.treeNode.deserialize("${args[i]}")`; + } + else { + args[i] = `treeNode.deserialize("${args[i]}")`; + } + } + else if (/TreeNode/.test(paramType)) { + console.warn('deserialize param meeting problem,args:', args[i]); + } + else if (exports.isListNode(paramType)) { + hasList = true; + if (includeFunctionCall) { + args[i] = `a.listNode.deserialize("${args[i]}")`; + } + else { + args[i] = `listNode.deserialize("${args[i]}")`; + } + } + else if (/ListNode/.test(paramType)) { + console.warn('deserialize param meeting problem,args:', args[i]); + } + } + return { + hasTree, + hasList, + }; +} +exports.deserializeParam = deserializeParam; +function getResultType(resultType) { + if (exports.isTreeNode(resultType)) { + return 'TreeNode'; + } + else if (exports.isListNode(resultType)) { + return 'ListNode'; + } + else if (/TreeNode|ListNode/.test(resultType)) { + console.warn('deserialize result meeting problem,resultType:', resultType); + } + return ''; +} +exports.getResultType = getResultType; +function setLinePrefix(str, prefix) { + return str + .split('\n') + .map((line) => prefix + line) + .join('\n'); +} +exports.setLinePrefix = setLinePrefix; +function downloadNpm(name, moduleDir) { + return __awaiter(this, void 0, void 0, function* () { + const url = 'https://registry.npmjs.org/' + name; + const randomName = Math.random().toString(32).slice(2); + const targetDir = path.join(moduleDir, name); + const tempDir = path.join(moduleDir, '.temp', randomName); + const res = yield axios_1.default.request({ + url, + }); + const data = res.data; + const latestVersion = data['dist-tags']['latest']; + const fileUrl = data['versions'][latestVersion]['dist']['tarball']; + const res2 = yield axios_1.default.get(fileUrl, { responseType: 'stream' }); + const stream = res2.data; + yield compressing.tgz.uncompress(stream, tempDir); + yield fse.copy(path.join(tempDir, 'package'), path.join(targetDir)); + rimraf(tempDir, (err) => { + console.log(err); + }); + }); +} +exports.downloadNpm = downloadNpm; +function uniqueArrByKey(arr, key) { + if (arr.length <= 1) { + return; + } + arr.sort((x, y) => x[key].localeCompare(y[key])); + let i = 0; + for (let j = 1; j < arr.length; j++) { + if (arr[j][key] !== arr[j - 1][key]) { + arr[++i] = arr[j]; + } + } + arr.length = i + 1; +} +exports.uniqueArrByKey = uniqueArrByKey; +function unionArr(arr1, arr2) { + const set = new Set(arr1); + arr2.forEach((v) => set.add(v)); + return [...set]; +} +exports.unionArr = unionArr; +function handleMsg(testResultList) { + const success = testResultList.every((v) => (v.expect && v.expect.trim()) === (v.result && v.result.trim())); + let msg = ''; + if (success) { + msg = `✓ ${testResultList.length} tests complete`; + } + else { + msg = + testResultList + .map((v) => { + if (v.expect === v.result) { + return `✓ @test(${v.args})\n`; + } + else { + return `× @test(${v.args})\n expect: ${v.expect}\n result: ${v.result}\n`; + } + }) + .join('') + '\n'; + } + return msg; +} +exports.handleMsg = handleMsg; +function handleParam(index, paramType, esbuild = false) { + const prefix = esbuild ? 'a.' : ''; + const handleConfig = [ + { + type: 'ListNode', + handleFn: prefix + 'listNode.deserialize', + }, + { + type: 'TreeNode', + handleFn: prefix + 'treeNode.deserialize', + }, + { + type: 'ListNode[]', + handleFn: prefix + 'listNode.deserializeArr', + }, + { + type: 'TreeNode[]', + handleFn: prefix + 'treeNode.deserializeArr', + }, + ]; + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'double', + ]; + if (jsonType.includes(paramType)) { + return `const arg${index} =JSON.parse(unitArgs[${index}])`; + } + else { + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `const arg${index} =${handleFn}(unitArgs[${index}])`; + } + } + } + throw new Error(`paramType ${paramType} not support`); +} +function handleReturn(paramCount, funcName, returnType, firstParamType, esbuild = false) { + const isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const prefix = esbuild ? 'a.' : ''; + const handleConfig = [ + { + type: 'ListNode', + handleFn: prefix + 'listNode.serialize', + }, + { + type: 'TreeNode', + handleFn: prefix + 'treeNode.serialize', + }, + { + type: 'ListNode[]', + handleFn: prefix + 'listNode.serializeArr', + }, + { + type: 'TreeNode[]', + handleFn: prefix + 'treeNode.serializeArr', + }, + { + type: 'double', + handleFn: `${isVoid ? ';' : ''}(v=>v.toFixed(5))`, + }, + ]; + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + ]; + const argStr = Array(paramCount) + .fill(0) + .map((v, i) => `arg${i}`) + .join(','); + if (jsonType.includes(returnType)) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + const result=${funcName}(${argStr}) + JSON.stringify(result) + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + ${funcName}(${argStr}) + JSON.stringify(arg0) + `; + return funcExpression; + } + } + else { + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + const result=${funcName}(${argStr}) + resultabc =${handleFn}(result) + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + ${funcName}(${argStr}) + ${handleFn}(arg0) + `; + return funcExpression; + } + } + } + } + throw new Error(`returnType ${returnType} not support`); +} +function handleArgsType(meta, originCode, args, isEsbuild = false) { + const params = meta.params || []; + const rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { type } = params[i]; + argExpressions[i] = handleParam(i, type, isEsbuild); + } + const argExpression = argExpressions.join('\n'); + const rtExpression = handleReturn(paramCount, funcName, rt, params[0].type, isEsbuild); + const formatArg = JSON.stringify(args); + return (originCode + + '\n' + + pretty_tag_1.tag ` + const unitArgs=${formatArg} + ${argExpression} + ${rtExpression} + `); +} +exports.handleArgsType = handleArgsType; +function generateId() { + return Math.random().toString(32).slice(2); +} +exports.generateId = generateId; +//# sourceMappingURL=util.js.map diff --git a/tools/supperchong.algorithm/out/common/website.js b/tools/supperchong.algorithm/out/common/website.js new file mode 100644 index 0000000..55f8200 --- /dev/null +++ b/tools/supperchong.algorithm/out/common/website.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getSolution = exports.WebsiteMap = exports.Website = void 0; +const common_1 = require("../model/common"); +const config_1 = require("../config"); +var Website; +(function (Website) { + Website["Leetcode"] = "https://leetcode.com"; + Website["LeetcodeCn"] = "https://leetcode-cn.com"; +})(Website = exports.Website || (exports.Website = {})); +exports.WebsiteMap = { + [common_1.Lang.cn]: Website.LeetcodeCn, + [common_1.Lang.en]: Website.Leetcode, +}; +function baseTag(strs, ...arr) { + const baseUrl = exports.WebsiteMap[config_1.config.lang]; + return baseUrl + '/' + arr.reduce((prev, cur, i) => prev + cur + strs[i + 1], strs[0]); +} +const getSolution = (titleSlug) => baseTag `problems/${titleSlug}/solution/`; +exports.getSolution = getSolution; +//# sourceMappingURL=website.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/config.js b/tools/supperchong.algorithm/out/config.js new file mode 100644 index 0000000..38cd38d --- /dev/null +++ b/tools/supperchong.algorithm/out/config.js @@ -0,0 +1,351 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.onChangeConfig = exports.checkEsbuildDir = exports.updateConfig = exports.updateEnv = exports.config = exports.InstallState = exports.log = void 0; +const fs_1 = require("fs"); +const os = require("os"); +const path = require("path"); +const vscode_1 = require("vscode"); +const common_1 = require("./model/common"); +const cache_1 = require("./cache"); +const langConfig_1 = require("./common/langConfig"); +const cp = require("child_process"); +const fs = require("fs"); +const util_1 = require("util"); +const util_2 = require("./common/util"); +const execFileAsync = util_1.promisify(cp.execFile); +const customConfig = vscode_1.workspace.getConfiguration('algorithm'); +const defaultCodeLang = langConfig_1.CodeLang.JavaScript; +const defaultNodeBinPath = 'node'; +const defaultLang = common_1.Lang.en; +const defaultBaseDir = path.join(os.homedir(), '.alg'); +const defaultJavacPath = 'javac'; +const defaultJavaPath = 'java'; +const algmVersion = '0.1.7'; +const ESBUILD = 'esbuild'; +const defaultDataBase = langConfig_1.DataBase.MySQL; +exports.log = vscode_1.window.createOutputChannel('algorithm'); +exports.InstallState = { + installEsbuild: false, + installAlgm: false, +}; +function ensureMemoUnique(folders) { + if (folders.length <= 1) { + return; + } + util_2.uniqueArrByKey(folders, 'name'); + folders.forEach((folder) => util_2.uniqueArrByKey(folder.children, 'name')); +} +function getEnv(cacheBaseDir) { + const envPath = path.join(cacheBaseDir, 'env.json'); + const defaultEnv = { + hasInstallEsbuild: false, + askForImportState: common_1.AskForImportState.Later, + memo: [], + }; + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const env = require(envPath); + const dir = __dirname; + const installEsbuild = env.installEsbuildArr.find((v) => v === dir); + const askForImportState = env.askForImportState; + const memo = env.memo || []; + ensureMemoUnique(memo); + const hasInstallEsbuild = !!installEsbuild; + return Object.assign(Object.assign({}, defaultEnv), { hasInstallEsbuild, + askForImportState, + memo }); + } + catch (err) { + return defaultEnv; + } +} +function initConfig() { + const codeLang = customConfig.get('codeLang') || defaultCodeLang; + const autoImportStr = customConfig.get('autoImportStr') || ''; + const lang = customConfig.get('lang') || defaultLang; + const baseDir = customConfig.get('baseDir') || defaultBaseDir; + const algDir = path.join(baseDir, lang); + const cacheBaseDir = path.join(os.homedir(), '.algcache'); + const cacheDir = path.join(os.homedir(), '.algcache', lang); + const questionDir = path.join(baseDir, lang, codeLang); + const database = customConfig.get('database') || defaultDataBase; + const cookiePath = path.join(cacheDir, 'cookie.json'); + const questionPath = path.join(cacheDir, 'question.json'); + const tagPath = path.join(cacheDir, 'tag.json'); + const dbDir = path.join(cacheDir, 'db'); + const nodeBinPath = vscode_1.workspace.getConfiguration('algorithm').get('nodePath') || defaultNodeBinPath; + const javacPath = customConfig.get('javacPath') || defaultJavacPath; + const javaPath = customConfig.get('javaPath') || defaultJavaPath; + // const algorithmPath = path.join(__dirname, '../node_modules/algm') + // const algorithmPath = path.join(cacheDir, 'node_modules/algm') + const debugOptionsFilePath = path.join(baseDir, '.vscode/debugParams.json'); + const autoImportAlgm = customConfig.get('autoImportAlgm') || false; + const moduleDir = path.join(baseDir, 'node_modules'); + const algmModuleDir = path.join(moduleDir, 'algm'); + const existAlgmModule = fs.existsSync(algmModuleDir); + const env = getEnv(cacheBaseDir); + const hasAskForImport = false; + return { + baseDir, + lang, + algDir, + cacheBaseDir, + cacheDir, + cookiePath, + log: exports.log, + questionPath, + tagPath, + dbDir, + nodeBinPath, + // algorithmPath, + questionDir, + codeLang, + debugOptionsFilePath, + autoImportStr, + autoImportAlgm, + moduleDir, + algmModuleDir, + existAlgmModule, + env, + hasAskForImport, + javaPath, + javacPath, + database, + }; +} +exports.config = initConfig(); +function initDir() { + const dirKeys = ['cacheDir']; + dirKeys.forEach((key) => { + const dir = exports.config[key]; + if (!fs_1.existsSync(dir)) { + fs_1.mkdirSync(dir, { recursive: true }); + } + }); +} +function checkNodePath() { + const { nodeBinPath } = exports.config; + cp.execFile(nodeBinPath, ['-v'], (err) => { + if (err) { + vscode_1.window.showInformationMessage('please set the node.js executable path'); + } + }); +} +function checkAlgmVersion() { + const targetDir = exports.config.algmModuleDir; + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const a = require(path.join(targetDir, 'package.json')); + return util_2.isVersionGte(a.version, algmVersion); + } + catch (err) { + return false; + } +} +function checkAlgm() { + return __awaiter(this, void 0, void 0, function* () { + if (exports.config.autoImportAlgm) { + const moduleDir = exports.config.moduleDir; + const targetDir = exports.config.algmModuleDir; + const name = 'algm'; + if (fs_1.existsSync(targetDir) && checkAlgmVersion()) { + return; + } + if (!exports.InstallState.installAlgm) { + exports.InstallState.installAlgm = true; + exports.log.appendLine('installing algm...'); + exports.log.show(); + try { + yield util_2.downloadNpm(name, moduleDir); + exports.log.appendLine('install algm success'); + } + catch (err) { + exports.log.appendLine(err); + exports.log.appendLine('install algm fail'); + } + exports.InstallState.installAlgm = false; + } + } + }); +} +function init() { + checkNodePath(); + initDir(); + checkAlgm(); +} +function updateEnv(key, value) { + exports.config.env[key] = value; + const envPath = path.join(exports.config.cacheBaseDir, 'env.json'); + const dir = __dirname; + const hasInstallEsbuild = exports.config.env.hasInstallEsbuild; + const installEsbuildArr = []; + if (hasInstallEsbuild) { + installEsbuildArr.push(dir); + } + const envFile = { + askForImportState: exports.config.env.askForImportState, + installEsbuildArr: installEsbuildArr, + memo: exports.config.env.memo, + }; + try { + const data = fs.readFileSync(envPath, { encoding: 'utf8' }); + const originEnvFile = JSON.parse(data); + envFile.askForImportState = originEnvFile.askForImportState || envFile.askForImportState; + const originInstallEsbuildArr = originEnvFile.installEsbuildArr; + if (Array.isArray(originInstallEsbuildArr)) { + envFile.installEsbuildArr = util_2.unionArr(installEsbuildArr, originInstallEsbuildArr); + } + } + catch (err) { + exports.log.appendLine(err); + } + fs.writeFileSync(envPath, JSON.stringify(envFile)); +} +exports.updateEnv = updateEnv; +function updateConfig(section, value, isSync = false) { + if (exports.config[section] !== value) { + vscode_1.workspace.getConfiguration('algorithm').update(section, value, true); + } + if (isSync) { + exports.config[section] = value; + } +} +exports.updateConfig = updateConfig; +function updateLang() { + const baseDir = exports.config.baseDir; + exports.config.lang = vscode_1.workspace.getConfiguration('algorithm').get('lang') || defaultLang; + exports.config.algDir = path.join(baseDir, exports.config.lang); + exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); + exports.config.cacheDir = path.join(os.homedir(), '.algcache', exports.config.lang); + exports.config.cookiePath = path.join(exports.config.cacheDir, 'cookie.json'); + exports.config.questionPath = path.join(exports.config.cacheDir, 'question.json'); + exports.config.tagPath = path.join(exports.config.cacheDir, 'tag.json'); + exports.config.dbDir = path.join(exports.config.cacheDir, 'db'); +} +function updateCodeLang() { + const baseDir = exports.config.baseDir; + exports.config.codeLang = vscode_1.workspace.getConfiguration('algorithm').get('codeLang') || defaultCodeLang; + exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); +} +function updateDataBaseLang() { + exports.config.database = vscode_1.workspace.getConfiguration('algorithm').get('database') || defaultDataBase; +} +function updateNodePath() { + exports.config.nodeBinPath = vscode_1.workspace.getConfiguration('algorithm').get('nodePath') || defaultNodeBinPath; +} +function updateJavacPath() { + exports.config.javacPath = vscode_1.workspace.getConfiguration('algorithm').get('javacPath') || defaultJavacPath; +} +function updateJavaPath() { + exports.config.javaPath = vscode_1.workspace.getConfiguration('algorithm').get('javaPath') || defaultJavaPath; +} +function updateAutoImportStr() { + exports.config.autoImportStr = vscode_1.workspace.getConfiguration('algorithm').get('autoImportStr') || ''; +} +function updateBaseDir() { + const baseDir = vscode_1.workspace.getConfiguration('algorithm').get('baseDir') || defaultBaseDir; + exports.config.baseDir = baseDir; + exports.config.algDir = path.join(baseDir, exports.config.lang); + exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); + exports.config.debugOptionsFilePath = path.join(baseDir, '.vscode/debugParams.json'); + exports.config.moduleDir = path.join(baseDir, 'node_modules'); + exports.config.algmModuleDir = path.join(exports.config.moduleDir, 'algm'); + exports.config.existAlgmModule = fs.existsSync(exports.config.algmModuleDir); +} +function installEsbuild() { + return __awaiter(this, void 0, void 0, function* () { + const name = ESBUILD; + const moduleDir = path.join(__dirname, '..', 'node_modules'); + const targetDir = path.join(moduleDir, name); + exports.log.appendLine('installing esbuild from npm...'); + exports.log.show(); + exports.InstallState.installEsbuild = true; + try { + if (!fs.existsSync(targetDir)) { + yield util_2.downloadNpm('esbuild', moduleDir); + } + const installFile = path.join(targetDir, 'install.js'); + if (fs.existsSync(installFile)) { + const nodeBinPath = exports.config.nodeBinPath; + const { stderr } = yield execFileAsync(nodeBinPath, [installFile]); + if (stderr) { + exports.log.appendLine(stderr); + // log.appendLine('install esbuild fail') + } + else { + updateEnv('hasInstallEsbuild', true); + exports.log.appendLine('install esbuild success'); + } + } + } + catch (err) { + exports.log.appendLine(err); + exports.log.appendLine('install esbuild fail'); + } + exports.InstallState.installEsbuild = false; + }); +} +function checkEsbuildDir() { + if (exports.config.env.hasInstallEsbuild) { + return true; + } + installEsbuild(); + return false; +} +exports.checkEsbuildDir = checkEsbuildDir; +function updateAutoImportAlgm() { + exports.config.autoImportAlgm = vscode_1.workspace.getConfiguration('algorithm').get('autoImportAlgm') || false; + checkAlgm(); +} +function onChangeConfig(questionsProvider, e) { + if (e.affectsConfiguration('algorithm.nodePath')) { + updateNodePath(); + } + if (e.affectsConfiguration('algorithm.javacPath')) { + updateJavacPath(); + } + if (e.affectsConfiguration('algorithm.javaPath')) { + updateJavaPath(); + } + if (e.affectsConfiguration('algorithm.lang')) { + updateLang(); + initDir(); + cache_1.cache.removeCache(); + questionsProvider.refresh(); + } + if (e.affectsConfiguration('algorithm.codeLang')) { + updateCodeLang(); + initDir(); + } + if (e.affectsConfiguration('algorithm.database')) { + updateDataBaseLang(); + } + if (e.affectsConfiguration('algorithm.autoImportStr')) { + updateAutoImportStr(); + } + if (e.affectsConfiguration('algorithm.baseDir')) { + updateBaseDir(); + /** + * do not init baseDir, as user change the baseDir, + * and then do something activating the extension, + * finally change the baseDir again. + * All these baseDirs may be initialized even if no question file open. + * Check the dir when question file open instead. + */ + } + if (e.affectsConfiguration('algorithm.autoImportAlgm')) { + updateAutoImportAlgm(); + } +} +exports.onChangeConfig = onChangeConfig; +init(); +//# sourceMappingURL=config.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/db.js b/tools/supperchong.algorithm/out/db.js new file mode 100644 index 0000000..d68c489 --- /dev/null +++ b/tools/supperchong.algorithm/out/db.js @@ -0,0 +1,37 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getDb = void 0; +const db_1 = require("./fileStorage/db"); +const config_1 = require("./config"); +const filename = 'question'; +const dbMap = {}; +function getDb() { + return __awaiter(this, void 0, void 0, function* () { + const lang = config_1.config.lang; + const db = dbMap[lang]; + if (db) { + return db; + } + else { + const dbDir = config_1.config.dbDir; + const db = new db_1.default({ + dbDir, + filename: filename, + }); + yield db.init(); + dbMap[lang] = db; + return db; + } + }); +} +exports.getDb = getDb; +//# sourceMappingURL=db.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/debug/launch.js b/tools/supperchong.algorithm/out/debug/launch.js new file mode 100644 index 0000000..6bc7441 --- /dev/null +++ b/tools/supperchong.algorithm/out/debug/launch.js @@ -0,0 +1,97 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.tranfromToCustomBreakpoint = exports.registerDebug = void 0; +/* eslint-disable indent */ +const vscode_1 = require("vscode"); +const config_1 = require("../config"); +const vscode = require("vscode"); +const path = require("path"); +const util_1 = require("../util"); +const util_2 = require("../common/util"); +function registerDebug() { + let breaks = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + class ConfigurationProvider { + provideDebugConfigurations(_folder, _token) { + const debugConfiguration = util_1.getDebugConfig(); + return [debugConfiguration]; + } + /** + * Massage a debug configuration just before a debug session is being launched, + * e.g. add all missing attributes to the debug configuration. + */ + resolveDebugConfigurationWithSubstitutedVariables(_folder, debugConfig, _token) { + const { nodeBinPath } = config_1.config; + debugConfig.runtimeExecutable = nodeBinPath; + return debugConfig; + } + } + class TaskProvider { + provideTasks() { + const { debugOptionsFilePath, nodeBinPath } = config_1.config; + const debugTaskFilePath = path.resolve(__dirname, '../debugTask', 'index.js'); + const taskName = 'build'; + const tasks = [ + new vscode.Task({ + type: TaskProvider.TaskType, + }, vscode.TaskScope.Workspace, taskName, TaskProvider.TaskType, new vscode.ProcessExecution(nodeBinPath, [debugTaskFilePath, '${file}', debugOptionsFilePath])), + ]; + const param = serializeBreaks(breaks); + util_2.writeFileSync(debugOptionsFilePath, param, { encoding: 'utf8' }); + return tasks; + } + resolveTask(task, _token) { + return task; + } + } + TaskProvider.TaskType = 'algorithm'; + vscode_1.debug.onDidChangeBreakpoints((e) => { + breaks = breaks.concat(e.added); + const removePoints = e.removed; + const editPoints = e.changed; + breaks = breaks.filter((b) => !removePoints.find((v) => v.id === b.id)); + breaks = breaks.map((v) => editPoints.find((eb) => eb.id === v.id) || v); + }); + vscode.tasks.registerTaskProvider('algorithm', new TaskProvider()); + // Automatically set configuration more better + // debug.registerDebugConfigurationProvider('node', new ConfigurationProvider()) +} +exports.registerDebug = registerDebug; +function serializeBreaks(breaks) { + const pathMap = new Map(); + breaks.forEach((b) => { + const p = b.location.uri.fsPath; + const line = b.location.range.start.line; + if (!pathMap.has(p)) { + pathMap.set(p, [line]); + } + else { + pathMap.get(p).push(line); + } + }); + const r = []; + for (const key of pathMap.keys()) { + r.push({ path: key, lines: pathMap.get(key) }); + } + return JSON.stringify(r); +} +function tranfromToCustomBreakpoint(breaks) { + const pathMap = new Map(); + breaks.forEach((b) => { + const p = b.location.uri.fsPath; + const line = b.location.range.start.line; + if (!pathMap.has(p)) { + pathMap.set(p, [line]); + } + else { + pathMap.get(p).push(line); + } + }); + const r = []; + for (const key of pathMap.keys()) { + r.push({ path: key, lines: pathMap.get(key) }); + } + return r; +} +exports.tranfromToCustomBreakpoint = tranfromToCustomBreakpoint; +//# sourceMappingURL=launch.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/debugTask/index.js b/tools/supperchong.algorithm/out/debugTask/index.js new file mode 100644 index 0000000..24c6273 --- /dev/null +++ b/tools/supperchong.algorithm/out/debugTask/index.js @@ -0,0 +1,99 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.buildTsCode = exports.main = void 0; +const fs_1 = require("fs"); +const babelPlugin_1 = require("../babelPlugin"); +const rollup = require("rollup"); +const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve"); +const plugin_babel_1 = require("@rollup/plugin-babel"); +const path = require("path"); +const langConfig_1 = require("../common/langConfig"); +const util_1 = require("../common/util"); +function main(options, args) { + return __awaiter(this, void 0, void 0, function* () { + const mainFilePath = options.filePath; + const dir = path.resolve(mainFilePath, '..', '..', '..'); + const outputDir = path.join(dir, 'out'); + const codeLang = langConfig_1.getFileLang(mainFilePath); + if (![langConfig_1.CodeLang.JavaScript, langConfig_1.CodeLang.TypeScript].includes(codeLang)) { + console.log('only support JavaScript and TypeScript'); + return; + } + yield fs_1.promises.mkdir(outputDir, { recursive: true }); + const codePath = path.join(outputDir, 'code.js'); + const codeMapPath = path.join(outputDir, 'code.js.map'); + const mainFileCode = options.originCode; + const meta = options.metaData; + const funName = meta.name; + if (codeLang === langConfig_1.CodeLang.TypeScript) { + const finalCode = mainFileCode + '\n' + util_1.handleArgsType(meta, '', args, true); + return buildTsCode(finalCode, mainFilePath, path.join(dir, 'out')); + } + const bundle = yield rollup.rollup({ + input: mainFilePath, + treeshake: false, + plugins: [ + plugin_node_resolve_1.default(), + plugin_babel_1.default({ + babelHelpers: 'bundled', + comments: false, + plugins: [babelPlugin_1.outBoundArrayPlugin], + }), + ], + }); + const { output } = yield bundle.generate({ + sourcemap: true, + sourcemapPathTransform: (r, s) => { + return path.join(path.parse(s).dir, r); + }, + }); + let code = output[0].code; + const map = output[0].map; + if (funName) { + code += util_1.handleArgsType(meta, '', args) + '\n'; + } + code = code + '//# sourceMappingURL=code.js.map'; + if (map === null || map === void 0 ? void 0 : map.file) { + map.file = 'code.js'; + } + fs_1.writeFileSync(codePath, code); + fs_1.writeFileSync(codeMapPath, JSON.stringify(map)); + }); +} +exports.main = main; +function buildTsCode(text, filePath, dir) { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require('esbuild') + .build({ + stdin: { + contents: text, + loader: 'ts', + resolveDir: dir, + sourcefile: filePath, + }, + platform: 'node', + mainFields: ['module', 'main'], + bundle: true, + format: 'esm', + treeShaking: true, + outfile: 'code.js', + absWorkingDir: dir, + sourcemap: 'inline', + }) + .catch((err) => { + console.log(err); + }); + }); +} +exports.buildTsCode = buildTsCode; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/execTestCode.js b/tools/supperchong.algorithm/out/execTestCode.js new file mode 100644 index 0000000..9c20c30 --- /dev/null +++ b/tools/supperchong.algorithm/out/execTestCode.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.execTestChildProcess = void 0; +const cp = require("child_process"); +const path = require("path"); +const config_1 = require("./config"); +const vscode_1 = require("vscode"); +const notFoundReg = /node: not found/; +function execTestChildProcess(options) { + return new Promise((resolve) => { + const { nodeBinPath } = config_1.config; + const cmd = cp.spawn(nodeBinPath, [path.join(__dirname, './child_process/execTestCode.js')]); + let msg = ''; + cmd.stdout.on('data', (data) => { + console.log('data', data); + msg += data; + }); + cmd.stdin.setDefaultEncoding('utf8'); + cmd.stdin.write(JSON.stringify(options)); + cmd.stdin.end(); + // cmd.send(JSON.stringify(options)) + cmd.stderr.on('data', (message) => { + console.log('err', message.toString()); + if (notFoundReg.test(message)) { + vscode_1.window.showErrorMessage(message + ',please set the path of the nodejs'); + } + else { + vscode_1.window.showErrorMessage(message); + } + }); + cmd.on('close', () => { + resolve(msg); + console.log('child process close'); + console.log('msg', msg); + }); + }); +} +exports.execTestChildProcess = execTestChildProcess; +//# sourceMappingURL=execTestCode.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/extension.js b/tools/supperchong.algorithm/out/extension.js new file mode 100644 index 0000000..46c232d --- /dev/null +++ b/tools/supperchong.algorithm/out/extension.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.deactivate = exports.activate = void 0; +const vscode = require("vscode"); +const vscode_1 = require("vscode"); +const codelensProvider_1 = require("./provider/codelensProvider"); +const commands_1 = require("./commands"); +const questionsProvider_1 = require("./provider/questionsProvider"); +const questionPreview_1 = require("./webview/questionPreview"); +const config_1 = require("./config"); +const snippetProvider_1 = require("./provider/snippetProvider"); +const launch_1 = require("./debug/launch"); +const completionProvider_1 = require("./provider/completionProvider"); +const memoProvider_1 = require("./provider/memoProvider"); +const process_1 = require("./process"); +function activate(context) { + const subscriptions = context.subscriptions; + completionProvider_1.registerCompletionItemProvider(context); + snippetProvider_1.registerForSnippetProviders(context); + launch_1.registerDebug(); + const codelensProvider = new codelensProvider_1.CodelensProvider(); + vscode_1.languages.registerCodeLensProvider('*', codelensProvider); + const questionsProvider = new questionsProvider_1.QuestionsProvider(vscode.workspace.workspaceFolders, context.extensionPath); + config_1.config.questionsProvider = questionsProvider; + const memoProvider = new memoProvider_1.MemoProvider(); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.testCode', commands_1.testCodeCommand)); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.debugCode', commands_1.debugCodeCommand)); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.buildCode', commands_1.buildCodeCommand.bind(null, context))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.submit', commands_1.submitCommand.bind(null, questionsProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.getDescription', commands_1.getDescriptionCommand.bind(null, context.extensionPath))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.questionPreview', questionPreview_1.createQuestionPanelCommand.bind(null, context.extensionPath))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.refreshQuestions', commands_1.refreshCommand.bind(null, questionsProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.switchEndpoint', commands_1.switchEndpointCommand.bind(null, questionsProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.signIn', commands_1.signInCommand.bind(null, questionsProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.switchCodeLang', commands_1.switchCodeLangCommand.bind(null, questionsProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.search', commands_1.searchCommand)); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.memoFilePreview', commands_1.memoFilePreviewCommand)); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.addFolder', commands_1.addFolderCommand.bind(null, memoProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.addMemoFile', commands_1.addMemoFileCommand.bind(null, memoProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.removeMemoFile', commands_1.removeMemoFileCommand.bind(null, memoProvider))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.switchDataBase', commands_1.switchDataBaseCommand)); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.viewSubmitHistory', commands_1.viewSubmitHistoryCommand.bind(null, context))); + subscriptions.push(vscode_1.commands.registerCommand('algorithm.newAnswer', commands_1.newAnswerCommand)); + vscode.window.createTreeView('questions', { + treeDataProvider: questionsProvider, + showCollapseAll: true, + }); + vscode.window.createTreeView('memo', { + treeDataProvider: memoProvider, + showCollapseAll: true, + }); + subscriptions.push(vscode.workspace.onDidChangeConfiguration(config_1.onChangeConfig.bind(null, questionsProvider))); +} +exports.activate = activate; +function deactivate() { + process_1.childProcessProxy.clear(); +} +exports.deactivate = deactivate; +//# sourceMappingURL=extension.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/fileStorage/crc32_table.js b/tools/supperchong.algorithm/out/fileStorage/crc32_table.js new file mode 100644 index 0000000..91f38e2 --- /dev/null +++ b/tools/supperchong.algorithm/out/fileStorage/crc32_table.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * copy from https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-abs/06966aa2-70da-4bf9-8448-3355f277cd77?redirectedfrom=MSDN + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const crc32_table = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, + 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, + 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, + 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, + 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, + 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, + 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, + 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, + 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, + 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +]; +exports.default = crc32_table; +//# sourceMappingURL=crc32_table.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/fileStorage/db.js b/tools/supperchong.algorithm/out/fileStorage/db.js new file mode 100644 index 0000000..78bd075 --- /dev/null +++ b/tools/supperchong.algorithm/out/fileStorage/db.js @@ -0,0 +1,261 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.convertToBuffer = exports.convertToObj = void 0; +const path = require("path"); +const fs = require("fs"); +const util = require("util"); +const util_1 = require("./util"); +const util_2 = require("../common/util"); +const openAsync = util.promisify(fs.open); +const readAsync = util.promisify(fs.read); +const writeAsync = util.promisify(fs.write); +const readFileAsync = util.promisify(fs.readFile); +const META = 'Meta'; +const MAGIC = 0x125e591; +const VERSION = 1; +const HeaderConfig = [ + { + field: 'magic', + type: 'int', + len: 32, + }, + { + field: 'version', + type: 'int', + len: 32, + }, + { + field: 'checksum', + type: 'int', + len: 32, + }, + { + field: 'count', + type: 'int', + len: 32, + }, +]; +const SectionHeaderConfig = [ + { + field: 'checksum', + type: 'int', + len: 32, + }, + { + field: 'id', + type: 'int', + len: 32, + }, + { + field: 'fid', + type: 'int', + len: 32, + }, + { + field: 'offset', + type: 'int', + len: 32, + }, + { + field: 'size', + type: 'int', + len: 16, + }, + { + field: 'hash', + type: 'hex', + len: 128, + }, + { + field: 'timestamp', + type: 'int', + len: 64, + }, +]; +class Db { + // public headerFd: number + constructor(options) { + this.fds = [-1, -1]; + this.buffer = Buffer.alloc(0); + this.header = null; + this.sectionHeaders = []; + this.dbDir = options.dbDir; + this.filename = options.filename; + this.headerPath = path.join(this.dbDir, this.filename + META); + this.filePath = path.join(this.dbDir, this.filename); + } + init() { + return __awaiter(this, void 0, void 0, function* () { + yield util_2.existDir(this.dbDir); + yield util_2.existFile(this.headerPath); + yield util_2.existFile(this.filePath); + const headerFd = yield openAsync(this.headerPath, 'r+'); + const dataFd = yield openAsync(this.filePath, 'r+'); + this.fds = [headerFd, dataFd]; + const buffer = yield readFileAsync(this.headerPath); + this.buffer = buffer; + yield this._init(); + }); + } + _init() { + return __awaiter(this, void 0, void 0, function* () { + const buffer = this.buffer; + let header; + const sectionHeaders = []; + if (!buffer.length) { + const count = 0; + header = { + magic: MAGIC, + version: VERSION, + checksum: util_1.crc32(Buffer.alloc(4)), + count, + }; + yield util_2.writeFileAsync(this.headerPath, convertToBuffer(header, HeaderConfig)); + } + else { + const headerLen = getLen(HeaderConfig); + const headerBuf = buffer.slice(0, headerLen); + header = convertToObj(headerBuf, HeaderConfig); + // header = { + // magic: buffer.slice(0, 4).readInt32BE(), + // version: buffer.slice(4, 8).readInt32BE(), + // checksum: buffer.slice(8, 12).readInt32BE(), + // count: buffer.slice(12, 16).readInt32BE() + // } + const sectionHeadersBuf = buffer.slice(headerLen); + const len = getLen(SectionHeaderConfig); + for (let i = 0; i < sectionHeadersBuf.length / len; i++) { + const buf = sectionHeadersBuf.slice(i * len, (i + 1) * len); + sectionHeaders.push(convertToObj(buf, SectionHeaderConfig)); + } + } + this.header = header; + this.sectionHeaders = sectionHeaders; + }); + } + read(id) { + return __awaiter(this, void 0, void 0, function* () { + const sectionHeader = this.sectionHeaders.find((v) => v.id === id); + if (sectionHeader) { + const buf = Buffer.alloc(sectionHeader.size); + yield readAsync(this.fds[1], buf, 0, buf.length, sectionHeader.offset); + return buf.toString('utf8'); + } + return ''; + }); + } + add(question, id, fid) { + return __awaiter(this, void 0, void 0, function* () { + if (this.sectionHeaders.find((v) => v.id === id)) { + return; + } + const buffer = Buffer.from(question); + const count = this.header.count; + const last = count > 0 ? this.sectionHeaders[count - 1] : { offset: 0, size: 0 }; + const offset = last.offset + last.size; + const size = buffer.length; + const hash = util_1.md5(buffer); + const partialSecHeader = { + id, + fid, + offset, + size, + hash, + timestamp: Date.now(), + }; + const config = SectionHeaderConfig.slice(1); + const partialSecHeaderBuf = convertToBuffer(partialSecHeader, config); + const checksum = util_1.crc32(partialSecHeaderBuf); + const sectionHeader = Object.assign({ checksum }, partialSecHeader); + this.sectionHeaders[count] = sectionHeader; + const secHeaderBuf = convertToBuffer(sectionHeader, SectionHeaderConfig); + this.header.count++; + this.header.checksum = util_1.crc32(convertToBuffer(this.sectionHeaders, SectionHeaderConfig)); + const headerBuf = convertToBuffer(this.header, HeaderConfig); + const headerLen = getLen(HeaderConfig); + const secHeaderLen = getLen(SectionHeaderConfig); + const secOffset = headerLen + count * secHeaderLen; + yield Promise.all([ + writeAsync(this.fds[0], secHeaderBuf, 0, secHeaderBuf.length, secOffset), + writeAsync(this.fds[0], headerBuf, 0, headerBuf.length, 0), + writeAsync(this.fds[1], buffer, 0, buffer.length, offset), + ]); + }); + } +} +exports.default = Db; +function convertToObj(buffer, config) { + let i = 0; + const obj = {}; + for (const field of config) { + obj[field.field] = read(buffer, i, field); + i += field.len / 8; + } + return obj; +} +exports.convertToObj = convertToObj; +function convertToBuffer(obj, config) { + if (Array.isArray(obj)) { + return Buffer.concat(obj.map((v) => convertToBuffer(v, config))); + } + let i = 0; + const len = getLen(config); + const buf = Buffer.alloc(len); + for (const field of config) { + write(obj[field.field], buf, i, field); + i += field.len / 8; + } + return buf; +} +exports.convertToBuffer = convertToBuffer; +function getLen(config) { + return config.reduce((prev, cur) => prev + cur.len / 8, 0); +} +function read(buffer, offset, field) { + const mapFun = { + int: (buffer) => { + const byteLen = field.len / 8; + if (byteLen === 8) { + try { + const a = Number(buffer.readBigUInt64BE(offset)); + return a; + } + catch (err) { + console.log(buffer); + } + } + else { + return buffer.readUIntBE(offset, field.len / 8); + } + }, + hex: (buffer) => buffer.slice(offset, offset + field.len / 8).toString('hex'), + }; + const fun = mapFun[field.type]; + return fun(buffer); +} +function write(value, buffer, offset, field) { + const mapFunc = { + int: () => { + const byteLen = field.len / 8; + if (byteLen === 8) { + buffer.writeBigInt64BE(BigInt(value), offset); + } + else { + buffer.writeUIntBE(value, offset, field.len / 8); + } + }, + hex: () => Buffer.from(value, 'hex').copy(buffer, offset), + }; + const fun = mapFunc[field.type]; + return fun(); +} +//# sourceMappingURL=db.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/fileStorage/util.js b/tools/supperchong.algorithm/out/fileStorage/util.js new file mode 100644 index 0000000..e2cebe1 --- /dev/null +++ b/tools/supperchong.algorithm/out/fileStorage/util.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verify = exports.crc32 = exports.md5 = void 0; +const crypto = require("crypto"); +const crc32_table_1 = require("./crc32_table"); +function md5(data) { + const hash = crypto.createHash('md5'); + return hash.update(data).digest('hex'); +} +exports.md5 = md5; +/** + * Reference:https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-abs/06966aa2-70da-4bf9-8448-3355f277cd77?redirectedfrom=MSDN + * @param buffer + */ +function crc32(buffer) { + let crc = 0xffffffff; + let i = 0; + while (i < buffer.length) { + crc = crc32_table_1.default[(crc & 0xff) ^ buffer[i]] ^ ((crc >= 0 ? crc : Math.pow(2, 32) + crc) / 256); + i++; + } + crc = crc ^ 0xffffffff; + return crc >= 0 ? crc : Math.pow(2, 32) + crc; +} +exports.crc32 = crc32; +function verify(data, checksum) { + return crc32(data) === checksum; +} +exports.verify = verify; +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/history/answer.js b/tools/supperchong.algorithm/out/history/answer.js new file mode 100644 index 0000000..2ccf2ed --- /dev/null +++ b/tools/supperchong.algorithm/out/history/answer.js @@ -0,0 +1,121 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.answerStorage = exports.AnswerStorage = void 0; +const util_1 = require("../common/util"); +const storage_1 = require("./storage"); +const path = require("path"); +const config_1 = require("../config"); +const questionPreview_1 = require("../webview/questionPreview"); +const util_2 = require("../util"); +const langConfig_1 = require("../common/langConfig"); +const common_1 = require("../lang/common"); +const util_3 = require("../common/util"); +const fs_extra_1 = require("fs-extra"); +class AnswerStorage { + getFilePath(questionId) { + const cacheDir = path.join(config_1.config.cacheDir, 'answer'); + return path.join(cacheDir, questionId + '.json'); + } + static saveSubmit(filePath, text, result) { + const desc = util_1.getDesc(text, filePath) || ''; + storage_1.submitStorage.save({ + filePath: filePath, + text, + result, + desc, + }); + } + read(questionId) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.getFilePath(questionId); + try { + const arr = yield fs_extra_1.readJson(filePath); + return arr; + } + catch (err) { + console.log(err); + return []; + } + }); + } + save(data, questionMeta) { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const id = questionMeta.id; + const historyfilePath = this.getFilePath(id); + const arr = yield this.read(id); + const newAnswer = { + code: data, + id: util_1.generateId(), + desc: questionMeta.desc || '', + timestamp: Math.floor(Date.now() / 1000).toString(), + lang: questionMeta.lang, + questionId: id, + titleSlug: questionMeta.titleSlug, + }; + arr.push(newAnswer); + yield fs_extra_1.ensureFile(historyfilePath); + yield fs_extra_1.writeJson(historyfilePath, arr); + }); + } + updateComment({ id, questionId, comment }) { + return __awaiter(this, void 0, void 0, function* () { + const arr = yield this.read(questionId); + const historyfilePath = this.getFilePath(questionId); + const item = arr.find((v) => v.id === id); + if (item) { + item.desc = comment; + } + yield fs_extra_1.writeJson(historyfilePath, arr); + }); + } + newAnswer(filePath) { + return __awaiter(this, void 0, void 0, function* () { + const data = yield util_1.readFileAsync(filePath, { encoding: 'utf8' }); + const { questionMeta } = util_1.getFuncNames(data, filePath); + const id = questionMeta.id; + if (!id) { + return; + } + yield this.save(data, questionMeta); + const { weekname, lang: langSlug } = questionMeta; + const param = { + titleSlug: questionMeta.titleSlug, + weekname: questionMeta.weekname, + questionId: questionMeta.id, + }; + const question = yield questionPreview_1.fetchQuestion(param); + if (!question) { + return; + } + const { codeSnippets, questionFrontendId, title, translatedTitle } = question; + const codeSnippet = codeSnippets.find((codeSnippet) => codeSnippet.langSlug === langSlug); + if (codeSnippet) { + const langSlug = codeSnippet.langSlug; + const langConfig = langConfig_1.langMap[langSlug]; + const { name } = questionPreview_1.getName(questionFrontendId, title, translatedTitle, codeSnippet); + let code = util_2.preprocessCode(question, weekname, codeSnippet, name); + if (langConfig.lang === langConfig_1.CodeLang.Java) { + code = code.replace('class Solution', 'public class Solution'); + } + if (langConfig_1.isAlgorithm(langConfig.lang)) { + yield common_1.Service.handlePreImport(filePath); + } + yield util_3.writeFile(filePath, code); + } + }); + } +} +exports.AnswerStorage = AnswerStorage; +AnswerStorage.answerStorage = new AnswerStorage(); +exports.answerStorage = AnswerStorage.answerStorage; +//# sourceMappingURL=answer.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/history/answerStorage.js b/tools/supperchong.algorithm/out/history/answerStorage.js new file mode 100644 index 0000000..1c4f80e --- /dev/null +++ b/tools/supperchong.algorithm/out/history/answerStorage.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const submitStorage_1 = require("./submitStorage"); +class AnswerStorage { + static saveSubmit(filePath, text, result, desc) { + // const desc = getDesc(text, filePath) || '' + // if (desc) { + // } + submitStorage_1.submitStorage.save({ + filePath: filePath, + text, + result, + desc + }); + } + static newAnswer(filePath) { + } +} +//# sourceMappingURL=answerStorage.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/history/index.js b/tools/supperchong.algorithm/out/history/index.js new file mode 100644 index 0000000..01134fc --- /dev/null +++ b/tools/supperchong.algorithm/out/history/index.js @@ -0,0 +1,176 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.updateComment = exports.formatMemory = exports.formatTimestamp = exports.getRemoteSubmits = exports.getHistory = void 0; +const answer_1 = require("./answer"); +const storage_1 = require("./storage"); +const config_1 = require("../config"); +const common_1 = require("../model/common"); +const index_1 = require("../api/index"); +function getHistory(questionId, fn) { + return __awaiter(this, void 0, void 0, function* () { + const originAnswers = yield answer_1.answerStorage.read(questionId); + const formatAnswers = originAnswers + .map((v) => { + return { + code: fn(v.code, v.lang || ''), + obj: { + desc: v.desc, + timestamp: formatTimestamp(v.timestamp), + id: v.id, + lang: v.lang, + }, + }; + }) + .reverse(); + const answerData = { + header: [ + { + label: 'description', + key: 'desc', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'timestamp', + key: 'timestamp', + }, + ], + arr: formatAnswers, + }; + const originSubmitStorage = yield storage_1.submitStorage.read(questionId); + const formatSubmits = originSubmitStorage + .map((v) => { + return { + code: fn(v.code, v.submission.lang), + obj: Object.assign(Object.assign({}, v.submission), { memory: v.submission.memory, comment: v.submission.submissionComment, statusDisplay: v.submission.statusDisplay }), + }; + }) + .reverse(); + const submitStorageData = { + header: [ + { + label: 'statusDisplay', + key: 'statusDisplay', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'memory', + key: 'memory', + }, + { + label: 'runtime', + key: 'runtime', + }, + { + label: 'comment', + key: 'comment', + }, + ], + arr: formatSubmits, + }; + return { + id: questionId, + answerData: answerData, + localSubmit: submitStorageData, + // remoteSubmit: remoteStorageData + }; + }); +} +exports.getHistory = getHistory; +function getRemoteSubmits(questionId) { + return __awaiter(this, void 0, void 0, function* () { + const question = yield index_1.api.fetchQuestionDetailById(questionId); + const res = yield index_1.api.fetchSubmissions({ titleSlug: question.titleSlug }); + const submissions = res.submissionList.submissions || []; + const formatRemoteSubmits = submissions.map((v) => { + var _a; + return { + code: '', + obj: Object.assign(Object.assign({}, v), { memory: v.memory, timestamp: formatTimestamp(v.timestamp), comment: (_a = v === null || v === void 0 ? void 0 : v.submissionComment) === null || _a === void 0 ? void 0 : _a.comment, id: v.id }), + }; + }); + const remoteStorageData = { + header: [ + { + label: 'statusDisplay', + key: 'statusDisplay', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'memory', + key: 'memory', + }, + { + label: 'runtime', + key: 'runtime', + }, + { + label: 'comment', + key: 'comment', + }, + ], + arr: formatRemoteSubmits, + }; + return remoteStorageData; + }); +} +exports.getRemoteSubmits = getRemoteSubmits; +function formatTimestamp(time) { + if (typeof time === 'string') { + time = parseInt(time); + } + const num = time * 1000; + const date = new Date(num); + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + if (config_1.config.lang === common_1.Lang.cn) { + return `${year}/${month}/${day} ${hours}:${minutes}`; + } + else { + return `${year}/${month}/${day} ${hours}:${minutes}`; + } +} +exports.formatTimestamp = formatTimestamp; +function formatMemory(memory) { + return Math.floor(memory / (1024 * 1024)) + 'M'; +} +exports.formatMemory = formatMemory; +// export function updateComment(type: HistoryType.Answer | HistoryType.LocalSubmit, options: UpdateCommentOption): Promise +// export function updateComment(type: HistoryType.RemoteSubmit, options: UpdateRemoteCommentOption): Promise +function updateComment(type, options) { + return __awaiter(this, void 0, void 0, function* () { + switch (type) { + case common_1.HistoryType.Answer: { + return answer_1.answerStorage.updateComment(options); + } + case common_1.HistoryType.LocalSubmit: { + return storage_1.submitStorage.updateComment(options); + } + case common_1.HistoryType.RemoteSubmit: { + return storage_1.submitStorage.updateRemoteComment(options); + } + } + }); +} +exports.updateComment = updateComment; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/history/storage.js b/tools/supperchong.algorithm/out/history/storage.js new file mode 100644 index 0000000..1d261dd --- /dev/null +++ b/tools/supperchong.algorithm/out/history/storage.js @@ -0,0 +1,129 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.submitStorage = void 0; +const path = require("path"); +const config_1 = require("../config"); +const fs_extra_1 = require("fs-extra"); +const common_1 = require("../model/common"); +const api_1 = require("../api"); +const _1 = require("."); +class SubmitStorage { + constructor() { + this.arr = []; + this.isWork = false; + } + getFilePath(question_id) { + const cacheDir = path.join(config_1.config.cacheDir, 'submit'); + return path.join(cacheDir, question_id + '.json'); + } + read(question_id) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.getFilePath(question_id); + try { + const arr = yield fs_extra_1.readJson(filePath); + return arr; + } + catch (err) { + return []; + } + }); + } + save(options) { + return __awaiter(this, void 0, void 0, function* () { + if (this.isWork) { + this.arr.push(options); + } + else { + this.isWork = true; + yield this.innerSave(options); + } + }); + } + saveSubmit(options) { + if (options.desc) { + this.updateRemoteComment({ + id: options.result.submission_id, + comment: options.desc, + }); + } + this.save(options); + } + updateRemoteComment({ id, comment }) { + if (config_1.config.lang === common_1.Lang.cn && comment) { + return api_1.apiCn.api.updateComment({ + submissionId: id, + comment: comment, + }); + } + } + updateComment({ id, questionId, comment }) { + return __awaiter(this, void 0, void 0, function* () { + const arr = yield this.read(questionId); + const item = arr.find((v) => v.id === id); + if (item) { + item.submission.submissionComment = comment; + } + const filePath = this.getFilePath(questionId); + return fs_extra_1.writeJson(filePath, arr); + }); + } + innerSave(options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const id = options.result.question_id; + const r = options.result; + const filePath = this.getFilePath(id); + const obj = { + id: r.submission_id, + code: options.text, + submission: { + id: r.submission_id, + isPending: 'Not Pending', + submissionComment: options.desc || '', + lang: r.lang, + memory: _1.formatMemory(r.memory), + runtime: r.status_runtime, + statusDisplay: r.status_msg, + timestamp: _1.formatTimestamp(r.task_finish_time), + url: '/submissions/detail/' + r.submission_id + '/', + }, + result: options.result, + }; + let arr = []; + const exist = yield fs_extra_1.pathExists(filePath); + if (exist) { + arr = yield fs_extra_1.readJson(filePath); + arr.push(obj); + } + else { + arr.push(obj); + } + yield fs_extra_1.ensureFile(filePath); + yield fs_extra_1.writeJson(filePath, arr); + } + catch (err) { + console.log(err); + } + if (this.arr.length) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const opt = this.arr.shift(); + yield this.innerSave(opt); + } + else { + this.isWork = false; + } + }); + } +} +SubmitStorage.submitStorage = new SubmitStorage(); +exports.submitStorage = SubmitStorage.submitStorage; +//# sourceMappingURL=storage.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/history/submitStorage.js b/tools/supperchong.algorithm/out/history/submitStorage.js new file mode 100644 index 0000000..d56c271 --- /dev/null +++ b/tools/supperchong.algorithm/out/history/submitStorage.js @@ -0,0 +1,108 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.submitStorage = void 0; +const path = require("path"); +const config_1 = require("../config"); +const fs_extra_1 = require("fs-extra"); +const common_1 = require("../model/common"); +const api_1 = require("../api"); +// interface LocalSubmit{ +// code:string +// submission +// } +class SubmitStorage { + constructor() { + this.arr = []; + this.isWork = false; + } + getFilePath(question_id) { + const cacheDir = path.join(config_1.config.cacheDir, 'submit'); + return path.join(cacheDir, question_id + '.json'); + } + read(question_id) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.getFilePath(question_id); + return fs_extra_1.readJson(filePath); + }); + } + save(options) { + return __awaiter(this, void 0, void 0, function* () { + if (this.isWork) { + this.arr.push(options); + } + else { + this.isWork = true; + yield this.innerSave(options); + } + }); + } + saveSubmit(options) { + this.updateComment(options); + this.save(options); + } + updateComment(options) { + if (config_1.config.lang === common_1.Lang.cn && options.desc) { + api_1.apiCn.api.updateComment({ + submissionId: options.result.submissionId, + comment: options.desc + }); + } + } + innerSave(options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const id = options.result.question_id; + const r = options.result; + const filePath = this.getFilePath(id); + const obj = { + code: options.text, + submission: { + id: r.submission_id, + isPending: 'Not Pending', + submissionComment: null, + lang: r.lang, + memory: r.memory, + runtime: r.status_runtime, + statusDisplay: r.status_msg, + timestamp: r.task_finish_time, + url: '/submissions/detail/' + r.submission_id + '/' + }, + result: options.result + }; + let arr = []; + const exist = yield fs_extra_1.pathExists(filePath); + if (exist) { + arr = yield fs_extra_1.readJson(filePath); + arr.push(obj); + } + else { + arr.push(obj); + } + yield fs_extra_1.ensureFile(filePath); + yield fs_extra_1.writeJson(filePath, arr); + } + catch (err) { + console.log(err); + } + if (this.arr.length) { + const opt = this.arr.shift(); + yield this.innerSave(opt); + } + else { + this.isWork = false; + } + }); + } +} +SubmitStorage.submitStorage = new SubmitStorage(); +exports.submitStorage = SubmitStorage.submitStorage; +//# sourceMappingURL=submitStorage.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/.common.js.swp b/tools/supperchong.algorithm/out/lang/.common.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..7ed86651e04dde206296b5e35a08bd4f5235cda2 GIT binary patch literal 12288 zcmeHNL2nyH6rLbTXiHi|k+@D=A-jsZPErX~L_wl%sfrSaNXsRP!g_aXZ?fLm%*?up zLO@7d5nPd|xF9YZkU)Y97f!$dxPUi=`B!hP(yPuq!Sy&HAAEH5+U!rik=ol+q%9SXm|pn%%gFg`)%C7%zH@m^a3|!R z8y-`8!w5E)Czk*gYHCn`OWUFsSOzQumI2FvWxz6E8L$jk1}p>rK?Yo( zkb9>H`R)-okKh0E|NoE96Y@FmKHve%z*E5ebABQgz;nPK zj}h`2@G0;ia0qMw&jY7`U(OQpHSi8_16TrPfN9{zGq44`2kZkJxC$%+XMrD16Y?%_ z0PF(SfG2@-z@Lv2@)hs}a1Yo8c7W@^8Q@{yXqu4kfp36MfY*UOumYS1P6N}x@8Csq z^R4E`UX}sNfMvik@b6=w(YQz@PlShKXmK1wojb3rEDuhMIXyQfY%k_QNoSpje&8{> zOtYsYa!4pH^QoT%Q;CSE>ITyB)Slz|eiNt9SfpwS$JXjpTgIqP+ezfT;4%s+5xtie_igz(>Iwam=W#8_pYwUUlj)&#hbUu*Nw zXQED9g1I{~vp7y_>^5wVc{*zFYeLTqpPV0MN}myI@~9njwiX>0xvh|`V9E(1FHC$U zYbKkBL{Det1G$c)hbW8MrBQaJDVMYkx*#BAYl7YC86}f-op}%E7!}QgQCktao7Y#Z z9YD!d-E31WUZh`-OuZGxf;O#fR9|%a?z$&}SXJw^dV4=+*=Vx}N}r@myJ3eCQe$GK_LvlvRwVPM@G=rZQFY^3Vp+T*w!)kiOc63B|Nv zyGbBet>QF_l?p1-NDmWNmM&Hb>7jfsmZY8R)OUIUyqUh;3oYFd!_s|<(&9ELQ6o@EBA9GUcFuRVYZoPP&N(Oc#SU)m#I@a!_UxSJcIWOk znVZ?p%%1I@k2JJ`QWByz2nvO^N&k_cR8=Da2$et)L=;6Wl$N#$kc#j}rL?pN6@gOt zeeciA?A-48a&|zV-Q;((Gw;3cd+(d~_j_+WyY=>c2b}Hotrb3(R4RY+_3s>?9DAnX zzVp1wT#`niF9Bs#yBHll9Y2)uB<(d=~UcO@mE!`q<+h88%p1-j|n z`1Xq{KlZw9s;OU9z0$e#HE%j|x?zl=1%?(FT3~2_p#_E(7+PRxfuRM47WjW-fwXf$ z7&8T`j9E0r(9 zC*XZ>8jizuxCFkosZ#k(cn{nS*TaSImG7%m9)m~WUYLQK;D_M?`14m(DnAQ{VGJ&U z=U!f^d=wU-23Nwr;JEk;_!N8q9)$a$4cp;I;2E4Be+Hj|kH9c4%2Lap+*FX&}gs<{Gd2v^C{7)kgSV*7SaU}8?Gc*5$c{`#d(LsMltW1Bxl_)C z4Iu~i>jAGbtprPoV_K5V>_JiIw!@Zxa;%`t2+i|-d`D%|RV{z69r{j(s+PL-dVM6z zQtYSQI3&bR(^E64H$Stj&R^%aijkyV+HN}YetIzW_bo~}-4Uar(Qr&KiFMcnPoy?e z0D6b!-QK+KEPCy*riA5rN*CHmT>|#D1OK3xE|8$ZrG8h`4qX+R1mR4p9gjIRiC5>) zR;^&jMq_OeDp9SJcvB{LE(%&!W$Xu(amm+eJMmpwZ5EeIj8t?|6F50AtMz&FGPG$40hPxsGrhIXcqFtE>_<*A1JwpgUc}Gy^Y5oWoJj zO*wkEDn-hvJSjMrvaI}-+cM-aXiI*a8DdPOH>FYyHSRW3+MP{kB2Xc9cBVQVnnmI} z>P%oOab~^5r$X=MvY%#0#1*Zq7BFtza3uD98N7DZ7^jwek)1trw(K;WhK_58v0_~N ztQ=Pf*G*w(F}_ieh3GL;%U5YkZ`CgmK|C&|Fk%XMw@-?(tjIz%5oIOmBx)ebZ7?98 z%?0|LX6nc5i*BvUz?F-(4+|!o$(}XO*ThIw_R7;VM6_reseEvZC7$CY!Z)l8qB<|-if2dcG8|ZO|~J?n2Kou#PVa<=ZM+%|g`{YYI8xEx`oKTA)!Cc&6fotg2I15v9R_|-9I*;(>} zE|cUm?)uIOl1=v{Umf#FQorN6^M2^Z9vu`J%f8pWPA52}My_4){FpQ2#q-@oKTH$n z^l4}M*vLpdq-5?$L7epE(q%JLBRBSwZjdshQ(E~}Z*f-Jxl!(-fI-nbRoNVICLFI7 zb<*Ca^>o1x-MMZ+uN?TTG17_&{MN{h!t^OqYeQWlbD6@QLchvRR!RCRN;Ai0*}K7;X$|`-U2tl%iu}; z0uMk7?tnvZ4SW}Wz!UH@;KMc$|G*dE<8T+;33tFvP=)941^gj=8a@QGunoS258w&7 z2PR<~jKan6IeY<+!4i0IHM|`D7JtB};lpqb_;52^0WaVOcozN`?t#7VS~w5BiS7Od zz5q|dV-Ua`wBQyH`(6#h&(H$@2QAQOT;(KDH*WGHpH7E`;+qcbpVYs{VL908H?Gk;y{T z4O)l%#c0Xj7w+ydz`G*JcGJ0<;!rFjvKgVx;H)mkR{OqG%>Iuhs68J>vA@@A2VKSq zJ^l}lEvqPIgyVkb;o=%MQy{gN$A)I+sB%*J)AEyM-0sM5Px?J7xmoHXg&C%-)#sQ~ z%(rF-h*_?bWI72RgU%FlLVPAnTU2I}3B04~po2}FmOtB_cUWlQm2hOKTM}(5 ze(#&n^Y=oI8Sd5E9pBBKyc}*}CMYjfCo6a<_?k~Wjizj(pr!_6X0DrG?bKn5lR1ab zdb1RRmyAozotce&@9yNxt?N|V$2FrT^z{?`e$UU=Fs?W*QJlbUy~AP z3He07&W{6WWRkE)LSI7^RTK<(q@cOK1+(0cO6NcsU%TpU3w{t3R#%&(sGDlz`)Z>qtHz-> zT5GV(HRFXEDQI!)iCb!z`bA0`%quO6^f6~zREm#I{*0Hq0&S9#J5=Sb_$+@3Qi#E3 zlu-E;YE}O?-z(5mOarEfvYJ=6KOZ%PN=^Q_Lbn|kua{QcB%2^qC z4;WAI;7VB@gbRi1mB5OmkT0==wiM4P+UpPBb}N$vaZ!s0WLk=PtZ#e?>21npJ-3U1 zy)5^3s}9XI{aS9zjknKPpOM&Cy`~jwS^%E*R>Z_<(U&frAzMe)1I3s>Ul#{GzS1OZ z(zGj5>byOdO{X)MXINqv%=uFGKxX5@?iOT&#hEhe)bMIaKIOA<1IOKPUwEs3Vk%{ibN@Xvd*p2^Hezm#c9>s`^cT0!I;Wqlj(L*h(Kc1 z>1<@eAnX4+3z9AP0A&4d&-csz|L5VO@Qd&+Xu-8mgCBx_W3B%b{5Cua?|>t)2d;xl zL3{yUgs0#k=)xS_0b}q2>;7-TbMQNGAFMzGyWur(KKwhrfG6RX;m2VDw!*jZ0sIqu z3{Ju0;k|Gt+y=YgGWZAH=a=EL@G(fB1-FB|>k)WyA6xzG)y$Ct z*^W_vboZQXb=Y{z75h!DYabU#{J8A}?YH@dRabwe&3vu#EcfzXq|V;0l-||FhKjmx zeFqnEJDZ(`b7SarYBxI1m8tDE(3*!QY^1X~K9Rj$ySuceN*n3isLU#HX|^ftpxAm$ z!zsnuP-R+&O5148g}S`R@xrXrR^6;zp8 zSc;JA(lfbpafHcEY31OaoMF=UN6y6|rd*Uc#UusHC;oDmM`0>D*N&4^opBQNJ1P=E zK5~Sro!riDtDT|CQ*8qMoWw;*lWdX8=B!ylXfqvBr=DES-FS;rQ8!HSCz*-AY}m<> zC{Zh3reZd%$~@oY6Jf`dNJ;B#Ue3O+IE8~^#f5V&NJ`OrCr@-%oa399?Gb<#S)XrS zR_DG}DC*{AU823=idsHT+c4I(9Q_g@_9LcCC1;b^B+HvElf)8Nu&Zs!wyZLMmCi0J zyOG68R!mrUry^(V=^3gMobKy7Xc=VlLemP)YQ9p^TxwC0b1AgAbVaSzSc;Z6ymb~e z8%@`oG~^}KUCY@QG}BuuK)IYoUn$m0R7|bxEN6h~J!ZvQ)2!!eqODZg0eVf1Hqu$m z{**d9La(XLMml?SHshs=P^c~gVl1ou{~ur>_>ejOZ-2l4H0%4{gU8|B(1qLJI`|&z z`o9EO_rDFc!wanC{~mr99)b6Q{7&FU;Tx>qzX*@Q`{3R1cDNC)hs)uwSj&F|ehzMf zU2rLUopt;cRTX9#R zkVS0_!YPyTmhn}OvSqhf-`xxQ3go&nQaqMrLsriLB*f&fu&dRKI;Y$uZjL#vBrRmn z%27wn+sU4jjAX@;+J@U1lZrrLbfqXL5NoKw#O<#^OCXHYx#?t|{bo70Et{Kt@}*Oe z@t#!rP{5#cI&bEX75}hj;EHfLK~7y#dSqW>1J$P27)mJFny%@?0|XzqiHmwrz&oH zWVAX_mGCT>8xz+LTUA211id;OX67+_0vy&z)gCd=QlXm9;|n^$h(%~hW1H$ z|JiYRPiw3FJE)(1Wda#+R;sz}@+?ZuWCN7nxTI1jx;mN6Ia~O?#M#!0eVzG9 zAI_6-bRY^j=+h_EwAX$?Ng5Q>h-5n`aP9NM7^_>iuHuWPWU5uIXQ9cmlT3Mw$@JD^ zby<3p>}A?+v7#Wpr{W~~H#4=PVY!{^#M0BKx5KY%lmXNkj=JqxWsOjcD-RUremG7A+_*+(tWb%pG^i?VR=EnONq}f8&j57JC4}s_g$W_Em^aF?CS)HVwCCiw zX%QP3XLVcH#cb~gHDvHMf4Q8;wMt1O-D&2R*|0xlwP~e(nu5s-&wJ$FcOuc`Qy6OW z1O3-@Z215&S@O$lEwyZ$I2qr$dD+&q6<2kM(jyLtp4ZGgqrAc5k0lDf-m^;N>T|}f z)OO_Y|BgYlod%S#=(e*%{Y74iY7;etRhW0G;P1>MmioT6U3Vq-I8yl^f5CqP DXdmRh literal 0 HcmV?d00001 diff --git a/tools/supperchong.algorithm/out/lang/base.js b/tools/supperchong.algorithm/out/lang/base.js new file mode 100644 index 0000000..266f01e --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/base.js @@ -0,0 +1,247 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BaseLang = void 0; +const util_1 = require("../common/util"); +const util_2 = require("../common/util"); +const config_1 = require("../config"); +const index_1 = require("../api/index"); +const path_1 = require("path"); +const vscode = require("vscode"); +const launch_1 = require("../debug/launch"); +const langConfig_1 = require("../common/langConfig"); +const util_3 = require("../common/util"); +const lang_1 = require("../common/lang"); +const process_1 = require("../process"); +class BaseLang { + constructor(filePath, text) { + this.filePath = filePath; + this.text = text; + this.log = config_1.log; + if (!filePath) { + throw new Error('filePath must not empty'); + } + if (text) { + this.originCode = text; + } + this.commentToken = langConfig_1.getFileComment(filePath); + } + getOriginCode() { + return __awaiter(this, void 0, void 0, function* () { + if (this.originCode) { + return this.originCode; + } + const originCode = yield util_1.readFileAsync(this.filePath, { + encoding: 'utf8', + }); + this.originCode = originCode; + return this.originCode; + }); + } + getQuestionMeta() { + return __awaiter(this, void 0, void 0, function* () { + const originCode = yield this.getOriginCode(); + const { questionMeta } = util_2.getFuncNames(originCode, this.filePath); + const id = questionMeta.id; + if (!id) { + this.log.appendLine('id is null'); + return; + } + const question = yield index_1.api.fetchQuestionDetailById(id); + if (!question) { + this.log.appendLine('question not found'); + return; + } + const metaData = JSON.parse(question.metaData); + return metaData; + }); + } + resolveArgsFromBreaks(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.filePath; + const customBreakpoints = launch_1.tranfromToCustomBreakpoint(breaks); + const customBreakPoint = customBreakpoints.find((c) => c.path === filePath); + if (!customBreakPoint) { + throw new Error('breakpoint not found, please set breakpoint first'); + } + const originCode = yield this.getOriginCode(); + const questionMeta = (yield this.getQuestionMeta()); + if (!questionMeta) { + throw new Error('questionMeta not found '); + } + const codeLines = originCode.split('\n'); + const lines = customBreakPoint.lines; + const line = lines.find((num) => this.testRegExp.test(codeLines[num])); + if (!Number.isInteger(line)) { + throw new Error('please select the test case'); + } + const { args } = util_3.parseCommentTest(codeLines[line]); + return args; + }); + } + handleResult(stdout, caseList) { + const testResultList = caseList.map((v) => { + return { + args: v.args, + expect: v.result, + }; + }); + const regexp = /resultabc(\d+):(.+?)resultend/g; + let r; + while ((r = regexp.exec(stdout))) { + const index = r[1]; + const result = r[2]; + testResultList[index].result = result; + } + return testResultList; + } + waitExecTest(p, caseList) { + return __awaiter(this, void 0, void 0, function* () { + const child = p.child; + process_1.childProcessProxy.add(child); + try { + const { stdout } = yield p; + const testResultList = this.handleResult(stdout, caseList); + process_1.childProcessProxy.remove(child); + return util_2.handleMsg(testResultList); + } + catch (err) { + if (err.killed) { + config_1.log.appendLine(`timeout ${lang_1.defaultTimeout}ms`); + } + process_1.childProcessProxy.remove(child); + config_1.log.appendLine(err); + } + }); + } + runMultiple(caseList, originCode, funcName) { + return __awaiter(this, void 0, void 0, function* () { + const testResultList = []; + for (const { args, result: expect } of caseList) { + try { + const result = yield this.runInNewContext(args, originCode, funcName); + testResultList.push({ + args: args.join(','), + expect: expect, + result, + }); + } + catch (err) { + const msg = `× @test(${args.join(',')})\n`; + path_1.resolve(msg + err.stderr); + return; + } + } + return util_2.handleMsg(testResultList); + }); + } + execTest(testCase) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.filePath; + const caseList = util_2.parseTestCase(testCase); + const originCode = yield util_1.readFileAsync(filePath, { encoding: 'utf8' }); + const { questionMeta } = util_2.getFuncNames(originCode, filePath); + const id = questionMeta.id; + if (!id) { + config_1.log.appendLine('id is null'); + return; + } + const question = yield index_1.api.fetchQuestionDetailById(id); + if (!question) { + config_1.log.appendLine('question not found'); + return; + } + const metaData = JSON.parse(question.metaData); + const funcName = metaData.name; + if (!caseList.length) { + return; + } + return this.runMultiple(caseList, originCode, funcName); + }); + } + getTestCaseList(text) { + const testRegExp = this.commentToken === '#' + ? /#\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + : /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + const funcRegExp = this.funcRegExp; + const testCase = []; + const lines = text.split(/\n/); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (testRegExp.test(line)) { + testCase.push(line); + } + else if (funcRegExp.test(line)) { + const testCaseList = [ + { + line: i, + testCase, + funcName: '', + paramsTypes: [], + resultType: '', + }, + ]; + return testCaseList; + } + } + return []; + } + debugCodeCommand(folder, breaks) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield this.beforeDebug(breaks); + } + catch (err) { + config_1.log.appendLine(err.message); + config_1.log.show(); + return; + } + const debugConfiguration = yield this.getDebugConfig(breaks); + vscode.debug.startDebugging(folder, debugConfiguration); + }); + } + buildCode() { + return __awaiter(this, void 0, void 0, function* () { + const originCode = yield this.getOriginCode(); + const { questionMeta } = util_2.getFuncNames(originCode, this.filePath); + const commentToken = langConfig_1.getFileComment(this.filePath); + const code = originCode + .split('\n') + .filter((line) => !isComment(line, commentToken) && !this.shouldRemoveInBuild(line)) + .join('\n'); + return { + code, + questionMeta, + }; + }); + } + addComment(text, comment, _funcName) { + const lines = text.split('\n'); + const n = lines.length; + for (let i = n - 1; i >= 0; i--) { + if (this.testRegExp.test(lines[i])) { + const newLine = this.commentToken + comment; + return [...lines.slice(0, i + 1), newLine, ...lines.slice(i + 1)].join('\n'); + } + } + for (let i = 0; i < n; i++) { + if (this.funcRegExp.test(lines[i])) { + const newLine = this.commentToken + comment; + return [...lines.slice(0, i + 1), newLine, ...lines.slice(i + 1)].join('\n'); + } + } + } +} +exports.BaseLang = BaseLang; +function isComment(line, commentToken) { + return line.trimLeft().startsWith(commentToken); +} +//# sourceMappingURL=base.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/bash.js b/tools/supperchong.algorithm/out/lang/bash.js new file mode 100644 index 0000000..b543398 --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/bash.js @@ -0,0 +1,60 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BashParse = void 0; +const config_1 = require("../config"); +const util_1 = require("../common/util"); +const util_2 = require("../common/util"); +class BashParse { + constructor(filePath, text) { + this.filePath = filePath; + this.text = text; + this.commentToken = '#'; + this.log = config_1.log; + if (!filePath) { + throw new Error('filePath must not empty'); + } + if (text) { + this.originCode = text; + } + } + getOriginCode() { + return __awaiter(this, void 0, void 0, function* () { + if (this.originCode) { + return this.originCode; + } + const originCode = yield util_1.readFileAsync(this.filePath, { + encoding: 'utf8', + }); + this.originCode = originCode; + return this.originCode; + }); + } + buildCode() { + return __awaiter(this, void 0, void 0, function* () { + const originCode = yield this.getOriginCode(); + const { questionMeta } = util_2.getFuncNames(originCode, this.filePath); + const code = originCode + .split('\n') + .filter((line) => !this.isComment(line)) + .join('\n'); + return { + code, + questionMeta, + }; + }); + } + isComment(line) { + return line.trim().startsWith('#'); + } +} +exports.BashParse = BashParse; +//# sourceMappingURL=bash.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/c.js b/tools/supperchong.algorithm/out/lang/c.js new file mode 100644 index 0000000..180c1a0 --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/c.js @@ -0,0 +1,375 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CParse = void 0; +const cp = require("child_process"); +const fs_extra_1 = require("fs-extra"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +const util_2 = require("../common/util"); +const config_1 = require("../config"); +const util_3 = require("util"); +const launch_1 = require("../debug/launch"); +const path = require("path"); +const base_1 = require("./base"); +const util_4 = require("../common/util"); +const execFileAsync = util_3.promisify(cp.execFile); +const langTypeMap = { + 'integer': 'int', + 'string': 'string', + 'boolean': 'bool', + 'integer[]': 'vector', + 'string[]': 'vector', + 'integer[][]': 'vector>', + 'double': 'double', + 'ListNode': 'ListNode *', + 'TreeNode': 'TreeNode *', + 'ListNode[]': 'vector', + 'TreeNode[]': 'vector', + 'character[][]': 'vector>', + 'string[][]': 'vector>', + 'list': 'vector', + 'list': 'vector', + 'list>': 'vector>', + 'list>': 'vector>', + 'list': 'vector', + 'list': 'vector' +}; +class CParse extends base_1.BaseLang { + constructor(filePath, text) { + super(filePath, text); + this.filePath = filePath; + this.text = text; + this.funcRegExp = /^(\s*class Solution)/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + this.cwd = path.join(filePath, '..', '..'); + this.mainFilePath = path.join('main', 'main.cpp'); + } + // static preImport: string = 'package main' + static getPreImport(name, extraTypeSet) { + return pretty_tag_1.tag ` + #include + #include + #include + #include "algm/algm.h" + using namespace std; + `; + } + handleParam(index, paramType) { + const langType = langTypeMap[paramType]; + if (!langType) { + throw new Error("not support param type:" + paramType); + } + const handleConfig = [{ + type: 'integer', + handleFn: 'parseInteger' + }, { + type: 'string', + handleFn: 'parseString' + }, { + type: 'integer[]', + handleFn: 'parseIntegerArr' + }, { + type: 'string[]', + handleFn: 'parseStringArr' + }, { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr' + }, { + type: 'double', + handleFn: 'parseFloat' + }, { + type: "ListNode", + handleFn: "parseListNode" + }, { + type: "TreeNode", + handleFn: "parseTreeNode" + }, { + type: "ListNode[]", + handleFn: "parseListNodeArr" + }, { + type: "TreeNode[]", + handleFn: "parseTreeNodeArr" + }, { + type: "character[][]", + handleFn: "parseStringArrArr" + }, { + type: "string[][]", + handleFn: "parseStringArrArr" + }, { + type: "list", + handleFn: 'parseStringArr' + }, { + type: 'list>', + handleFn: 'parseStringArrArr' + }, { + type: 'list', + handleFn: 'parseIntegerArr' + }, { + type: 'list>', + handleFn: 'parseIntegerArrArr' + }]; + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `${langType} arg${index} = ${handleFn}(args[${index}]);`; + } + } + throw new Error(`paramType ${paramType} not support`); + } + handleReturn(paramCount, funcName, returnType, firstParamType) { + let isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const langType = langTypeMap[returnType]; + if (!langType) { + throw new Error("not support return type:" + returnType); + } + const handleConfig = [{ + type: 'integer', + handleFn: 'serializeInteger', + }, { + type: 'string', + handleFn: 'serializeString', + }, { + type: 'double', + handleFn: 'serializeFloat', + }, { + type: 'boolean', + handleFn: 'serializeBool', + }, { + type: "ListNode", + handleFn: "serializeListNode" + }, { + type: "TreeNode", + handleFn: "serializeTreeNode" + }, + { + type: 'integer[]', + handleFn: 'serializeIntegerArr' + }, { + type: 'list', + handleFn: 'serializeIntegerArr' + }, + { + type: 'string[]', + handleFn: 'serializeStringArr' + }, { + type: 'list', + handleFn: 'serializeStringArr' + }, + { + type: "ListNode[]", + handleFn: "serializeListNodeArr" + }, { + type: "TreeNode[]", + handleFn: "serializeTreeNodeArr" + }, { + type: 'integer[][]', + handleFn: 'serializeIntegerArrArr' + }, + { + type: 'list>', + handleFn: 'serializeIntegerArrArr' + }, + { + type: "character[][]", + handleFn: "serializeStringArrArr" + }, { + type: "string[][]", + handleFn: "serializeStringArrArr" + }, { + type: 'list>', + handleFn: 'serializeStringArrArr' + }]; + const argStr = Array(paramCount).fill(0).map((_, i) => `arg${i}`).join(','); + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + ${langType} result=s->${funcName}(${argStr}); + string resultabc =${handleFn}(result); + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + s->${funcName}(${argStr}); + string resultabc =${handleFn}(arg0); + `; + return funcExpression; + } + } + } + throw new Error(`returnType ${returnType} not support`); + } + handleArgsType() { + return __awaiter(this, void 0, void 0, function* () { + const meta = yield this.getQuestionMeta(); + if (!meta) { + throw new Error('question meta not found'); + } + const params = meta.params || []; + let rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { name, type } = params[i]; + argExpressions[i] = this.handleParam(i, type); + } + const name = path.parse(this.filePath).name; + const argExpression = argExpressions.join('\n'); + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type); + return pretty_tag_1.tag ` + #include "question/${name}.cpp" + #include "regex" + #include "algm/parse.h" + int main(int argc, char *argv[]) + { + string str = argv[1]; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + // cout< args = arr[i]; + Solution *s = new Solution(); + ${argExpression} + ${rtExpression} + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; + } + `; + }); + } + ensureCommonModuleFile() { + return __awaiter(this, void 0, void 0, function* () { + // const dir = config. + const algmDir = path.resolve(this.filePath, '..', '..', 'algm'); + // const files = await readdirAsync(algmDir) + const sourceDir = path.resolve(__dirname, '..', '..', 'template', 'cpp'); + const names = ['algm.h', 'ListNode.h', 'TreeNode.h', 'parse.h']; + yield Promise.all(names.map((name) => __awaiter(this, void 0, void 0, function* () { + const src = path.join(sourceDir, name); + const dst = path.join(algmDir, name); + const isExist = yield fs_extra_1.pathExists(dst); + if (!isExist) { + return fs_extra_1.copy(src, dst); + } + }))); + }); + } + runMultiple(caseList, originCode, funcName) { + return __awaiter(this, void 0, void 0, function* () { + const argsArr = caseList.map(v => v.args); + yield this.buildMainFile(); + const cwd = this.cwd; + try { + const { stdout, stderr } = yield execFileAsync('./main/main', [JSON.stringify(argsArr).replace(/"|\\|\s/g, (s) => `\\${s}`)], { timeout: 10000, cwd: cwd, shell: true }); + let testResultList = this.handleResult(stdout, caseList); + return util_2.handleMsg(testResultList); + } + catch (err) { + config_1.log.appendLine(err); + } + }); + } + runInNewContext(args, originCode, funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureCommonModuleFile(); + return; + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + yield this.buildMainFile(); + }); + } + buildMainFile() { + return __awaiter(this, void 0, void 0, function* () { + yield this.writeTestCase(); + const cppPath = 'g++'; + const dir = path.parse(this.filePath).dir; + const dirParse = path.parse(dir); + const cwd = dirParse.dir; + const mainFilePath = this.mainFilePath; + yield execFileAsync(cppPath, ['-I', '.', '-g', mainFilePath, '-o', 'main/main'], { timeout: 10000, cwd: cwd, shell: true }); + }); + } + getTestFilePath() { + const testFilePath = path.join(this.filePath, '..', '..', 'main', 'main.cpp'); + return testFilePath; + } + writeTestCase() { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureCommonModuleFile(); + const finalCode = yield this.handleArgsType(); + const testFilePath = this.getTestFilePath(); + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + }); + } + getDebugConfig(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.filePath; + const customBreakpoints = launch_1.tranfromToCustomBreakpoint(breaks); + const customBreakPoint = customBreakpoints.find(c => c.path === filePath); + if (!customBreakPoint) { + throw new Error('breakpoint not found, please set breakpoint first'); + } + const originCode = yield this.getOriginCode(); + const questionMeta = yield this.getQuestionMeta(); + if (!questionMeta) { + throw new Error('questionMeta not found '); + } + const funcName = questionMeta.name; + let codeLines = originCode.split('\n'); + const lines = customBreakPoint.lines; + const line = lines.find(num => this.testRegExp.test(codeLines[num])); + if (!Number.isInteger(line)) { + throw new Error('please select the test case'); + } + const { args } = util_4.parseCommentTest(codeLines[line]); + const cwd = this.cwd; + return { + "name": "g++ - Build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": path.join(cwd, 'main/main'), + "args": [JSON.stringify([args]).replace(/"|\\|\s/g, (s) => `\\${s}`)], + "stopAtEntry": false, + "cwd": cwd, + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + }; + }); + } + shouldRemoveInBuild(line) { + return line.trim().startsWith('package'); + } +} +exports.CParse = CParse; +//# sourceMappingURL=c.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/common.js b/tools/supperchong.algorithm/out/lang/common.js new file mode 100644 index 0000000..8230768 --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/common.js @@ -0,0 +1,68 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Service = void 0; +const langConfig_1 = require("../common/langConfig"); +const python_1 = require("./python"); +const golang_1 = require("./golang"); +const java_1 = require("./java"); +const cpp_1 = require("./cpp"); +const path = require("path"); +const langConfig_2 = require("../common/langConfig"); +const javascript_1 = require("./javascript"); +const typescript_1 = require("./typescript"); +const langMap = { + [langConfig_1.CodeLang.Python3]: python_1.PythonParse, + [langConfig_1.CodeLang.Go]: golang_1.GoParse, + [langConfig_1.CodeLang.Java]: java_1.JavaParse, + [langConfig_1.CodeLang['C++']]: cpp_1.CppParse, + [langConfig_1.CodeLang.JavaScript]: javascript_1.JavascriptParse, + [langConfig_1.CodeLang.TypeScript]: typescript_1.TypescriptParse, +}; +class Service { + constructor(filePath, text) { + this.filePath = filePath; + this.text = text; + this.codeLang = langConfig_1.getFileLang(filePath); + const Parse = langMap[this.codeLang]; + if (!Parse) { + const fileParse = path.parse(filePath); + throw new Error('Currently, not support ' + fileParse.ext); + } + this.ctx = new Parse(filePath, text); + } + static getPreImport(codeLang, name, extraTypeSet) { + const Parse = langMap[codeLang]; + if (!Parse) { + return ''; + } + return Parse.getPreImport(name, extraTypeSet); + } + static handlePreImport(filePath) { + const codeLang = langConfig_1.getFileLang(filePath); + if (['JavaScript', 'TypeScript'].includes(codeLang)) { + return; + } + const service = new Service(filePath); + return service.ctx.handlePreImport(); + } + isSupport() { + return langConfig_2.enableLang.includes(this.codeLang); + } + execTest(testCase) { + return this.ctx.execTest(testCase); + } + debugCodeCommand(folder, breaks) { + return this.ctx.debugCodeCommand(folder, breaks); + } + buildCode() { + return this.ctx.buildCode(); + } + getTestCaseList(text) { + return this.ctx.getTestCaseList(text); + } + addComment(text, comment, funcName) { + return this.ctx.addComment(text, comment, funcName); + } +} +exports.Service = Service; +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/cpp.js b/tools/supperchong.algorithm/out/lang/cpp.js new file mode 100644 index 0000000..d280c12 --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/cpp.js @@ -0,0 +1,395 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CppParse = void 0; +const cp = require("child_process"); +const fs_extra_1 = require("fs-extra"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +const util_2 = require("util"); +const path = require("path"); +const base_1 = require("./base"); +const lang_1 = require("../common/lang"); +const execFileAsync = util_2.promisify(cp.execFile); +const GCC = 'g++ -std=c++17'; +const langTypeMap = { + integer: 'int', + string: 'string', + boolean: 'bool', + 'integer[]': 'vector', + 'string[]': 'vector', + 'integer[][]': 'vector>', + double: 'double', + ListNode: 'ListNode *', + TreeNode: 'TreeNode *', + 'ListNode[]': 'vector', + 'TreeNode[]': 'vector', + 'character[][]': 'vector>', + 'string[][]': 'vector>', + 'list': 'vector', + 'list': 'vector', + 'list>': 'vector>', + 'list>': 'vector>', + 'list': 'vector', + 'list': 'vector', +}; +class CppParse extends base_1.BaseLang { + constructor(filePath, text) { + super(filePath, text); + this.filePath = filePath; + this.text = text; + this.funcRegExp = /^(\s*class Solution)/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + //this.cwd = path.join(filePath, '..', '..'); + this.sln_dir=path.parse(filePath).dir + this.cwd = this.sln_dir + this.prj_dir=path.join(this.sln_dir, '..') + this.sln_fold = path.relative(this.prj_dir, this.sln_dir) + //this.mainFilePath = path.join('main', 'main.cpp'); + this.mainFilePath = path.join(this.sln_dir, 'main.cpp'); + } + // static preImport: string = 'package main' + static getPreImport() { + return pretty_tag_1.tag ` + #define print(...) + `; + } + handleParam(index, paramType) { + const langType = langTypeMap[paramType]; + if (!langType) { + throw new Error('not support param type:' + paramType); + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + { + type: 'character[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseStringArr', + }, + { + type: 'list>', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseIntegerArr', + }, + { + type: 'list>', + handleFn: 'parseIntegerArrArr', + }, + ]; + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `${langType} arg${index} = ${handleFn}(args[${index}]);`; + } + } + throw new Error(`paramType ${paramType} not support`); + } + handleReturn(paramCount, funcName, returnType, firstParamType) { + const isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const langType = langTypeMap[returnType]; + if (!langType) { + throw new Error('not support return type:' + returnType); + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInteger', + }, + { + type: 'string', + handleFn: 'serializeString', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeBool', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeIntegerArr', + }, + { + type: 'list', + handleFn: 'serializeIntegerArr', + }, + { + type: 'string[]', + handleFn: 'serializeStringArr', + }, + { + type: 'list', + handleFn: 'serializeStringArr', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'list>', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'character[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'string[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'list>', + handleFn: 'serializeStringArrArr', + }, + ]; + const argStr = Array(paramCount) + .fill(0) + .map((_, i) => `arg${i}`) + .join(','); + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + ${langType} result=s->${funcName}(${argStr}); + string resultabc =${handleFn}(result); + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + s->${funcName}(${argStr}); + string resultabc =${handleFn}(arg0); + `; + return funcExpression; + } + } + } + throw new Error(`returnType ${returnType} not support`); + } + handleArgsType(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + const meta = (yield this.getQuestionMeta()); + if (!meta) { + throw new Error('question meta not found'); + } + const params = meta.params || []; + const rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { type } = params[i]; + argExpressions[i] = this.handleParam(i, type); + } + const name = path.parse(this.filePath).name; + const argExpression = argExpressions.join('\n'); + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type); + return pretty_tag_1.tag ` + #include "stl.h" + #include "parse.h" + #include "solution.h" + int main(int argc, char *argv[]) + { + string str = "${argsStr}"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + ${argExpression} + ${rtExpression} + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; + } + `; + }); + } + ensureCommonModuleFile() { + return __awaiter(this, void 0, void 0, function* () { + // const dir = config. + const algmDir = path.resolve(this.prj_dir, '..', 'include', 'algm'); + // const files = await readdirAsync(algmDir) + const sourceDir = path.resolve(__dirname, '..', '..', 'template', 'cpp'); + const names = ['algm.h', 'ListNode.h', 'TreeNode.h', 'parse.h']; + yield Promise.all(names.map((name) => __awaiter(this, void 0, void 0, function* () { + const src = path.join(sourceDir, name); + const dst = path.join(algmDir, name); + const isExist = yield fs_extra_1.pathExists(dst); + if (!isExist) { + return fs_extra_1.copy(src, dst); + } + }))); + }); + } + getExecProgram() { + const cwd = this.cwd; + return path.join(cwd, 'test.exe'); + } + runMultiple(caseList, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + const argsArr = caseList.map((v) => v.args); + const argsStr = JSON.stringify(argsArr); + yield this.buildMainFile(argsStr); + const cwd = this.cwd; + const execProgram = this.getExecProgram(); + const p = execFileAsync(execProgram, { + cwd: cwd, + timeout: lang_1.defaultTimeout + }); + return this.waitExecTest(p, caseList); + }); + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureCommonModuleFile(); + return; + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const str = JSON.stringify([args]); + yield this.buildMainFile(str); + }); + } + buildMainFile(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`); + yield this.writeTestCase(argsStr); + const cwd = this.cwd; + const mainFilePath = this.mainFilePath; + yield execFileAsync(GCC, ['-I', '.', '-g', + '-I'+this.prj_dir+'/../include', + '-I'+this.prj_dir+'/../include/algm', + 'main.cpp', '-o', 'test.exe'], { cwd: cwd, shell: true }); + }); + } + getTestFilePath() { + const cwd = this.cwd; + const testFilePath = path.join(this.sln_dir, 'main.cpp'); + return testFilePath; + } + writeTestCase(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureCommonModuleFile(); + const finalCode = yield this.handleArgsType(argsStr); + const testFilePath = this.getTestFilePath(); + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + }); + } + getDebugConfig(_breaks) { + return __awaiter(this, void 0, void 0, function* () { + const cwd = this.cwd; + const execProgram = this.getExecProgram(); + return { + name: 'g++ - Build and debug active file', + type: 'cppdbg', + request: 'launch', + program: execProgram, + args: [], + stopAtEntry: false, + cwd: cwd, + environment: [], + externalConsole: false, + MIMode: 'gdb', + setupCommands: [ + { + description: 'Enable pretty-printing for gdb', + text: '-enable-pretty-printing', + ignoreFailures: true, + }, + ], + }; + }); + } + shouldRemoveInBuild(line) { + return line.trim().startsWith('#include "algm/algm.h"'); + } +} +exports.CppParse = CppParse; +//# sourceMappingURL=cpp.js.map diff --git a/tools/supperchong.algorithm/out/lang/database.js b/tools/supperchong.algorithm/out/lang/database.js new file mode 100644 index 0000000..6a581ed --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/database.js @@ -0,0 +1,60 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DataBaseParse = void 0; +const config_1 = require("../config"); +const util_1 = require("../common/util"); +const util_2 = require("../common/util"); +class DataBaseParse { + constructor(filePath, text) { + this.filePath = filePath; + this.text = text; + this.commentToken = '#'; + this.log = config_1.log; + if (!filePath) { + throw new Error('filePath must not empty'); + } + if (text) { + this.originCode = text; + } + } + getOriginCode() { + return __awaiter(this, void 0, void 0, function* () { + if (this.originCode) { + return this.originCode; + } + const originCode = yield util_1.readFileAsync(this.filePath, { + encoding: 'utf8', + }); + this.originCode = originCode; + return this.originCode; + }); + } + buildCode() { + return __awaiter(this, void 0, void 0, function* () { + const originCode = yield this.getOriginCode(); + const { questionMeta } = util_2.getFuncNames(originCode, this.filePath); + const code = originCode + .split('\n') + .filter((line) => !this.isComment(line)) + .join('\n'); + return { + code, + questionMeta, + }; + }); + } + isComment(line) { + return line.trim().startsWith('#'); + } +} +exports.DataBaseParse = DataBaseParse; +//# sourceMappingURL=database.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/golang.js b/tools/supperchong.algorithm/out/lang/golang.js new file mode 100644 index 0000000..358b50d --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/golang.js @@ -0,0 +1,343 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GoParse = void 0; +const cp = require("child_process"); +const fs_extra_1 = require("fs-extra"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +const util_2 = require("util"); +const path = require("path"); +const base_1 = require("./base"); +const os_1 = require("os"); +const lang_1 = require("../common/lang"); +const execFileAsync = util_2.promisify(cp.execFile); +class GoParse extends base_1.BaseLang { + constructor(filePath, text) { + super(filePath, text); + this.filePath = filePath; + this.text = text; + this.funcRegExp = /^(\s*func)/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + this.cwd = path.dirname(filePath); + } + static getPreImport() { + return 'package main'; + } + handleParam(index, paramType) { + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'deserializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'deserializeTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'deserializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'deserializeTreeNodeArr', + }, + { + type: 'character[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + ]; + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `arg${index} := ${handleFn}(unitArgs[${index}]);`; + } + } + throw new Error(`paramType ${paramType} not support`); + } + handleReturn(paramCount, funcName, returnType, firstParamType) { + const isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInterface', + }, + { + type: 'string', + handleFn: 'serializeInterface', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeInterface', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeInterface', + }, + { + type: 'list', + handleFn: 'serializeInterface', + }, + { + type: 'string[]', + handleFn: 'serializeInterface', + }, + { + type: 'list', + handleFn: 'serializeInterface', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeInterface', + }, + { + type: 'list>', + handleFn: 'serializeInterface', + }, + { + type: 'character[][]', + handleFn: 'serializeInterface', + }, + { + type: 'string[][]', + handleFn: 'serializeInterface', + }, + { + type: 'list>', + handleFn: 'serializeInterface', + }, + ]; + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(','); + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + result := ${funcName}(${argStr}); + resultabc :=${handleFn}(result); + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + ${funcName}(${argStr}) + resultabc := ${handleFn}(arg0); + `; + return funcExpression; + } + } + } + throw new Error(`returnType ${returnType} not support`); + } + handleArgsType(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + const meta = (yield this.getQuestionMeta()); + if (!meta) { + throw new Error('question meta not found'); + } + const params = meta.params || []; + const rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { type } = params[i]; + argExpressions[i] = this.handleParam(i, type); + } + const argExpression = argExpressions.join('\n'); + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type); + return pretty_tag_1.tag ` + package main + import "fmt" + func main(){ + str := "${argsStr}" + arr := parseStringArrArr(str) + for i:=0;i v.args); + const argsStr = JSON.stringify(argsArr); + yield this.buildMainFile(argsStr); + const mainFile = this.getExecProgram(); + const cwd = this.cwd; + const p = execFileAsync(mainFile, { + cwd: cwd, + timeout: lang_1.defaultTimeout + }); + return this.waitExecTest(p, caseList); + }); + } + ensureModFile() { + return __awaiter(this, void 0, void 0, function* () { + const cwd = this.cwd; + const modName = 'lc' + path.parse(cwd).name; + const modPath = path.join(cwd, 'go.mod'); + const isExist = yield fs_extra_1.pathExists(modPath); + const goPath = 'go'; + if (!isExist) { + yield fs_extra_1.ensureDir(cwd); + try { + yield execFileAsync(goPath, ['mod', 'init', modName], { + cwd: cwd, + shell: true, + }); + } + catch (err) { + console.log(err); + } + } + }); + } + ensureCommonModuleFile() { + return __awaiter(this, void 0, void 0, function* () { + const algmDir = this.cwd; + const sourceDir = path.resolve(__dirname, '..', '..', 'template', 'golang'); + const names = ['algm.go']; + yield Promise.all(names.map((name) => __awaiter(this, void 0, void 0, function* () { + const src = path.join(sourceDir, name); + const dst = path.join(algmDir, name); + const isExist = yield fs_extra_1.pathExists(dst); + if (!isExist) { + return fs_extra_1.copy(src, dst); + } + }))); + }); + } + buildMainFile(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + yield this.writeTestCase(argsStr); + const goPath = 'go'; + const cwd = this.cwd; + let outFile = 'main'; + if (os_1.platform() === 'win32') { + outFile = 'main.exe'; + } + yield execFileAsync(goPath, ['build', '-o', outFile, '.'], { + cwd: cwd, + shell: true, + }); + }); + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureModFile(); + yield this.ensureCommonModuleFile(); + return; + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const str = JSON.stringify([args]); + yield this.writeTestCase(str); + }); + } + getTestFilePath() { + const cwd = this.cwd; + return path.join(cwd, 'main.go'); + } + writeTestCase(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`); + const finalCode = yield this.handleArgsType(argsStr); + const testFilePath = this.getTestFilePath(); + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + }); + } + getDebugConfig() { + const dir = path.parse(this.filePath).dir; + return { + name: 'Launch Package', + type: 'go', + request: 'launch', + mode: 'debug', + program: dir, + }; + } + shouldRemoveInBuild(line) { + const preImportStr = GoParse.getPreImport(); + return line.trim().startsWith(preImportStr); + } +} +exports.GoParse = GoParse; +//# sourceMappingURL=golang.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/java.js b/tools/supperchong.algorithm/out/lang/java.js new file mode 100644 index 0000000..8ad181a --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/java.js @@ -0,0 +1,385 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.JavaParse = void 0; +const cp = require("child_process"); +const fs_extra_1 = require("fs-extra"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +const config_1 = require("../config"); +const util_2 = require("util"); +const path = require("path"); +const base_1 = require("./base"); +const lang_1 = require("../common/lang"); +const execFileAsync = util_2.promisify(cp.execFile); +const langTypeMap = { + integer: 'int', + string: 'String', + 'integer[]': 'int[]', + 'string[]': 'String[]', + 'integer[][]': 'int[][]', + double: 'double', + ListNode: 'ListNode', + TreeNode: 'TreeNode', + 'ListNode[]': 'ListNode[]', + 'TreeNode[]': 'TreeNode[]', + 'character[][]': 'String[][]', + 'string[][]': 'String[][]', + 'list': 'List', + 'list': 'List', + 'list>': 'List>', + 'list>': 'List>', + 'list': 'ListNode[]', + 'list': 'TreeNode[]', + boolean: 'boolean', +}; +class JavaParse extends base_1.BaseLang { + constructor(filePath, text) { + super(filePath, text); + this.filePath = filePath; + this.text = text; + this.funcRegExp = /^(\s*(public)? class Solution)/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + this.cwd = path.join(filePath, '..', '..'); + } + // static preImport: string = 'package main' + static getPreImport(name, extraTypeSet) { + let importStr = ''; + if (extraTypeSet.size) { + importStr = 'import algm.*;'; + } + return pretty_tag_1.tag ` + package ${name}; + ${importStr} + `; + } + handleParam(index, paramType) { + const langType = langTypeMap[paramType]; + if (!langType) { + throw new Error('not support param type:' + paramType); + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + { + type: 'character[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseIntegerList', + }, + { + type: 'list>', + handleFn: 'parseIntegerListList', + }, + { + type: 'list', + handleFn: 'parseStringList', + }, + { + type: 'list>', + handleFn: 'parseStringListList', + }, + ]; + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `${langType} arg${index} = Util.${handleFn}(unitArgs[${index}]);`; + } + } + throw new Error(`paramType ${paramType} not support`); + } + handleReturn(paramCount, funcName, returnType, firstParamType) { + const isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const langType = langTypeMap[returnType]; + if (!langType) { + throw new Error('not support return type:' + returnType); + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInteger', + }, + { + type: 'string', + handleFn: 'serializeString', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeBool', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeIntegerArr', + }, + { + type: 'list', + handleFn: 'serializeIntegerList', + }, + { + type: 'string[]', + handleFn: 'serializeStringArr', + }, + { + type: 'list', + handleFn: 'serializeStringArr', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'list>', + handleFn: 'serializeIntegerListList', + }, + { + type: 'character[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'string[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'list', + handleFn: 'serializeStringList', + }, + { + type: 'list>', + handleFn: 'serializeStringListList', + }, + ]; + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(','); + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + ${langType} result=s.${funcName}(${argStr}); + String resultabc =Util.${handleFn}(result); + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + s.${funcName}(${argStr}); + String resultabc =Util.${handleFn}(arg0); + `; + return funcExpression; + } + } + } + throw new Error(`returnType ${returnType} not support`); + } + handleArgsType(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + const meta = (yield this.getQuestionMeta()); + if (!meta) { + throw new Error('question meta not found'); + } + const params = meta.params || []; + const rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { type } = params[i]; + argExpressions[i] = this.handleParam(i, type); + } + const dir = path.parse(path.parse(this.filePath).dir).name; + const argExpression = argExpressions.join('\n'); + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type); + return pretty_tag_1.tag ` + package test; + import ${dir}.*; + import algm.*; + import java.util.List; + public class Test { + public static void main(String[] args){ + String str="${argsStr}"; + String[][] arr = Util.parseStringArrArr(str); + + for(int i=0;i __awaiter(this, void 0, void 0, function* () { + const src = path.join(sourceDir, name); + const dst = path.join(algmDir, name); + const isExist = yield fs_extra_1.pathExists(dst); + if (!isExist) { + return fs_extra_1.copy(src, dst); + } + }))); + }); + } + runMultiple(caseList, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + const argsArr = caseList.map((v) => v.args); + const argsStr = JSON.stringify(argsArr); + yield this.buildMainFile(argsStr); + const javaPath = config_1.config.javaPath; + const cwd = this.cwd; + const p = execFileAsync(javaPath, [`test/Test`], { + cwd: cwd, + timeout: lang_1.defaultTimeout + }); + return this.waitExecTest(p, caseList); + }); + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + yield this.ensureCommonModuleFile(); + return; + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const str = JSON.stringify([args]); + yield this.writeTestCase(str); + }); + } + getTestFilePath() { + const cwd = this.cwd; + const testFilePath = path.join(cwd, 'test', 'Test.java'); + return testFilePath; + } + writeTestCase(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`); + yield this.ensureCommonModuleFile(); + const finalCode = yield this.handleArgsType(argsStr); + const testFilePath = this.getTestFilePath(); + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + }); + } + buildMainFile(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + yield this.writeTestCase(argsStr); + const javacPath = config_1.config.javacPath; + const cwd = this.cwd; + yield execFileAsync(javacPath, [`test/Test.java`], { + cwd: cwd, + shell: true, + }); + }); + } + getDebugConfig(_breaks) { + return __awaiter(this, void 0, void 0, function* () { + const testFilePath = this.getTestFilePath(); + const cwd = this.cwd; + return { + type: 'java', + name: 'Launch Current File', + request: 'launch', + mainClass: testFilePath, + cwd: cwd, + args: '', + }; + }); + } + shouldRemoveInBuild(line) { + line = line.trim(); + return line.startsWith('package') || line.startsWith('import algm'); + } +} +exports.JavaParse = JavaParse; +//# sourceMappingURL=java.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/javascript.js b/tools/supperchong.algorithm/out/lang/javascript.js new file mode 100644 index 0000000..8ef62b2 --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/javascript.js @@ -0,0 +1,158 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.JavascriptParse = void 0; +const util_1 = require("../common/util"); +const config_1 = require("../config"); +const base_1 = require("./base"); +const execTestCode_1 = require("../execTestCode"); +const index_1 = require("../debugTask/index"); +const path = require("path"); +const babelPlugin_1 = require("../babelPlugin"); +const babel = require("@babel/core"); +const virtual = require("@rollup/plugin-virtual"); +const rollup = require("rollup"); +const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve"); +const plugin_babel_1 = require("@rollup/plugin-babel"); +const vscode_1 = require("vscode"); +const transformCode_1 = require("../common/transformCode"); +class JavascriptParse extends base_1.BaseLang { + constructor() { + super(...arguments); + this.funcRegExp = /^(?:(\s*function)|(.*=\s*function))/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + } + static getPreImport() { + return ''; + } + runMultiple(caseList, originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + const metaData = (yield this.getQuestionMeta()); + if (!metaData) { + throw new Error('question meta not found'); + } + const options = { + caseList, + originCode, + filePath: this.filePath, + metaData: metaData, + }; + return yield execTestCode_1.execTestChildProcess(options); + }); + } + shouldRemoveInBuild(_line) { + return false; + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + return; + }); + } + buildCode() { + return __awaiter(this, void 0, void 0, function* () { + try { + const filePath = this.filePath; + const text = this.text; + const dir = path.parse(filePath).dir; + const { funcNames, questionMeta } = util_1.getFuncNames(text, filePath); + const funcRunStr = 'console.log(' + funcNames.map((f) => f + '()').join('+') + ')'; + // The rollup will not transform code in virtual entry + const entry = yield babel.transformAsync(text, { + comments: false, + compact: false, + plugins: [babelPlugin_1.outBoundArrayPlugin], + }); + const entryCode = (entry === null || entry === void 0 ? void 0 : entry.code) + `\n${funcRunStr}`; + const bundle = yield rollup.rollup({ + input: 'entry', + treeshake: true, + plugins: [ + // It use virtual entry because treeshake will remove unuse code. + virtual({ + entry: entryCode, + }), + plugin_node_resolve_1.default({ rootDir: dir }), + plugin_babel_1.default({ + babelHelpers: 'bundled', + comments: false, + shouldPrintComment: () => false, + }), + ], + }); + const { output } = yield bundle.generate({}); + let code = output[0].code; + code = code.replace(funcRunStr, '').replace(/;\s*$/, ''); + return { + code, + questionMeta, + }; + } + catch (err) { + console.log('err:', err); + vscode_1.window.showInformationMessage(`parse params err: ${err}`); + return { + code: '', + questionMeta: {}, + }; + } + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const metaData = (yield this.getQuestionMeta()); + if (!metaData) { + throw new Error('question meta not found'); + } + const originCode = yield util_1.readFileAsync(this.filePath, { + encoding: 'utf8', + }); + const options = { + originCode, + filePath: this.filePath, + metaData: metaData, + }; + yield this.writeTestCase(options, args); + }); + } + writeTestCase(options, args) { + return __awaiter(this, void 0, void 0, function* () { + return index_1.main(options, args); + }); + } + getDebugConfig() { + const { nodeBinPath } = config_1.config; + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + // "preLaunchTask": "algorithm: build" + }; + } + addComment(text, comment, funcName) { + return transformCode_1.addComment(text, comment, funcName); + } +} +exports.JavascriptParse = JavascriptParse; +//# sourceMappingURL=javascript.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/python.js b/tools/supperchong.algorithm/out/lang/python.js new file mode 100644 index 0000000..bff72bd --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/python.js @@ -0,0 +1,400 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PythonParse = void 0; +const cp = require("child_process"); +const fs_extra_1 = require("fs-extra"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +const config_1 = require("../config"); +const util_2 = require("util"); +const path = require("path"); +const base_1 = require("./base"); +const os_1 = require("os"); +const lang_1 = require("../common/lang"); +const execFileAsync = util_2.promisify(cp.execFile); +class PythonParse extends base_1.BaseLang { + constructor(filePath, text) { + super(filePath, text); + this.filePath = filePath; + this.text = text; + this.funcRegExp = /^(\s*class Solution)/; + this.testRegExp = /#\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + this.handleTypeCode = pretty_tag_1.tag ` + class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + def serializeListNode(head:ListNode): + if(head==None): + return [] + node=head + arr=[] + while(node!=None): + arr.append(str(node.val)) + node=node.next + return '['+','.join(arr)+']' + def parseListNode(arr)->ListNode: + header=ListNode() + node=header + for num in arr: + node.next=ListNode(num) + node=node.next + return header.next + + def serializeTreeNode(root:TreeNode): + if(root==None): + return [] + arr=[] + queue=[root] + while(len(queue)>0): + node=queue.pop(0) + if node!=None: + arr.append(str(node.val)) + queue.append(node.left) + queue.append(node.right) + else: + arr.append("null") + i=len(arr)-1 + while(arr[i]=="null"): + i=i-1 + arr.pop() + return '['+','.join(arr)+']' + def parseTreeNode(arr)->TreeNode: + if(len(arr)==0): + return None + val=arr.pop(0) + root=TreeNode(val) + queue=[root] + while(queue): + node=queue.pop(0) + if len(arr)==0: + return root + leftVal=arr.pop(0) + if leftVal!=None: + left=TreeNode(leftVal) + node.left=left + queue.append(left) + if len(arr)==0: + return root + rightVal=arr.pop(0) + if rightVal!=None: + right=TreeNode(rightVal) + node.right=right + queue.append(right) + return root + def parseTreeNodeArr(arr): + out=[] + for item in arr: + treeNode=parseTreeNode(item) + out.append(treeNode) + return out + def serializeTreeNodeArr(arr): + treeNodeStrArr=[] + for item in arr: + treeNodeStrArr.append(serializeTreeNode(item)) + return '['+','.join(treeNodeStrArr)+']' + def parseListNodeArr(arr): + out=[] + for item in arr: + listNode=parseListNode(item) + out.append(listNode) + return out + def serializeListNodeArr(arr): + listNodeStrArr=[] + for item in arr: + listNodeStrArr.append(serializeListNode(item)) + return '['+','.join(listNodeStrArr)+']' + def serializeFloat(param): + r=str(param) + arr=r.split(".") + if len(arr)==1: + return r+".00000" + else: + decimalStr=arr[1]+"00000" + return arr[0]+"."+decimalStr[0:5] + `; + this.cwd = path.join(config_1.config.algDir, 'Python3'); + } + static getPreImport() { + const lang = config_1.config.lang; + const codeLang = config_1.config.codeLang; + return `from ${lang}.${codeLang}.mod.preImport import *`; + } + handleParam(index, paramType) { + const handleConfig = [ + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + ]; + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'double', + ]; + if (jsonType.includes(paramType)) { + return `arg${index} = unitArgs[${index}]`; + } + else { + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `arg${index} =${handleFn}(unitArgs[${index}])`; + } + } + } + throw new Error(`paramType ${paramType} not support`); + } + handleReturn(paramCount, funcName, returnType, firstParamType) { + const isVoid = returnType === 'void'; + if (isVoid) { + returnType = firstParamType; + } + const handleConfig = [ + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + ]; + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + ]; + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(','); + if (jsonType.includes(returnType)) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + result=s.${funcName}(${argStr}) + resultabc =json.dumps(result,separators=(',', ':')) + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + s.${funcName}(${argStr}) + resultabc =json.dumps(arg0,separators=(',', ':')) + `; + return funcExpression; + } + } + else { + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = pretty_tag_1.tag ` + result=s.${funcName}(${argStr}) + resultabc =${handleFn}(result) + `; + return funcExpression; + } + else { + const funcExpression = pretty_tag_1.tag ` + s.${funcName}(${argStr}) + resultabc =${handleFn}(arg0) + `; + return funcExpression; + } + } + } + } + throw new Error(`returnType ${returnType} not support`); + } + handleArgsType(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + const meta = (yield this.getQuestionMeta()); + if (!meta) { + throw new Error('question meta not found'); + } + const params = meta.params || []; + const rt = meta.return.type; + const funcName = meta.name; + const argExpressions = []; + const paramCount = params.length; + for (let i = 0; i < paramCount; i++) { + const { type } = params[i]; + argExpressions[i] = this.handleParam(i, type); + } + const filePathParse = path.parse(this.filePath); + const name = filePathParse.name; + const argExpression = argExpressions.join('\n'); + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type); + const cwd = this.cwd.replace(/\\/g, '\\\\'); + const baseDir = config_1.config.baseDir.replace(/\\/g, '\\\\'); + return pretty_tag_1.tag ` + import sys + import json + sys.path.append("${cwd}") + sys.path.append("${baseDir}") + a = __import__('${name}') + ${this.handleTypeCode} + + + arr=json.loads("${argsStr}") + for i in range(len(arr)): + unitArgs=arr[i] + s=a.Solution() + ${argExpression} + ${rtExpression} + print("resultabc"+str(i)+":"+resultabc+"resultend") + `; + }); + } + runMultiple(caseList, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + const argsArr = caseList.map((v) => v.args.map((str) => JSON.parse(str))); + const argsStr = JSON.stringify(argsArr); + yield this.buildMainFile(argsStr); + let pythonPath = 'python3'; + if (os_1.platform() === 'win32') { + pythonPath = 'python'; + } + const testFilePath = this.getTestFilePath(); + const cwd = this.cwd; + const p = execFileAsync(pythonPath, [testFilePath], { + cwd: cwd, + timeout: lang_1.defaultTimeout + }); + return this.waitExecTest(p, caseList); + }); + } + buildMainFile(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + yield this.writeTestCase(argsStr); + }); + } + shouldRemoveInBuild(line) { + const preImportStr = PythonParse.getPreImport(); + return line.trimLeft().startsWith(preImportStr); + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + const dir = config_1.config.questionDir; + const preImportFile = path.join(dir, 'mod', 'preImport.py'); + const exist = yield fs_extra_1.pathExists(preImportFile); + if (exist) { + return; + } + else { + yield fs_extra_1.ensureFile(preImportFile); + } + const data = pretty_tag_1.tag ` + from typing import List + class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + `; + if (!exist) { + yield util_1.writeFileAsync(preImportFile, data, { encoding: 'utf8' }); + } + }); + } + getTestFilePath() { + const cwd = this.cwd; + const testFilePath = path.join(cwd, 'out', 'out.py'); + return testFilePath; + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const str = JSON.stringify([args.map((v) => JSON.parse(v))]); + yield this.writeTestCase(str); + }); + } + writeTestCase(argsStr) { + return __awaiter(this, void 0, void 0, function* () { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`); + const finalCode = yield this.handleArgsType(argsStr); + const testFilePath = this.getTestFilePath(); + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + }); + } + getDebugConfig() { + const outputFile = path.join(this.cwd, 'out', 'out.py'); + return { + name: 'Python: Current File (Integrated Terminal)', + type: 'python', + request: 'launch', + program: outputFile, + console: 'integratedTerminal', + }; + } +} +exports.PythonParse = PythonParse; +//# sourceMappingURL=python.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/lang/typescript.js b/tools/supperchong.algorithm/out/lang/typescript.js new file mode 100644 index 0000000..8bcdadb --- /dev/null +++ b/tools/supperchong.algorithm/out/lang/typescript.js @@ -0,0 +1,165 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TypescriptParse = void 0; +const util_1 = require("../common/util"); +const config_1 = require("../config"); +const base_1 = require("./base"); +const execTestCode_1 = require("../execTestCode"); +const index_1 = require("../debugTask/index"); +const path = require("path"); +const babel = require("@babel/core"); +const presetTs = require("@babel/preset-typescript"); +const babelPlugin_1 = require("../babelPlugin"); +const rollup = require("rollup"); +const virtual = require("@rollup/plugin-virtual"); +const plugin_node_resolve_1 = require("@rollup/plugin-node-resolve"); +const plugin_babel_1 = require("@rollup/plugin-babel"); +const vscode_1 = require("vscode"); +const transformCode_1 = require("../common/transformCode"); +class TypescriptParse extends base_1.BaseLang { + constructor() { + super(...arguments); + this.funcRegExp = /^(?:(\s*function)|(.*=\s*function))/; + this.testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/; + } + static getPreImport() { + return ''; + } + runMultiple(caseList, originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + const metaData = (yield this.getQuestionMeta()); + if (!metaData) { + throw new Error('question meta not found'); + } + const options = { + caseList, + originCode, + filePath: this.filePath, + metaData: metaData, + }; + return yield execTestCode_1.execTestChildProcess(options); + }); + } + buildCode() { + return __awaiter(this, void 0, void 0, function* () { + try { + const filePath = this.filePath; + let text = this.text; + text = text + .split('\n') + .filter((line) => !this.shouldRemoveInBuild(line)) + .join('\n'); + const dir = path.parse(filePath).dir; + const { funcNames, questionMeta } = util_1.getFuncNames(text, filePath); + const funcRunStr = 'console.log(' + funcNames.map((f) => f + '()').join('+') + ')'; + // The rollup will not transform code in virtual entry + const entry = yield babel.transformAsync(text, { + filename: filePath, + comments: false, + compact: false, + presets: [presetTs], + plugins: [babelPlugin_1.outBoundArrayPlugin], + }); + const entryCode = (entry === null || entry === void 0 ? void 0 : entry.code) + `\n${funcRunStr}`; + const bundle = yield rollup.rollup({ + input: 'entry', + treeshake: true, + plugins: [ + // It use virtual entry because treeshake will remove unuse code. + virtual({ + entry: entryCode, + }), + plugin_node_resolve_1.default({ rootDir: dir, modulesOnly: true }), + plugin_babel_1.default({ + babelHelpers: 'bundled', + comments: false, + shouldPrintComment: () => false, + }), + ], + }); + const { output } = yield bundle.generate({}); + let code = output[0].code; + code = code.replace(funcRunStr, '').replace(/;\s*$/, ''); + return { + code, + questionMeta, + }; + } + catch (err) { + console.log('err:', err); + vscode_1.window.showInformationMessage(`parse params err: ${err}`); + return { + code: '', + questionMeta: {}, + }; + } + }); + } + shouldRemoveInBuild(line) { + return /import\s*{\s*(ListNode|TreeNode)\s*}\s*from\s*'algm'/.test(line.trimLeft()); + } + runInNewContext(_args, _originCode, _funcName) { + return __awaiter(this, void 0, void 0, function* () { + return ''; + }); + } + handlePreImport() { + return __awaiter(this, void 0, void 0, function* () { + return; + }); + } + // do some thing before debug,eg. get testcase + beforeDebug(breaks) { + return __awaiter(this, void 0, void 0, function* () { + const args = yield this.resolveArgsFromBreaks(breaks); + const metaData = (yield this.getQuestionMeta()); + if (!metaData) { + throw new Error('question meta not found'); + } + const originCode = yield util_1.readFileAsync(this.filePath, { + encoding: 'utf8', + }); + const options = { + originCode, + filePath: this.filePath, + metaData: metaData, + }; + yield this.writeTestCase(options, args); + }); + } + writeTestCase(options, args) { + return __awaiter(this, void 0, void 0, function* () { + return index_1.main(options, args); + }); + } + getDebugConfig() { + const { nodeBinPath } = config_1.config; + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + // "preLaunchTask": "algorithm: build" + }; + } + addComment(text, comment, funcName) { + return transformCode_1.addComment(text, comment, funcName); + } +} +exports.TypescriptParse = TypescriptParse; +//# sourceMappingURL=typescript.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/login/index.js b/tools/supperchong.algorithm/out/login/index.js new file mode 100644 index 0000000..305070e --- /dev/null +++ b/tools/supperchong.algorithm/out/login/index.js @@ -0,0 +1,251 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.showLoginMessage = exports.accountLogin = exports.cookieLogin = exports.githubLogin = void 0; +const _request = require("request"); +const util_1 = require("util"); +const vscode_1 = require("vscode"); +const config_1 = require("../config"); +const util_2 = require("../common/util"); +const commands_1 = require("../commands"); +function parseCookie(cookie) { + const keyValueStrArr = cookie.split(';'); + const map = {}; + keyValueStrArr.forEach((kvStr) => { + let [key, value] = kvStr.split('='); + key = key.trim(); + value = value.trim(); + map[key] = value; + }); + return map; +} +function saveCookie(cookie) { + return __awaiter(this, void 0, void 0, function* () { + const cookiePath = config_1.config.cookiePath; + const map = parseCookie(cookie); + const headers = { cookie }; + if (map['csrftoken']) { + headers['x-csrftoken'] = map['csrftoken']; + } + yield util_2.writeFileAsync(cookiePath, JSON.stringify(headers)); + }); +} +// set-cookie +function saveResCookie(cookies = []) { + return __awaiter(this, void 0, void 0, function* () { + const map = {}; + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i]; + const arr = cookie.split(';'); + const kv = arr[0]; + let [key, value] = kv.split('='); + key = key.trim(); + if (key) { + map[key] = value; + } + } + const cookieStr = Object.keys(map) + .map((key) => `${key}=${map[key]}`) + .join('; '); + const headers = { cookie: cookieStr }; + if (map['csrftoken']) { + headers['x-csrftoken'] = map['csrftoken']; + } + const cookiePath = config_1.config.cookiePath; + yield util_2.writeFileAsync(cookiePath, JSON.stringify(headers)); + }); +} +function parseFormData(html) { + const formRegExp = //; + const r = formRegExp.exec(html.replace(/\n/g, '')); + if (!r) { + return Promise.reject({ + message: 'the page of login github not found', + code: 3, + }); + } + const formStr = r[0]; + const inputRegExp = /]*name="(.*?)"(?:[^>](?!alue))*(?:value="(.*?)")?[^>]*>/g; + let inputRegExpRes = null; + let d = {}; + const defaultObj = { + 'webauthn-support': 'supported', + 'webauthn-iuvpaa-support': 'unsupported', + }; + while ((inputRegExpRes = inputRegExp.exec(formStr))) { + const name = inputRegExpRes[1]; + const value = inputRegExpRes[2]; + if (name) { + d[name] = value || ''; + } + } + d = Object.assign(d, defaultObj); + return d; +} +function githubAuth(html, request, user) { + return __awaiter(this, void 0, void 0, function* () { + let data = parseFormData(html); + data = Object.assign(data, { + login: user.name, + password: user.password, + }); + // github login and then redirect back + const res = yield request({ + url: 'https://github.com/session', + form: data, + method: 'POST', + followAllRedirects: true, + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); + let body = res.body; + if (/Incorrect username or password/.test(body)) { + return Promise.reject({ + message: 'Incorrect username or password', + code: 3, + }); + } + // enable two-factor + const twoFactorRegExp = /Two-factor authentication/; + if (twoFactorRegExp.test(body)) { + body = yield githubTwoFactorAuth(body, request); + } + return body; + }); +} +function githubTwoFactorAuth(html, request) { + return __awaiter(this, void 0, void 0, function* () { + const authenticityTokenTwoFactor = html.match(/name="authenticity_token" value="(.*?)"/); + if (authenticityTokenTwoFactor === null) { + return Promise.reject({ + message: 'get GitHub two-factor page fail', + code: 3, + }); + } + const code = yield vscode_1.window.showInputBox({ + prompt: 'input the Authentication code', + }); + if (!code) { + return Promise.reject({ + message: 'cancel login', + code: 2, + }); + } + const data = { + otp: code, + authenticity_token: authenticityTokenTwoFactor[1], + }; + const res = yield request({ + url: 'https://github.com/sessions/two-factor', + form: data, + method: 'POST', + followAllRedirects: true, + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); + return res.body; + }); +} +function githubRedirectBack(body, request) { + return __awaiter(this, void 0, void 0, function* () { + const redirectRegExp = / { + const input = vscode_1.window.createQuickPick(); + input.title = title; + input.step = step; + input.totalSteps = totalSteps; + input.placeholder = placeholder; + input.items = items; + if (activeItem) { + input.activeItems = [activeItem]; + } + input.buttons = [...(this.steps.length > 1 ? [vscode_1.QuickInputButtons.Back] : []), ...(buttons || [])]; + disposables.push(input.onDidTriggerButton((item) => { + if (item === vscode_1.QuickInputButtons.Back) { + reject(InputFlowAction.back); + } + else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + resolve(item); + } + }), input.onDidChangeSelection((items) => resolve(items[0])), input.onDidHide(() => { + ; + (() => __awaiter(this, void 0, void 0, function* () { + reject(shouldResume && (yield shouldResume()) ? InputFlowAction.resume : InputFlowAction.cancel); + }))().catch(reject); + })); + if (this.current) { + this.current.dispose(); + } + this.current = input; + this.current.show(); + }); + } + finally { + disposables.forEach((d) => d.dispose()); + } + }); + } + showInputBox({ title, step, totalSteps, password = false, value, prompt, validate, buttons, shouldResume, }) { + return __awaiter(this, void 0, void 0, function* () { + const disposables = []; + try { + return yield new Promise((resolve, reject) => { + const input = vscode_1.window.createInputBox(); + input.title = title; + input.step = step; + input.totalSteps = totalSteps; + input.value = value || ''; + input.prompt = prompt; + input.password = password; + input.buttons = [...(this.steps.length > 1 ? [vscode_1.QuickInputButtons.Back] : []), ...(buttons || [])]; + let validating = validate(''); + disposables.push(input.onDidTriggerButton((item) => { + if (item === vscode_1.QuickInputButtons.Back) { + reject(InputFlowAction.back); + } + else { + resolve(item); + } + }), input.onDidAccept(() => __awaiter(this, void 0, void 0, function* () { + const value = input.value; + input.enabled = false; + input.busy = true; + if (!(yield validate(value))) { + resolve(value); + } + input.enabled = true; + input.busy = false; + })), input.onDidChangeValue((text) => __awaiter(this, void 0, void 0, function* () { + const current = validate(text); + validating = current; + const validationMessage = yield current; + if (current === validating) { + input.validationMessage = validationMessage; + } + })), input.onDidHide(() => { + ; + (() => __awaiter(this, void 0, void 0, function* () { + reject(shouldResume && (yield shouldResume()) ? InputFlowAction.resume : InputFlowAction.cancel); + }))().catch(reject); + })); + if (this.current) { + this.current.dispose(); + } + this.current = input; + this.current.show(); + }); + } + finally { + disposables.forEach((d) => d.dispose()); + } + }); + } +} +function inputName(input, user, title) { + return __awaiter(this, void 0, void 0, function* () { + user.name = yield input.showInputBox({ + step: 1, + totalSteps: 2, + validate: () => __awaiter(this, void 0, void 0, function* () { return ''; }), + prompt: 'please input username or email', + title, + value: '', + shouldResume: () => Promise.resolve(false), + }); + return (input) => inputPass(input, user, title); + }); +} +function inputPass(input, user, title) { + return __awaiter(this, void 0, void 0, function* () { + user.password = yield input.showInputBox({ + step: 2, + totalSteps: 2, + password: true, + validate: () => __awaiter(this, void 0, void 0, function* () { return ''; }), + prompt: 'please input password', + title, + value: '', + shouldResume: () => Promise.resolve(false), + }); + }); +} +function validUser(user) { + return !!(user.name && user.password); +} +function validCookie(cookie) { + return cookie.includes('LEETCODE_SESSION') && cookie.includes('csrftoken'); +} +function refresh(questionsProvider) { + return __awaiter(this, void 0, void 0, function* () { + cache_1.cache.removeCache(); + const refreshPromise = index_1.refreshQuestions(); + util_1.execWithProgress(refreshPromise, 'refresh questions'); + questionsProvider.refresh(); + }); +} +function selectLogin(questionsProvider) { + return __awaiter(this, void 0, void 0, function* () { + const githubItem = { + label: 'Third-Party:GitHub', + detail: 'Use GitHub account to login', + }; + const cookieItem = { + label: 'Leetcode Cookie', + detail: 'Use Leetcode cookie copied from browser to login', + }; + const accountItem = { + label: 'Leetcode Account', + detail: 'use Leetcode account to login', + }; + const items = [githubItem, cookieItem]; + if (config_1.config.lang === 'cn') { + items.unshift(accountItem); + } + const result = yield vscode_1.window.showQuickPick(items); + if (result === githubItem) { + const user = yield githubInput(); + if (!validUser(user)) { + return; + } + yield util_1.execWithProgress(_1.githubLogin(user), 'wait login'); + vscode_1.window.showInformationMessage('login success'); + } + else if (result === cookieItem) { + const cookie = yield cookieInput(); + if (!cookie) { + return; + } + if (!validCookie(cookie)) { + vscode_1.window.showErrorMessage('cookie is invalid'); + return; + } + yield _1.cookieLogin(cookie); + config_1.config.log.appendLine('save cookie success'); + // window.showInformationMessage('save cookie success') + yield refresh(questionsProvider); + return; + } + else if (result === accountItem) { + const user = yield accountInput(); + if (!validUser(user)) { + return; + } + yield _1.accountLogin(user); + config_1.config.log.appendLine('login success'); + // window.showInformationMessage('login success') + yield refresh(questionsProvider); + } + }); +} +exports.selectLogin = selectLogin; +function githubInput() { + return __awaiter(this, void 0, void 0, function* () { + const user = {}; + yield MultiStepInput.run((input) => inputName(input, user, 'login github')); + return user; + }); +} +exports.githubInput = githubInput; +function cookieInput() { + return __awaiter(this, void 0, void 0, function* () { + const cookie = yield vscode_1.window.showInputBox({ + prompt: 'copy the cookie from browser', + }); + return cookie; + }); +} +exports.cookieInput = cookieInput; +function accountInput() { + return __awaiter(this, void 0, void 0, function* () { + const user = {}; + yield MultiStepInput.run((input) => inputName(input, user, 'account login')); + return user; + }); +} +exports.accountInput = accountInput; +// copy from https://github.com/microsoft/vscode-extension-samples/blob/master/quickinput-sample/src/multiStepInput.ts +//# sourceMappingURL=input.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/memo/index.js b/tools/supperchong.algorithm/out/memo/index.js new file mode 100644 index 0000000..39f7da1 --- /dev/null +++ b/tools/supperchong.algorithm/out/memo/index.js @@ -0,0 +1,81 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addQuestion = exports.addFolderFile = exports.deleteFolder = exports.addFolder = void 0; +const util_1 = require("../common/util"); +const config_1 = require("../config"); +const path = require("path"); +function addFolder(name) { + if (config_1.config.env.memo.find((v) => v.name === name)) { + throw new Error('folder already exists'); + } + config_1.config.env.memo.push({ + name, + children: [], + }); + config_1.updateEnv('memo', config_1.config.env.memo); +} +exports.addFolder = addFolder; +function deleteFolder(name) { + const memo = config_1.config.env.memo; + const index = memo.findIndex((item) => item.name === name); + memo.splice(index, 1); + config_1.updateEnv('memo', memo); +} +exports.deleteFolder = deleteFolder; +function addFolderFile(folderName, fileName) { + return __awaiter(this, void 0, void 0, function* () { + const memo = config_1.config.env.memo; + const folder = memo.find((item) => item.name === folderName); + if (folder) { + folder.children.push({ + type: 'other', + name: fileName, + param: fileName, + }); + const memoDir = path.join(config_1.config.cacheBaseDir, 'memo'); + const filePath = path.join(memoDir, fileName); + yield util_1.existDir(memoDir); + yield util_1.writeFileAsync(filePath, Buffer.alloc(0)); + } + }); +} +exports.addFolderFile = addFolderFile; +function addQuestion(folderName, name, param) { + const memo = config_1.config.env.memo; + const folder = memo.find((item) => item.name === folderName); + if (folder) { + if (folder.children.find((v) => v.name === name)) { + throw new Error('file already exists'); + } + folder.children.push({ + type: 'question', + name, + param, + }); + config_1.updateEnv('memo', memo); + } +} +exports.addQuestion = addQuestion; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function deleteFile(folderName, fileName) { + return __awaiter(this, void 0, void 0, function* () { + const memo = config_1.config.env.memo; + const folder = memo.find((item) => item.name === folderName); + if (folder) { + const index = folder.children.findIndex((c) => c.name === fileName); + if (index !== -1) { + folder.children.splice(index, 1); + } + } + }); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/model/command.js b/tools/supperchong.algorithm/out/model/command.js new file mode 100644 index 0000000..d2ea9e9 --- /dev/null +++ b/tools/supperchong.algorithm/out/model/command.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=command.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/model/common.js b/tools/supperchong.algorithm/out/model/common.js new file mode 100644 index 0000000..b735a49 --- /dev/null +++ b/tools/supperchong.algorithm/out/model/common.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkParams = exports.HistoryType = exports.FlagType = exports.PendingStatus = exports.AskForImportState = exports.ErrorStatus = exports.Lang = void 0; +var Lang; +(function (Lang) { + Lang["en"] = "en"; + Lang["cn"] = "cn"; +})(Lang = exports.Lang || (exports.Lang = {})); +var ErrorStatus; +(function (ErrorStatus) { + ErrorStatus[ErrorStatus["Unlogin"] = 403] = "Unlogin"; + ErrorStatus[ErrorStatus["InvalidCookie"] = 499] = "InvalidCookie"; +})(ErrorStatus = exports.ErrorStatus || (exports.ErrorStatus = {})); +var AskForImportState; +(function (AskForImportState) { + AskForImportState["Yes"] = "Yes"; + AskForImportState["No"] = "No"; + AskForImportState["Later"] = "Later"; +})(AskForImportState = exports.AskForImportState || (exports.AskForImportState = {})); +var PendingStatus; +(function (PendingStatus) { + PendingStatus["NotPending"] = "Not Pending"; + PendingStatus["Pending"] = "Pending"; +})(PendingStatus = exports.PendingStatus || (exports.PendingStatus = {})); +var FlagType; +(function (FlagType) { + FlagType["BLUE"] = "BLUE"; + FlagType["ORANGE"] = "ORANGE"; + FlagType["GREEN"] = "GREEN"; + FlagType["PURPLE"] = "PURPLE"; + FlagType["RED"] = "RED"; +})(FlagType = exports.FlagType || (exports.FlagType = {})); +var HistoryType; +(function (HistoryType) { + HistoryType["Answer"] = "answer"; + HistoryType["LocalSubmit"] = "localSubmit"; + HistoryType["RemoteSubmit"] = "remoteSubmit"; +})(HistoryType = exports.HistoryType || (exports.HistoryType = {})); +function checkParams(obj, attrs) { + const verify = attrs.every((attr) => !!obj[attr]); + if (!verify) { + const attr = attrs.find((attr) => !obj[attr]); + throw new Error(`options error, ${attr} is ${obj[attr]}`); + } +} +exports.checkParams = checkParams; +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/model/memo.js b/tools/supperchong.algorithm/out/model/memo.js new file mode 100644 index 0000000..eb6b45f --- /dev/null +++ b/tools/supperchong.algorithm/out/model/memo.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=memo.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/model/question.cn.js b/tools/supperchong.algorithm/out/model/question.cn.js new file mode 100644 index 0000000..b41de89 --- /dev/null +++ b/tools/supperchong.algorithm/out/model/question.cn.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=question.cn.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/model/question.js b/tools/supperchong.algorithm/out/model/question.js new file mode 100644 index 0000000..242223b --- /dev/null +++ b/tools/supperchong.algorithm/out/model/question.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=question.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/process.js b/tools/supperchong.algorithm/out/process.js new file mode 100644 index 0000000..f10619d --- /dev/null +++ b/tools/supperchong.algorithm/out/process.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.childProcessProxy = exports.clearProcessArr = exports.processArr = void 0; +exports.processArr = []; +function clearProcessArr() { + exports.processArr.forEach(p => { + p.kill(); + }); +} +exports.clearProcessArr = clearProcessArr; +class ChildProcessProxy { + constructor() { + this.processIdSet = new Set(); + } + clear() { + this.processIdSet.forEach(pid => { + process.kill(pid); + }); + } + add(p) { + const pid = p.pid; + this.processIdSet.add(pid); + p.once('exit', () => { + this.processIdSet.delete(pid); + }); + } + remove(p) { + if (!p) { + return; + } + if (this.processIdSet.has(p.pid)) { + p.kill(); + } + } +} +exports.childProcessProxy = new ChildProcessProxy(); +//# sourceMappingURL=process.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/codelensProvider.js b/tools/supperchong.algorithm/out/provider/codelensProvider.js new file mode 100644 index 0000000..abc7140 --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/codelensProvider.js @@ -0,0 +1,125 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CodelensProvider = void 0; +const vscode = require("vscode"); +const util_1 = require("../common/util"); +const langConfig_1 = require("../common/langConfig"); +const common_1 = require("../lang/common"); +class CodelensProvider { + constructor() { + this.codeLenses = []; + this._onDidChangeCodeLenses = new vscode.EventEmitter(); + this.onDidChangeCodeLenses = this._onDidChangeCodeLenses.event; + this.regex = /(@test)/g; + vscode.workspace.onDidChangeConfiguration((_) => { + this._onDidChangeCodeLenses.fire(); + }); + } + getBuildCodeLenses(options) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)); + codeLens.command = { + title: 'build', + tooltip: 'build', + command: 'algorithm.buildCode', + arguments: [options], + }; + return codeLens; + } + getSubmitCodeLenses(options) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)); + codeLens.command = { + title: 'submit', + tooltip: 'submit', + command: 'algorithm.submit', + arguments: [options], + }; + return codeLens; + } + getDescriptionCodeLenses(options) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)); + codeLens.command = { + title: 'description', + tooltip: 'description', + command: 'algorithm.getDescription', + arguments: [options], + }; + return codeLens; + } + getHistoryCodeLenses(options) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)); + codeLens.command = { + title: 'history', + tooltip: 'history', + command: 'algorithm.viewSubmitHistory', + arguments: [options], + }; + return codeLens; + } + getTestCodeLenses(options) { + const { testCaseParam: { line }, } = options; + const codeLens = new vscode.CodeLens(new vscode.Range(line, 0, line, 7)); + codeLens.command = { + title: 'test', + tooltip: 'test', + command: 'algorithm.testCode', + arguments: [options], + }; + return codeLens; + } + getDebugCodeLenses(testCaseParam, filePath) { + const { line } = testCaseParam; + const codeLens = new vscode.CodeLens(new vscode.Range(line, 0, line, 7)); + codeLens.command = { + title: 'debug', + tooltip: 'debug', + command: 'algorithm.debugCode', + arguments: [filePath], + }; + return codeLens; + } + provideCodeLenses(document) { + this.codeLenses = []; + const text = document.getText(); + const filePath = document.fileName; + const isSupport = langConfig_1.isSupportFile(filePath); + if (!isSupport) { + return []; + } + const enableExt = util_1.detectEnableExt(text, filePath); + if (enableExt) { + const codeLang = langConfig_1.getFileLang(filePath); + const langSlug = langConfig_1.getFileLangSlug(filePath); + const codeLensesOptions = { + text, + filePath, + langSlug, + }; + const submitCodeLenses = this.getSubmitCodeLenses(Object.assign({}, codeLensesOptions)); + const buildCodeLenses = this.getBuildCodeLenses(Object.assign({}, codeLensesOptions)); + const desCodeLenses = this.getDescriptionCodeLenses(Object.assign({}, codeLensesOptions)); + const historyCodeLenses = this.getHistoryCodeLenses(Object.assign({}, codeLensesOptions)); + this.codeLenses.push(submitCodeLenses); + this.codeLenses.push(buildCodeLenses); + this.codeLenses.push(desCodeLenses); + this.codeLenses.push(historyCodeLenses); + if (langConfig_1.isAlgorithm(codeLang)) { + const lang = new common_1.Service(filePath, text); + const testCaseList = lang.getTestCaseList(text); + testCaseList.forEach((testCaseParam) => { + const testCodeOptions = { + filePath: document.uri.fsPath, + testCaseParam, + }; + const testCodeLenses = this.getTestCodeLenses(testCodeOptions); + const debugCodeLenses = this.getDebugCodeLenses(testCaseParam, document.uri.fsPath); + this.codeLenses.push(testCodeLenses); + this.codeLenses.push(debugCodeLenses); + }); + } + return this.codeLenses; + } + return []; + } +} +exports.CodelensProvider = CodelensProvider; +//# sourceMappingURL=codelensProvider.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/completionProvider.js b/tools/supperchong.algorithm/out/provider/completionProvider.js new file mode 100644 index 0000000..3170918 --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/completionProvider.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerCompletionItemProvider = void 0; +const config_1 = require("../config"); +const vscode = require("vscode"); +const defaultCompletionItems = [ + { + languages: ['javascript', 'typescript'], + prefix: 'algorithm', + body: "// @algorithm\r\nimport * as a from '" + config_1.config.algmModuleDir + "'\r\n\r\n", + }, +]; +function registerCompletionItemProvider(context) { + defaultCompletionItems.forEach(({ languages, prefix, body }) => { + context.subscriptions.push(vscode.languages.registerCompletionItemProvider(languages, { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + provideCompletionItems(document, position) { + const snippetCompletion = new vscode.CompletionItem(prefix); + snippetCompletion.insertText = new vscode.SnippetString(body); + return [snippetCompletion]; + }, + }, '.' // triggered whenever a '.' is being typed + )); + }); +} +exports.registerCompletionItemProvider = registerCompletionItemProvider; +//# sourceMappingURL=completionProvider.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/memoProvider.js b/tools/supperchong.algorithm/out/provider/memoProvider.js new file mode 100644 index 0000000..6c2dad8 --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/memoProvider.js @@ -0,0 +1,185 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MemoProvider = exports.MemoTree = void 0; +const vscode = require("vscode"); +const config_1 = require("../config"); +const util_1 = require("../util"); +const MemoFilePreviewCommand = 'algorithm.memoFilePreview'; +const MemoFileContext = 'memoFile'; +var MemoLevel; +(function (MemoLevel) { + MemoLevel[MemoLevel["Folder"] = 0] = "Folder"; + MemoLevel[MemoLevel["File"] = 1] = "File"; + MemoLevel[MemoLevel["Invalid"] = 2] = "Invalid"; +})(MemoLevel || (MemoLevel = {})); +var RemoveMemoMsg; +(function (RemoveMemoMsg) { + RemoveMemoMsg["Folder"] = "Are you sure you want to delete the folder?"; + RemoveMemoMsg["File"] = "Are you sure you want to delete the file?"; +})(RemoveMemoMsg || (RemoveMemoMsg = {})); +class MemoTree extends vscode.TreeItem { + constructor(label, id, paths, collapsibleState = vscode.TreeItemCollapsibleState.Collapsed, command) { + super(label, vscode.TreeItemCollapsibleState.Collapsed); + this.label = label; + this.id = id; + this.paths = paths; + this.collapsibleState = collapsibleState; + this.command = command; + this.contextValue = 'memo'; + } +} +exports.MemoTree = MemoTree; +class MemoProvider { + constructor() { + this._onDidChangeTreeData = new vscode.EventEmitter(); + this.onDidChangeTreeData = this._onDidChangeTreeData.event; + } + refresh() { + this._onDidChangeTreeData.fire(undefined); + } + getTreeItem(element) { + return element; + } + getChildren(element) { + if (element) { + const folderName = element.label; + const files = this.getFolderFiles(folderName); + return Promise.resolve(files.map((f) => { + const tree = new MemoTree(f.label, f.id, f.paths, vscode.TreeItemCollapsibleState.None, { + title: 'memoFilePreview', + command: MemoFilePreviewCommand, + arguments: [f.param], + }); + tree.contextValue = MemoFileContext; + return tree; + })); + } + else { + const folders = this.getFolders(); + return Promise.resolve(folders.map((f) => { + const tree = new MemoTree(f.label, f.id, f.paths); + tree.contextValue = MemoFileContext; + return tree; + })); + } + } + getFolders() { + return config_1.config.env.memo.map((v) => { + return { + label: v.name, + id: 'folder' + v.name, + paths: [v.name], + }; + }); + } + getFolderFiles(name) { + const folder = config_1.config.env.memo.find((v) => v.name === name); + if (folder) { + const files = folder.children; + util_1.sortFiles(files); + return files.map((v) => { + return { + label: v.name, + id: name + v.name, + paths: [name, v.name], + param: v, + }; + }); + } + else { + return []; + } + } + static getElementLevel(element) { + const paths = element.paths; + if (paths.length === 1) { + return MemoLevel.Folder; + } + else if (paths.length === 2) { + return MemoLevel.File; + } + return MemoLevel.Invalid; + } + static remove(element) { + return __awaiter(this, void 0, void 0, function* () { + const isRemove = yield MemoProvider.checkRemove(element); + if (!isRemove) { + return false; + } + const removeConfigs = [ + { + level: MemoLevel.Folder, + fn: MemoProvider.removeFolder, + }, + { + level: MemoLevel.File, + fn: MemoProvider.removeFile, + }, + ]; + const level = MemoProvider.getElementLevel(element); + const config = removeConfigs.find((c) => c.level === level); + if (config) { + config.fn(element.paths); + return true; + } + return false; + }); + } + static checkRemove(element) { + return __awaiter(this, void 0, void 0, function* () { + const msgConfigs = [ + { + level: MemoLevel.Folder, + msg: RemoveMemoMsg.Folder, + }, + { + level: MemoLevel.File, + msg: RemoveMemoMsg.File, + }, + ]; + const Remove = 'remove'; + const level = MemoProvider.getElementLevel(element); + const config = msgConfigs.find((c) => c.level === level); + if (config) { + const msg = config.msg; + const r = yield vscode.window.showWarningMessage(msg, { modal: true }, Remove); + return r === Remove; + } + return false; + }); + } + static removeFolder(paths) { + const memo = config_1.config.env.memo; + const folderName = paths[0]; + const index = memo.findIndex((m) => m.name === folderName); + if (index !== -1) { + memo.splice(index, 1); + return config_1.updateEnv('memo', memo); + } + config_1.config.log.appendLine('folder not exist'); + } + static removeFile(paths) { + const memo = config_1.config.env.memo; + const [folderName, fileName] = paths; + const folder = memo.find((m) => m.name === folderName); + if (folder) { + const index = folder.children.findIndex((f) => f.name === fileName); + if (index !== -1) { + folder.children.splice(index, 1); + return config_1.updateEnv('memo', memo); + } + } + config_1.config.log.appendLine('file not exist'); + } +} +exports.MemoProvider = MemoProvider; +//# sourceMappingURL=memoProvider.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/questionsProvider.js b/tools/supperchong.algorithm/out/provider/questionsProvider.js new file mode 100644 index 0000000..1a4633b --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/questionsProvider.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.QuestionsProvider = exports.QuestionTree = void 0; +const vscode = require("vscode"); +const questionPreview_1 = require("../webview/questionPreview"); +const config_1 = require("../config"); +const resolver_1 = require("./resolver"); +const resolver_cn_1 = require("./resolver.cn"); +const path = require("path"); +class QuestionTree extends vscode.TreeItem { + constructor(label, id, collapsibleState, type, key, param, command) { + super(label, collapsibleState); + this.label = label; + this.id = id; + this.collapsibleState = collapsibleState; + this.type = type; + this.key = key; + this.param = param; + this.command = command; + } +} +exports.QuestionTree = QuestionTree; +class QuestionsProvider { + constructor(workspaceRoot, _extensionPath) { + this.workspaceRoot = workspaceRoot; + this._extensionPath = _extensionPath; + this._onDidChangeTreeData = new vscode.EventEmitter(); + this.onDidChangeTreeData = this._onDidChangeTreeData.event; + } + refresh() { + this._onDidChangeTreeData.fire(undefined); + } + getTreeItem(element) { + return element; + } + getChildren(element) { + let resolver; + if (config_1.config.lang === 'en') { + resolver = resolver_1.resolverEn; + } + else { + resolver = resolver_cn_1.resolverCn; + } + if (element) { + const type = element.type; + const key = element.key; + const param = element.param || {}; + let fn; + if (key) { + fn = resolver[type][key]; + } + else { + fn = resolver[type]; + } + return Promise.resolve(fn(param)) + .then((arr) => { + if (!arr.length) { + return []; + } + const isLastChild = arr[0].isLast; + if (isLastChild) { + return arr.map((v) => { + const dep = new QuestionTree(v.label, v.id, vscode.TreeItemCollapsibleState.None, v.type, v.key, v.param, { + title: 'QuestionPreview', + command: questionPreview_1.QuestionPreview, + arguments: [v.param], + }); + if (v.paidOnly) { + dep.iconPath = new vscode.ThemeIcon('lock'); + } + else { + // dep.iconPath = v.isAC ? new vscode.ThemeIcon('check') : '' + dep.iconPath = v.isAC ? path.join(__dirname, '..', '..', 'media', 'ac.svg') : ''; + } + dep.contextValue = 'memo'; + return dep; + }); + } + else { + return arr.map((v) => new QuestionTree(v.label, v.id, vscode.TreeItemCollapsibleState.Collapsed, v.type, v.key, v.param || {})); + } + }) + .catch((err) => { + console.log(err); + return []; + }); + } + else { + return Promise.resolve(resolver.Query()).then((arr) => arr.map((v) => new QuestionTree(v.label, v.id, vscode.TreeItemCollapsibleState.Collapsed, v.type, v.key, v.param || {}))); + } + } +} +exports.QuestionsProvider = QuestionsProvider; +//# sourceMappingURL=questionsProvider.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/resolver.cn.js b/tools/supperchong.algorithm/out/provider/resolver.cn.js new file mode 100644 index 0000000..fbb7f01 --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/resolver.cn.js @@ -0,0 +1,180 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.resolverCn = void 0; +const api_cn_1 = require("../api/api.cn"); +const util_1 = require("../common/util"); +exports.resolverCn = { + Query() { + //'Company', 'Favorite', + return ['All', 'Difficulty', 'Category', 'Tag', 'Contest', 'TodayRecord'].map((v) => ({ + key: v.toLowerCase(), + type: 'Catalogue', + label: v, + id: v, + })); + }, + Catalogue: { + all() { + return __awaiter(this, void 0, void 0, function* () { + const questions = yield api_cn_1.getAllQuestions(); + return util_1.normalizeQuestions(questions, 'all'); + }); + }, + difficulty() { + return ['Easy', 'Medium', 'Hard'].map((v) => ({ + key: v.toLowerCase(), + type: 'Difficulty', + label: v, + id: v, + })); + }, + category() { + const categories = api_cn_1.getCategories(); + return categories.map((v) => ({ + label: v.label, + type: 'Category', + key: v.category_slug, + id: 'Category' + v.category_slug, + })); + }, + tag() { + return __awaiter(this, void 0, void 0, function* () { + const tags = yield api_cn_1.getTags(); + return tags.map((tag) => ({ + key: 'tagkey', + type: 'Tag', + label: tag, + id: tag, + param: { + tag, + }, + })); + }); + }, + // company() { + // }, + // favorite() { + // }, + contest() { + return __awaiter(this, void 0, void 0, function* () { + const contests = yield api_cn_1.api.fetchContests(); + return contests.map((contest) => ({ + key: 'contestKey', + type: 'Contest', + label: contest.title, + id: contest.title, + param: { + titleSlug: contest.titleSlug, + }, + })); + }); + }, + todayrecord() { + return __awaiter(this, void 0, void 0, function* () { + const record = yield api_cn_1.api.fetchTodayRecord(); + return record.map((v) => ({ + type: 'Question', + label: v.question.questionFrontendId + '.' + v.question.translatedTitle, + isAC: v.userStatus === 'FINISH', + isLast: true, + id: 'todayrecord' + v.question.questionFrontendId, + param: { + titleSlug: v.question.titleSlug, + }, + })); + }); + }, + }, + Category: { + algorithm() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'algorithm'; + const questions = yield api_cn_1.getQuestionsByCategory(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + lcci() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'lcci'; + const questions = yield api_cn_1.getQuestionsByCategory(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + lcof() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'lcof'; + const questions = yield api_cn_1.getQuestionsByCategory(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + }, + Tag: { + tagkey({ tag }) { + return __awaiter(this, void 0, void 0, function* () { + if (!tag) { + return []; + } + const questions = yield api_cn_1.getQuestionsByTag(tag); + return util_1.normalizeQuestions(questions, 'tag' + tag); + }); + }, + }, + Difficulty: { + easy() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'easy'; + const questions = yield api_cn_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + medium() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'medium'; + const questions = yield api_cn_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + hard() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'hard'; + const questions = yield api_cn_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + }, + // Company() { + // }, + // Favorite() { + // }, + Contest: { + contestKey({ titleSlug }) { + return __awaiter(this, void 0, void 0, function* () { + if (!titleSlug) { + return []; + } + const data = yield api_cn_1.api.fetchContest(titleSlug); + const questions = data.questions; + return questions.map((question) => ({ + type: 'QuestionContest', + label: question.title, + id: 'QuestionContest' + question.id, + isLast: true, + param: { + titleSlug: question.title_slug, + weekname: titleSlug, + }, + })); + }); + }, + }, +}; +//# sourceMappingURL=resolver.cn.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/resolver.js b/tools/supperchong.algorithm/out/provider/resolver.js new file mode 100644 index 0000000..f9fbe31 --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/resolver.js @@ -0,0 +1,179 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.resolverEn = void 0; +const api_1 = require("../api/api"); +const util_1 = require("../common/util"); +exports.resolverEn = { + Query() { + //'Company', 'Favorite', + return ['All', 'Difficulty', 'Tag', 'Contest', 'DailyChallenge'].map((v) => ({ + type: 'Catalogue', + key: v.toLowerCase(), + label: v, + id: v, + })); + }, + Catalogue: { + all() { + return __awaiter(this, void 0, void 0, function* () { + const questions = yield api_1.getAllQuestions(); + return util_1.normalizeQuestions(questions, 'all'); + }); + }, + difficulty() { + return ['Easy', 'Medium', 'Hard'].map((v) => ({ + type: 'Difficulty', + key: v.toLowerCase(), + label: v, + id: v, + })); + }, + tag() { + return __awaiter(this, void 0, void 0, function* () { + const tags = yield api_1.getTags(); + return tags.map((tag) => ({ + type: 'Tag', + key: 'tagkey', + label: tag, + id: tag, + param: { + tag, + }, + })); + }); + }, + // company() { + // }, + // favorite() { + // }, + contest() { + return __awaiter(this, void 0, void 0, function* () { + const contests = yield api_1.api.fetchContests(); + return contests.map((contest) => ({ + type: 'Contest', + key: 'contestKey', + label: contest.title, + id: contest.title, + param: { + titleSlug: contest.titleSlug, + }, + })); + }); + }, + dailychallenge() { + return __awaiter(this, void 0, void 0, function* () { + const { chapters } = yield api_1.api.fetchChapters(); + return chapters.map((chapter) => ({ + type: 'Chapter', + label: chapter.title, + id: chapter.title, + param: { + // titleSlug: chapter.slug, + chapterId: chapter.id, + }, + })); + }); + }, + }, + Chapter({ chapterId }) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + if (!chapterId) { + return []; + } + const chapterDetail = yield api_1.api.fetchChapter(chapterId); + const chaptersProgressRes = yield api_1.api.fetchChapterProgress(); + const progress = (_a = chaptersProgressRes === null || chaptersProgressRes === void 0 ? void 0 : chaptersProgressRes.getOrCreateExploreSession) === null || _a === void 0 ? void 0 : _a.progress; + let progressMap = null; + try { + progressMap = JSON.parse(progress); + } + catch (err) { + progressMap = null; + } + const items = chapterDetail.chapter.items; + return items.map((item) => { + return { + type: 'DailyQuestion', + label: item.title, + id: 'DailyQuestion' + item.title, + isLast: true, + isAC: progressMap ? progressMap[chapterId][item.id].is_complete : false, + paidOnly: item.paidOnly, + param: { + itemId: item.id, + }, + }; + }); + }); + }, + Tag: { + tagkey({ tag }) { + return __awaiter(this, void 0, void 0, function* () { + if (!tag) { + return []; + } + const questions = yield api_1.getQuestionsByTag(tag); + return util_1.normalizeQuestions(questions, 'tag' + tag); + }); + }, + }, + Difficulty: { + easy() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'easy'; + const questions = yield api_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + medium() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'medium'; + const questions = yield api_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + hard() { + return __awaiter(this, void 0, void 0, function* () { + const key = 'hard'; + const questions = yield api_1.getQuestionsByDifficult(key); + return util_1.normalizeQuestions(questions, key); + }); + }, + }, + // Company() { + // }, + // Favorite() { + // }, + Contest: { + contestKey({ titleSlug }) { + return __awaiter(this, void 0, void 0, function* () { + if (!titleSlug) { + return []; + } + const data = yield api_1.api.fetchContest(titleSlug); + const questions = data.questions; + return questions.map((question) => ({ + type: 'QuestionContest', + label: question.id + ' ' + question.title, + id: 'QuestionContest' + question.id, + isLast: true, + param: { + titleSlug: question.title_slug, + fatherTitleSlug: titleSlug, + }, + })); + }); + }, + }, +}; +//# sourceMappingURL=resolver.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/provider/snippetProvider.js b/tools/supperchong.algorithm/out/provider/snippetProvider.js new file mode 100644 index 0000000..21609bd --- /dev/null +++ b/tools/supperchong.algorithm/out/provider/snippetProvider.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.registerForSnippetProviders = void 0; +const vscode = require("vscode"); +const util_1 = require("../common/util"); +const pretty_tag_1 = require("pretty-tag"); +function registerForSnippetProviders(context) { + const forVariables = ['i', 'j', 'k']; + const fns = forVariables.map((forVariable) => { + return function provideCompletionItems(document, position) { + const key = `for${forVariable}.`; + let text = document.lineAt(position).text; + if (!text.endsWith(key)) { + return; + } + let whitePrefix = ''; + for (let i = 0; i < text.length; i++) { + if (!/\s/.test(text[i])) { + whitePrefix = text.slice(0, i); + break; + } + } + text = text.trimLeft(); + const snippetCompletion = new vscode.CompletionItem(text); + const range = document.lineAt(position).range; + snippetCompletion.range = range; + const prefix = text.slice(0, text.length - 5); + let snippetString = pretty_tag_1.tag ` + for (let ${forVariable} = 0; ${forVariable} < ${prefix}.length; ${forVariable}++) { + let element = ${prefix}[${forVariable}] + $0 + }`; + snippetString = util_1.setLinePrefix(snippetString, whitePrefix); + snippetCompletion.insertText = new vscode.SnippetString(snippetString); + return [snippetCompletion]; + }; + }); + fns.forEach((fn) => { + context.subscriptions.push(vscode.languages.registerCompletionItemProvider({ language: 'javascript', scheme: 'file' }, { provideCompletionItems: fn }, '.')); + }); +} +exports.registerForSnippetProviders = registerForSnippetProviders; +//# sourceMappingURL=snippetProvider.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/submitHistory/storage.js b/tools/supperchong.algorithm/out/submitHistory/storage.js new file mode 100644 index 0000000..6bb6257 --- /dev/null +++ b/tools/supperchong.algorithm/out/submitHistory/storage.js @@ -0,0 +1,90 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.submitStorage = void 0; +const path = require("path"); +const config_1 = require("../config"); +const fs_extra_1 = require("fs-extra"); +class Storage { + constructor() { + this.arr = []; + this.isWork = false; + } + getFilePath(question_id) { + const cacheDir = path.join(config_1.config.cacheDir, 'submit'); + return path.join(cacheDir, question_id + '.json'); + } + read(question_id) { + return __awaiter(this, void 0, void 0, function* () { + const filePath = this.getFilePath(question_id); + return fs_extra_1.readJson(filePath); + }); + } + save(options) { + return __awaiter(this, void 0, void 0, function* () { + if (this.isWork) { + this.arr.push(options); + } + else { + this.isWork = true; + yield this.innerSave(options); + } + }); + } + innerSave(options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const id = options.result.question_id; + const r = options.result; + const filePath = this.getFilePath(id); + const obj = { + code: options.text, + submission: { + id: r.submission_id, + isPending: 'Not Pending', + submissionComment: null, + lang: r.lang, + memory: r.memory, + runtime: r.status_runtime, + statusDisplay: r.status_msg, + timestamp: r.task_finish_time, + url: '/submissions/detail/' + r.submission_id + '/' + }, + result: options.result + }; + let arr = []; + const exist = yield fs_extra_1.pathExists(filePath); + if (exist) { + arr = yield fs_extra_1.readJson(filePath); + arr.push(obj); + } + else { + arr.push(obj); + } + yield fs_extra_1.ensureFile(filePath); + yield fs_extra_1.writeJson(filePath, arr); + } + catch (err) { + console.log(err); + } + if (this.arr.length) { + const opt = this.arr.shift(); + yield this.innerSave(opt); + } + else { + this.isWork = false; + } + }); + } +} +Storage.submitStorage = new Storage(); +exports.submitStorage = Storage.submitStorage; +//# sourceMappingURL=storage.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/submitHistory/util.js b/tools/supperchong.algorithm/out/submitHistory/util.js new file mode 100644 index 0000000..ec1dbac --- /dev/null +++ b/tools/supperchong.algorithm/out/submitHistory/util.js @@ -0,0 +1,20 @@ +"use strict"; +const headerMap = { + en: { + statusDisplay: '', + runtime: '', + memory: '', + lang: '', + timestamp: '', + comment: '' + }, + cn: { + statusDisplay: '', + runtime: '', + memory: '', + lang: '', + timestamp: '', + comment: '' + } +}; +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/util.js b/tools/supperchong.algorithm/out/util.js new file mode 100644 index 0000000..9635948 --- /dev/null +++ b/tools/supperchong.algorithm/out/util.js @@ -0,0 +1,249 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.reRequire = exports.sortQuestions = exports.sortFiles = exports.checkBeforeDebug = exports.getDebugConfig = exports.preprocessCode = exports.askForImport = exports.shouldAskForImport = exports.appendComment = exports.execWithProgress2 = exports.execWithProgress = exports.highlightCode = void 0; +const vscode = require("vscode"); +const vscode_1 = require("vscode"); +const core_1 = require("@babel/core"); +const babelPlugin_1 = require("./babelPlugin"); +const langConfig_1 = require("./common/langConfig"); +const parseContent_1 = require("./common/parseContent"); +const config_1 = require("./config"); +const pretty_tag_1 = require("pretty-tag"); +const common_1 = require("./model/common"); +const common_2 = require("./lang/common"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const hljs = require('highlight.js'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const md = require('markdown-it')({ + highlight: function (str, lang) { + if (lang && hljs.getLanguage(lang)) { + try { + return ('
' +
+                    hljs.highlight(str, {
+                        language: lang,
+                        ignoreIllegals: true,
+                    }).value +
+                    '
'); + } + catch (err) { + config_1.log.appendLine('highlight code error'); + } + } + return '
' + md.utils.escapeHtml(str) + '
'; + }, +}); +const highlightCode = (code, lang) => md.render(`\`\`\`${langConfig_1.transformToHightlightLang(lang)}\n${code}\n\`\`\``); +exports.highlightCode = highlightCode; +function execWithProgress(promise, message) { + return __awaiter(this, void 0, void 0, function* () { + return vscode_1.window.withProgress({ location: vscode.ProgressLocation.Notification }, (p) => { + p.report({ message }); + return promise; + }); + }); +} +exports.execWithProgress = execWithProgress; +function execWithProgress2(promise, message) { + return __awaiter(this, void 0, void 0, function* () { + return vscode_1.window.withProgress({ location: vscode.ProgressLocation.Window }, (p) => { + p.report({ message }); + return promise; + }); + }); +} +exports.execWithProgress2 = execWithProgress2; +function appendComment(code, comment, funcName) { + return __awaiter(this, void 0, void 0, function* () { + const fileResult = yield core_1.transformAsync(code, { + // comments: true, + // compact: false, + plugins: [babelPlugin_1.generateAddTestCommentPlugin(funcName, comment)], + }); + return fileResult === null || fileResult === void 0 ? void 0 : fileResult.code; + }); +} +exports.appendComment = appendComment; +const extraTypeValues = [langConfig_1.ExtraType.ListNode, langConfig_1.ExtraType.TreeNode]; +function shouldAskForImport() { + return !config_1.config.hasAskForImport && config_1.config.env.askForImportState === common_1.AskForImportState.Later && !config_1.config.autoImportAlgm; +} +exports.shouldAskForImport = shouldAskForImport; +function askForImport() { + return __awaiter(this, void 0, void 0, function* () { + config_1.config.hasAskForImport = true; + const r = yield vscode_1.window.showInformationMessage('Would you like to import the algm module?', common_1.AskForImportState.Yes, common_1.AskForImportState.No, common_1.AskForImportState.Later); + switch (r) { + case common_1.AskForImportState.Yes: { + config_1.updateConfig('autoImportAlgm', true, true); + config_1.updateEnv('askForImportState', common_1.AskForImportState.Yes); + break; + } + case common_1.AskForImportState.No: { + config_1.updateConfig('autoImportAlgm', false, true); + config_1.updateEnv('askForImportState', common_1.AskForImportState.No); + break; + } + } + }); +} +exports.askForImport = askForImport; +function getExtraTypeSet(metaData) { + const arr = new Set(); + const params = metaData.params; + const r = metaData.return; + params.forEach((p) => { + extraTypeValues.forEach((e) => { + if (p.type.includes(e)) { + arr.add(e); + } + }); + }); + extraTypeValues.forEach((e) => { + if (r.type.includes(e)) { + arr.add(e); + } + }); + return arr; +} +function getImportStr(metaData) { + const arr = getExtraTypeSet(metaData); + if (arr.size) { + return `import { ${[...arr].join(', ')} } from 'algm'`; + } + return ''; +} +function isLanguageMetaData(metaData) { + return 'name' in metaData; +} +function preprocessCode({ questionId, metaData, content, titleSlug, questionSourceContent }, weekname = '', codeSnippet, name) { + const testCases = parseContent_1.ParseContent.getTestCases(questionSourceContent || content); + const langSlug = codeSnippet.langSlug; + const langConfig = langConfig_1.langMap[langSlug]; + const weektag = weekname ? `weekname=${weekname}` : ''; + const metaDataParse = JSON.parse(metaData); + const LcComment = pretty_tag_1.tag ` + ${langConfig.comment} @algorithm @lc id=${questionId} lang=${langSlug} ${weektag} + ${langConfig.comment} @title ${titleSlug} + `; + if (!isLanguageMetaData(metaDataParse)) { + return LcComment; + } + const supportImport = ['JavaScript', 'TypeScript'].includes(langConfig.lang); + const shouldImport = supportImport && config_1.config.autoImportAlgm; + const importStr = shouldImport ? `import * as a from 'algm'\n` + getImportStr(metaDataParse) : ''; + const autoImportStr = config_1.config.autoImportStr || ''; + const preImport = common_2.Service.getPreImport(langConfig.lang, name, getExtraTypeSet(metaDataParse)); + const flag = pretty_tag_1.tag ` + ${LcComment} + ${importStr} + ${autoImportStr} + ${preImport} + `; + let codeTestSnippet = ''; + try { + codeTestSnippet = testCases + .map((testCase) => { + const pa = metaDataParse.params + .map((param, i) => { + const input = testCase.input.find(({ key }) => key === param.name); + if (input) { + return input.value; + } + else { + return testCase.input[i].value; + } + }) + .join(','); + return `${langConfig.comment} @test(${pa})=${testCase.output}\n`; + }) + .join(''); + } + catch (err) { + console.log(err); + } + const code = codeSnippet.code; + const newCode = flag + '\n' + codeTestSnippet + code; + return newCode; +} +exports.preprocessCode = preprocessCode; +function getDebugConfig() { + const { nodeBinPath } = config_1.config; + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + preLaunchTask: 'algorithm: build', + }; +} +exports.getDebugConfig = getDebugConfig; +function checkBeforeDebug(filePath) { + const lang = langConfig_1.getFileLang(filePath); + if (lang === langConfig_1.CodeLang.TypeScript) { + if (config_1.InstallState.installEsbuild || !config_1.checkEsbuildDir()) { + config_1.log.appendLine('wait downloading esbuild'); + return false; + } + } + return true; +} +exports.checkBeforeDebug = checkBeforeDebug; +function sortFiles(files) { + files.sort((q1, q2) => { + const fid1 = q1.name; + const fid2 = q2.name; + const sortOrder = ['LCP', 'LCS', '剑指 Offer', '面试题']; + const weight1 = sortOrder.findIndex((prefix) => fid1.startsWith(prefix)); + const weight2 = sortOrder.findIndex((prefix) => fid2.startsWith(prefix)); + if (weight1 !== weight2) { + return weight1 - weight2; + } + else { + if (weight1 !== -1) { + return fid1.localeCompare(fid2); + } + return parseInt(fid1) - parseInt(fid2); + } + }); +} +exports.sortFiles = sortFiles; +function sortQuestions(questions) { + questions.sort((q1, q2) => { + const fid1 = q1.fid; + const fid2 = q2.fid; + const sortOrder = ['LCP', 'LCS', '剑指 Offer', '面试题']; + const weight1 = sortOrder.findIndex((prefix) => fid1.startsWith(prefix)); + const weight2 = sortOrder.findIndex((prefix) => fid2.startsWith(prefix)); + if (weight1 !== weight2) { + return weight1 - weight2; + } + else { + if (weight1 !== -1) { + return fid1.localeCompare(fid2); + } + return parseInt(fid1) - parseInt(fid2); + } + }); +} +exports.sortQuestions = sortQuestions; +function reRequire(moduleName) { + delete require.cache[moduleName]; + return require(moduleName); +} +exports.reRequire = reRequire; +//# sourceMappingURL=util.js.map diff --git a/tools/supperchong.algorithm/out/webview/buildCodeWebview.js b/tools/supperchong.algorithm/out/webview/buildCodeWebview.js new file mode 100644 index 0000000..9745832 --- /dev/null +++ b/tools/supperchong.algorithm/out/webview/buildCodeWebview.js @@ -0,0 +1,133 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createPanel = void 0; +const path = require("path"); +const vscode = require("vscode"); +const vscode_1 = require("vscode"); +const util_1 = require("../util"); +// eslint-disable-next-line @typescript-eslint/no-var-requires +class BuildCodePanel { + constructor(panel, context, text, langSlug) { + this.clipboard = vscode_1.env.clipboard; + this._disposables = []; + this._panel = panel; + this._extensionPath = context.extensionPath; + this.context = context; + this.text = text; + this.langSlug = langSlug; + this.registerCommand('algorithm.copyCode', () => { + this.clipboard.writeText(this.text); + }); + this.initView(); + // Set the webview's initial html content + this._update(); + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables); + // Update the content based on view changes + this._panel.onDidChangeViewState((e) => { + this.setbuildCodeActiveContext(e.webviewPanel.active); + if (e.webviewPanel.active) { + this._update(); + } + }, null, this._disposables); + } + setbuildCodeActiveContext(value) { + vscode.commands.executeCommand('setContext', BuildCodePanel.buildCodeActiveContextKey, value); + } + registerCommand(id, impl, thisArg) { + if (!BuildCodePanel.commands.get(id)) { + const dispose = vscode.commands.registerCommand(id, impl, thisArg); + this.context.subscriptions.push(dispose); + BuildCodePanel.commands.set(id, dispose); + } + } + static createOrShow(context, text, langSlug) { + const column = vscode.ViewColumn.Two; + const extensionPath = context.extensionPath; + // If we already have a panel, show it. + if (BuildCodePanel.currentPanel) { + BuildCodePanel.currentPanel._panel.reveal(column); + BuildCodePanel.currentPanel.update(text, langSlug); + return; + } + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel(BuildCodePanel.viewType, 'code', vscode.ViewColumn.Two, { + // Enable javascript in the webview + enableScripts: true, + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + }); + BuildCodePanel.currentPanel = new BuildCodePanel(panel, context, text, langSlug); + } + dispose() { + BuildCodePanel.currentPanel = undefined; + // Clean up our resources + this._panel.dispose(); + this.setbuildCodeActiveContext(false); + while (this._disposables.length) { + const x = this._disposables.pop(); + if (x) { + x.dispose(); + } + } + } + update(text, langSlug) { + this.text = text; + this.langSlug = langSlug; + this._update(); + } + getWebviewUri(name) { + const webview = this._panel.webview; + const scriptPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', name)); + return webview.asWebviewUri(scriptPathOnDisk); + } + initView() { + const nonce = getNonce(); + // And the uri we use to load this script in the webview + const buildCodeUri = this.getWebviewUri('buildcode.js'); + const scriptUri = this.getWebviewUri('highlight.min.js'); + const cssUri = this.getWebviewUri('highlight.css'); + this._panel.webview.html = ` + + + + + + + Cat Coding + + + +
+
+ + + + + `; + } + _update() { + this.setbuildCodeActiveContext(true); + const code = util_1.highlightCode(this.text, this.langSlug); + this._panel.webview.postMessage({ command: 'newCode', data: code }); + } +} +BuildCodePanel.buildCodeActiveContextKey = 'buildCodeFocus'; +BuildCodePanel.viewType = 'buildCodeView'; +BuildCodePanel.commands = new Map(); +function getNonce() { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} +function createPanel(context, text, langSlug) { + BuildCodePanel.createOrShow(context, text, langSlug); +} +exports.createPanel = createPanel; +//# sourceMappingURL=buildCodeWebview.js.map \ No newline at end of file diff --git a/tools/supperchong.algorithm/out/webview/questionPreview.js b/tools/supperchong.algorithm/out/webview/questionPreview.js new file mode 100644 index 0000000..eccb096 --- /dev/null +++ b/tools/supperchong.algorithm/out/webview/questionPreview.js @@ -0,0 +1,301 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getQuestionDescription = exports.createQuestionPanelCommand = exports.getName = exports.fetchQuestion = exports.QuestionPreview = void 0; +const path = require("path"); +const vscode = require("vscode"); +const index_1 = require("../api/index"); +const config_1 = require("../config"); +const util_1 = require("../common/util"); +const util_2 = require("../util"); +const langConfig_1 = require("../common/langConfig"); +const common_1 = require("../lang/common"); +const fs_extra_1 = require("fs-extra"); +const website_1 = require("../common/website"); +exports.QuestionPreview = 'algorithm.questionPreview'; +// eslint-disable-next-line @typescript-eslint/no-var-requires +const md = require('markdown-it')({ + html: true, + inkify: true, + typographer: true, +}); +function getNonce() { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} +function fetchQuestion(param) { + return __awaiter(this, void 0, void 0, function* () { + let { titleSlug, weekname, questionId: id, itemId } = param; + let data; + let question = null; + if (itemId) { + const q = yield index_1.api.fetchQuestionByItemId(itemId); + if (q) { + id = q.questionId; + titleSlug = q.titleSlug; + } + } + if (id) { + question = yield index_1.api.fetchQuestionDetailById(id); + } + if (!question && titleSlug) { + if (weekname) { + data = yield index_1.api.fetchContestQuestionDetail(titleSlug, weekname); + question = util_1.parseHtml(data); + } + else { + question = yield index_1.api.fetchQuestionDetail(titleSlug); + } + //if (question) { + // index_1.api.saveQuestionDetail(question); + //} + } + if (question) { + index_1.api.saveQuestionDetail(question); + } + return question; + }); +} +exports.fetchQuestion = fetchQuestion; +function getCodeSnippet(codeSnippets) { + const langTypes = [config_1.config.codeLang, config_1.config.database]; + for (const defaultLang of langTypes) { + const codeSnippet = codeSnippets.find((codeSnippet) => codeSnippet.lang === defaultLang); + if (codeSnippet) { + return codeSnippet; + } + } + return codeSnippets[0]; +} +function getName(questionFrontendId, title, translatedTitle, codeSnippet) { + const langSlug = codeSnippet.langSlug; + const langConfig = langConfig_1.langMap[langSlug]; + let filename = questionFrontendId + langConfig.fileNameSep + title + langConfig.ext; + //if (config_1.config.lang === 'cn' && !langConfig_1.enNameLangs.includes(langConfig.lang)) { + if (config_1.config.lang === 'cn') { + filename = questionFrontendId + langConfig.fileNameSep + translatedTitle + langConfig.ext; + } + const questionDir = path.join(config_1.config.algDir, codeSnippet.lang); + let filePath = path.join(questionDir, filename); + let name = path.parse(filename).name; + if (langConfig.lang === langConfig_1.CodeLang.Go) { + filePath = path.join(questionDir, name, 'solution.go'); + } + else if (langConfig.lang === langConfig_1.CodeLang.Java) { + name = '_' + name.replace(/\./, '_'); + name = name.replace(/[^\w]/g, '_'); + filePath = path.join(questionDir, name, 'Solution.java'); + } + else if (langConfig.lang === langConfig_1.CodeLang['C++']) { + //name = name.replace(/[^\w]/g, '_'); + filePath = path.join(questionDir, 'question', name, 'solution' +langConfig.ext); + name = 'solution' + } + return { + filePath, + name, + filename, + }; +} +exports.getName = getName; +class QuestionPreviewPanel { + constructor(panel, extensionPath, text, titleSlug) { + this._disposables = []; + this._panel = panel; + this._extensionPath = extensionPath; + // QuestionPreviewPanel._text = text; + this.text = text; + this.titleSlug = titleSlug; + // Set the webview's initial html content + this._update(); + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables); + // Update the content based on view changes + this._panel.onDidChangeViewState((e) => { + this.setbuildCodeActiveContext(e.webviewPanel.active); + if (this._panel.visible) { + this._update(); + } + }, null, this._disposables); + // Handle messages from the webview + this._panel.webview.onDidReceiveMessage((message) => { + switch (message.command) { + case 'alert': + vscode.window.showErrorMessage(message.text); + return; + } + }, null, this._disposables); + } + setbuildCodeActiveContext(value) { + vscode.commands.executeCommand('setContext', QuestionPreviewPanel.buildCodeActiveContextKey, value); + } + static createOrShow(extensionPath, text, titleSlug) { + const column = vscode.ViewColumn.Two; + // If we already have a panel, show it. + if (QuestionPreviewPanel.currentPanel) { + QuestionPreviewPanel.currentPanel._panel.reveal(column); + QuestionPreviewPanel.currentPanel.update(text, titleSlug); + return; + } + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel(QuestionPreviewPanel.viewType, 'algorithm', column, { + // Enable javascript in the webview + enableScripts: true, + // And restrict the webview to only loading content from our extension's `media` directory. + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + }); + QuestionPreviewPanel.currentPanel = new QuestionPreviewPanel(panel, extensionPath, text, titleSlug); + } + doRefactor() { + // Send a message to the webview webview. + // You can send any JSON serializable data. + this._panel.webview.postMessage({ command: 'refactor' }); + } + dispose() { + QuestionPreviewPanel.currentPanel = undefined; + // Clean up our resources + this._panel.dispose(); + this.setbuildCodeActiveContext(false); + while (this._disposables.length) { + const x = this._disposables.pop(); + if (x) { + x.dispose(); + } + } + } + update(text, titleSlug) { + this.text = text; + this.titleSlug = titleSlug; + this._update(); + } + _update() { + this.setbuildCodeActiveContext(true); + const webview = this._panel.webview; + const nonce = getNonce(); + // const scriptPathOnDisk = vscode.Uri.file( + // path.join(this._extensionPath, 'media', 'highlight.min.js') + // ) + const cssPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', 'highlight.css')); + const cssMdOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', 'markdown.css')); + const text = this.text; + const titleSlug = this.titleSlug; + const solutionUrl = website_1.getSolution(titleSlug); + // let temp = QuestionPreviewPanel._text; + const temp = text.replace(/
/g, '
').replace(/<\/pre>/g, '
'); + const code = md.render(temp); + const cssUri = webview.asWebviewUri(cssPathOnDisk); + const cssMd = webview.asWebviewUri(cssMdOnDisk); + this._panel.webview.html = ` + + + + + + + Cat Coding + + + + + + ${code} +
+
+ Solution + + + `; + } +} +QuestionPreviewPanel.buildCodeActiveContextKey = 'questionPreviewFocus'; +QuestionPreviewPanel.viewType = 'questionPreview'; +QuestionPreviewPanel.commandText = exports.QuestionPreview; +QuestionPreviewPanel.commands = new Map(); +function createQuestionPanelCommand(extensionPath, param) { + return __awaiter(this, void 0, void 0, function* () { + const { weekname } = param; + try { + const question = yield fetchQuestion(param); + if (question) { + const { codeSnippets, questionFrontendId, title, content, translatedContent, translatedTitle, titleSlug } = question; + //preview + let previewText = `# ${title}\n` + content; + if (config_1.config.lang === 'cn') { + previewText = `# ${questionFrontendId} ${translatedTitle}\n` + + `\`${param.titleSlug}\`` + + translatedContent; + } + const codeSnippet = getCodeSnippet(codeSnippets); + const langSlug = codeSnippet.langSlug; + const langConfig = langConfig_1.langMap[langSlug]; + //generate code + const { filePath, name } = getName(questionFrontendId, title, translatedTitle, codeSnippet); + const exist = yield fs_extra_1.pathExists(filePath); + if (!exist) { + const supportImport = ['JavaScript', 'TypeScript'].includes(langConfig.lang); + if (supportImport && util_2.shouldAskForImport()) { + util_2.askForImport(); + } + let code = util_2.preprocessCode(question, weekname, codeSnippet, name); + if (langConfig.lang === langConfig_1.CodeLang.Java) { + code = code.replace('class Solution', 'public class Solution'); + } + if (langConfig_1.isAlgorithm(langConfig.lang)) { + yield common_1.Service.handlePreImport(filePath); + } + yield util_1.writeFile(filePath, code); + } + const fileDocument = yield vscode.workspace.openTextDocument(filePath); + yield vscode.window.showTextDocument(fileDocument, vscode.ViewColumn.One); + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug); + } + else { + console.log('parse question error:', question); + } + return; + } + catch (err) { + console.log(err); + } + }); +} +exports.createQuestionPanelCommand = createQuestionPanelCommand; +function getQuestionDescription(extensionPath, param) { + return __awaiter(this, void 0, void 0, function* () { + const question = yield fetchQuestion(param); + if (question) { + const { title, content, translatedContent, translatedTitle, titleSlug } = question; + //preview + let previewText = `# ${title}\n` + content; + if (config_1.config.lang === 'cn') { + previewText = `# ${translatedTitle}\n` + translatedContent; + } + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug); + } + else { + console.log('question not found'); + } + }); +} +exports.getQuestionDescription = getQuestionDescription; +//# sourceMappingURL=questionPreview.js.map diff --git a/tools/supperchong.algorithm/out/webview/submitHistory.js b/tools/supperchong.algorithm/out/webview/submitHistory.js new file mode 100644 index 0000000..09484f4 --- /dev/null +++ b/tools/supperchong.algorithm/out/webview/submitHistory.js @@ -0,0 +1,194 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createSubmitHistoryPanel = void 0; +const path = require("path"); +const vscode = require("vscode"); +const index_1 = require("../api/index"); +const config_1 = require("../config"); +const history_1 = require("../history"); +const util_1 = require("../util"); +class BuildSubmitHistoryPanel { + constructor(panel, context, question_id) { + this._disposables = []; + this._panel = panel; + this._extensionPath = context.extensionPath; + this.context = context; + this.question_id = question_id; + this.initView(); + this._update(); + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables); + this._panel.webview.onDidReceiveMessage((message) => { + switch (message.command) { + case 'getSubmissionCode': + index_1.api.fetchSubmissionDetail({ id: message.id }) + .then((code) => { + const p = util_1.highlightCode(code, message.lang); + console.log(p); + this._panel.webview.postMessage({ + command: 'submissionDetail', + data: { + code: util_1.highlightCode(code, message.lang), + id: message.id, + uuid: message.uuid, + }, + }); + }) + .catch((err) => { + this._panel.webview.postMessage({ + command: 'submissionDetail', + data: { + code: err, + id: message.id, + uuid: message.uuid, + }, + }); + }); + return; + case 'updateComment': { + history_1.updateComment(message.type, message.params) + .then(() => { + this._panel.webview.postMessage({ + command: 'updateComment', + data: { + code: 200, + msg: 'ok', + uuid: message.uuid, + }, + }); + }) + .catch((err) => { + this._panel.webview.postMessage({ + command: 'updateComment', + data: { + code: 201, + msg: 'update fail', + uuid: message.uuid, + }, + }); + config_1.config.log.appendLine(err); + }); + } + } + }, null, this._disposables); + } + static createOrShow(context, question_id) { + const column = vscode.ViewColumn.Two; + const extensionPath = context.extensionPath; + // If we already have a panel, show it. + if (BuildSubmitHistoryPanel.currentPanel) { + BuildSubmitHistoryPanel.currentPanel._panel.reveal(column); + BuildSubmitHistoryPanel.currentPanel.update(question_id); + return; + } + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel(BuildSubmitHistoryPanel.viewType, 'history', vscode.ViewColumn.Two, { + // Enable javascript in the webview + enableScripts: true, + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + }); + BuildSubmitHistoryPanel.currentPanel = new BuildSubmitHistoryPanel(panel, context, question_id); + } + dispose() { + BuildSubmitHistoryPanel.currentPanel = undefined; + // Clean up our resources + this._panel.dispose(); + while (this._disposables.length) { + const x = this._disposables.pop(); + if (x) { + x.dispose(); + } + } + } + update(question_id) { + if (question_id !== this.question_id) { + this.question_id = question_id; + // BuildSubmitHistoryPanel._text = text; + this._update(); + } + } + getWebviewUri(name) { + const webview = this._panel.webview; + const scriptPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', name)); + return webview.asWebviewUri(scriptPathOnDisk); + } + initView() { + const nonce = getNonce(); + const historyUri = this.getWebviewUri('history.js'); + const scriptUri = this.getWebviewUri('highlight.min.js'); + const cssUri = this.getWebviewUri('highlight.css'); + const historyCssUri = this.getWebviewUri('history.css'); + this._panel.webview.html = ` + + + + + + + Cat Coding + + + + + +
+
+ + + + + + `; + } + _update() { + return __awaiter(this, void 0, void 0, function* () { + const question_id = this.question_id; + const data = yield history_1.getHistory(question_id, util_1.highlightCode); + this._panel.webview.postMessage({ command: 'init', data: data }); + history_1.getRemoteSubmits(question_id).then((data) => { + this._panel.webview.postMessage({ + command: 'remoteStorageData', + data: data, + }); + }); + }); + } +} +BuildSubmitHistoryPanel.viewType = 'submitHistoryView'; +BuildSubmitHistoryPanel.commands = new Map(); +function getNonce() { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} +function createSubmitHistoryPanel(context, question_id) { + BuildSubmitHistoryPanel.createOrShow(context, question_id); +} +exports.createSubmitHistoryPanel = createSubmitHistoryPanel; +//# sourceMappingURL=submitHistory.js.map \ No newline at end of file -- Gitee From c86d657a27b4fe2144c6c7e32dd239d87ce6cfe2 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 18 Jul 2021 14:13:21 +0800 Subject: [PATCH 48/77] =?UTF-8?q?supperchong.algorithm-=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9B=AE=E5=BD=95(./)=E5=92=8C=E5=8F=AF?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95(../../)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/supperchong.algorithm/out/config.js | 8 ++++---- tools/supperchong.algorithm/out/lang/cpp.js | 4 ++-- .../supperchong.algorithm/out/webview/questionPreview.js | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/supperchong.algorithm/out/config.js b/tools/supperchong.algorithm/out/config.js index 38cd38d..4d25cf8 100644 --- a/tools/supperchong.algorithm/out/config.js +++ b/tools/supperchong.algorithm/out/config.js @@ -76,7 +76,7 @@ function initConfig() { const algDir = path.join(baseDir, lang); const cacheBaseDir = path.join(os.homedir(), '.algcache'); const cacheDir = path.join(os.homedir(), '.algcache', lang); - const questionDir = path.join(baseDir, lang, codeLang); + const questionDir = baseDir; const database = customConfig.get('database') || defaultDataBase; const cookiePath = path.join(cacheDir, 'cookie.json'); const questionPath = path.join(cacheDir, 'question.json'); @@ -224,7 +224,7 @@ function updateLang() { const baseDir = exports.config.baseDir; exports.config.lang = vscode_1.workspace.getConfiguration('algorithm').get('lang') || defaultLang; exports.config.algDir = path.join(baseDir, exports.config.lang); - exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); + exports.config.questionDir = baseDir; exports.config.cacheDir = path.join(os.homedir(), '.algcache', exports.config.lang); exports.config.cookiePath = path.join(exports.config.cacheDir, 'cookie.json'); exports.config.questionPath = path.join(exports.config.cacheDir, 'question.json'); @@ -234,7 +234,7 @@ function updateLang() { function updateCodeLang() { const baseDir = exports.config.baseDir; exports.config.codeLang = vscode_1.workspace.getConfiguration('algorithm').get('codeLang') || defaultCodeLang; - exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); + exports.config.questionDir = baseDir; } function updateDataBaseLang() { exports.config.database = vscode_1.workspace.getConfiguration('algorithm').get('database') || defaultDataBase; @@ -255,7 +255,7 @@ function updateBaseDir() { const baseDir = vscode_1.workspace.getConfiguration('algorithm').get('baseDir') || defaultBaseDir; exports.config.baseDir = baseDir; exports.config.algDir = path.join(baseDir, exports.config.lang); - exports.config.questionDir = path.join(baseDir, exports.config.lang, exports.config.codeLang); + exports.config.questionDir = baseDir; exports.config.debugOptionsFilePath = path.join(baseDir, '.vscode/debugParams.json'); exports.config.moduleDir = path.join(baseDir, 'node_modules'); exports.config.algmModuleDir = path.join(exports.config.moduleDir, 'algm'); diff --git a/tools/supperchong.algorithm/out/lang/cpp.js b/tools/supperchong.algorithm/out/lang/cpp.js index d280c12..7ae0c87 100644 --- a/tools/supperchong.algorithm/out/lang/cpp.js +++ b/tools/supperchong.algorithm/out/lang/cpp.js @@ -301,7 +301,7 @@ class CppParse extends base_1.BaseLang { } getExecProgram() { const cwd = this.cwd; - return path.join(cwd, 'test.exe'); + return path.join(cwd, '../../test.exe'); } runMultiple(caseList, _originCode, _funcName) { return __awaiter(this, void 0, void 0, function* () { @@ -345,7 +345,7 @@ class CppParse extends base_1.BaseLang { yield execFileAsync(GCC, ['-I', '.', '-g', '-I'+this.prj_dir+'/../include', '-I'+this.prj_dir+'/../include/algm', - 'main.cpp', '-o', 'test.exe'], { cwd: cwd, shell: true }); + 'main.cpp', '-o', '../../test.exe'], { cwd: cwd, shell: true }); }); } getTestFilePath() { diff --git a/tools/supperchong.algorithm/out/webview/questionPreview.js b/tools/supperchong.algorithm/out/webview/questionPreview.js index eccb096..d86d2fc 100644 --- a/tools/supperchong.algorithm/out/webview/questionPreview.js +++ b/tools/supperchong.algorithm/out/webview/questionPreview.js @@ -87,7 +87,7 @@ function getName(questionFrontendId, title, translatedTitle, codeSnippet) { if (config_1.config.lang === 'cn') { filename = questionFrontendId + langConfig.fileNameSep + translatedTitle + langConfig.ext; } - const questionDir = path.join(config_1.config.algDir, codeSnippet.lang); + const questionDir = config_1.config.baseDir; let filePath = path.join(questionDir, filename); let name = path.parse(filename).name; if (langConfig.lang === langConfig_1.CodeLang.Go) { @@ -100,7 +100,7 @@ function getName(questionFrontendId, title, translatedTitle, codeSnippet) { } else if (langConfig.lang === langConfig_1.CodeLang['C++']) { //name = name.replace(/[^\w]/g, '_'); - filePath = path.join(questionDir, 'question', name, 'solution' +langConfig.ext); + filePath = path.join(questionDir, 'questions', name, 'solution' +langConfig.ext); name = 'solution' } return { -- Gitee From b14ecfe193c1c7fbea2cb0a606534f42c8157f91 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 18 Jul 2021 23:57:04 +0800 Subject: [PATCH 49/77] =?UTF-8?q?supperchong.algorithm-=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=8F=8F=E8=BF=B0=E9=9D=A2=E9=A1=B5=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E5=8F=8A=E6=B5=8B=E8=AF=95=E6=8C=89=E9=92=AE=E6=96=87?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/provider/codelensProvider.js | 2 +- .../out/webview/questionPreview.js | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/tools/supperchong.algorithm/out/provider/codelensProvider.js b/tools/supperchong.algorithm/out/provider/codelensProvider.js index abc7140..fdc8485 100644 --- a/tools/supperchong.algorithm/out/provider/codelensProvider.js +++ b/tools/supperchong.algorithm/out/provider/codelensProvider.js @@ -59,7 +59,7 @@ class CodelensProvider { const { testCaseParam: { line }, } = options; const codeLens = new vscode.CodeLens(new vscode.Range(line, 0, line, 7)); codeLens.command = { - title: 'test', + title: 'RunTestCases', tooltip: 'test', command: 'algorithm.testCode', arguments: [options], diff --git a/tools/supperchong.algorithm/out/webview/questionPreview.js b/tools/supperchong.algorithm/out/webview/questionPreview.js index d86d2fc..6517a61 100644 --- a/tools/supperchong.algorithm/out/webview/questionPreview.js +++ b/tools/supperchong.algorithm/out/webview/questionPreview.js @@ -142,7 +142,7 @@ class QuestionPreviewPanel { setbuildCodeActiveContext(value) { vscode.commands.executeCommand('setContext', QuestionPreviewPanel.buildCodeActiveContextKey, value); } - static createOrShow(extensionPath, text, titleSlug) { + static createOrShow(extensionPath, text, titleSlug, viewTitle) { const column = vscode.ViewColumn.Two; // If we already have a panel, show it. if (QuestionPreviewPanel.currentPanel) { @@ -151,7 +151,7 @@ class QuestionPreviewPanel { return; } // Otherwise, create a new panel. - const panel = vscode.window.createWebviewPanel(QuestionPreviewPanel.viewType, 'algorithm', column, { + const panel = vscode.window.createWebviewPanel(QuestionPreviewPanel.viewType, viewTitle, column, { // Enable javascript in the webview enableScripts: true, // And restrict the webview to only loading content from our extension's `media` directory. @@ -240,10 +240,11 @@ function createQuestionPanelCommand(extensionPath, param) { const { codeSnippets, questionFrontendId, title, content, translatedContent, translatedTitle, titleSlug } = question; //preview let previewText = `# ${title}\n` + content; + let viewTitle = `${questionFrontendId}`; if (config_1.config.lang === 'cn') { - previewText = `# ${questionFrontendId} ${translatedTitle}\n` - + `\`${param.titleSlug}\`` - + translatedContent; + let questionUrl = `https://leetcode-cn.com/problems/${param.titleSlug}`; + previewText = `\[\[${questionFrontendId}. ${translatedTitle}\]\(${questionUrl}\)\]\(${questionUrl}\)\n` + + `\n --- \n` + translatedContent; } const codeSnippet = getCodeSnippet(codeSnippets); const langSlug = codeSnippet.langSlug; @@ -267,7 +268,7 @@ function createQuestionPanelCommand(extensionPath, param) { } const fileDocument = yield vscode.workspace.openTextDocument(filePath); yield vscode.window.showTextDocument(fileDocument, vscode.ViewColumn.One); - QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug); + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug, viewTitle); } else { console.log('parse question error:', question); @@ -284,13 +285,16 @@ function getQuestionDescription(extensionPath, param) { return __awaiter(this, void 0, void 0, function* () { const question = yield fetchQuestion(param); if (question) { - const { title, content, translatedContent, translatedTitle, titleSlug } = question; + const { questionFrontendId, title, content, translatedContent, translatedTitle, titleSlug } = question; //preview + let viewTitle = `${questionFrontendId}`; let previewText = `# ${title}\n` + content; if (config_1.config.lang === 'cn') { - previewText = `# ${translatedTitle}\n` + translatedContent; + let questionUrl = `https://leetcode-cn.com/problems/${param.titleSlug}`; + previewText = `\[\[${questionFrontendId}. ${translatedTitle}\]\(${questionUrl}\)\]\(${questionUrl}\)\n` + + `\n --- \n` + translatedContent; } - QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug); + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug, viewTitle); } else { console.log('question not found'); -- Gitee From fcb0f25655a03b9651a560804afaf7d0da48420b Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 19 Jul 2021 00:00:29 +0800 Subject: [PATCH 50/77] =?UTF-8?q?LC-30.=E4=B8=B2=E8=81=94=E6=89=80?= =?UTF-8?q?=E6=9C=89=E5=8D=95=E8=AF=8D=E7=9A=84=E5=AD=90=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../main.cpp" | 19 ++++++++ .../solution.h" | 43 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 "questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/main.cpp" create mode 100644 "questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/solution.h" diff --git a/README.md b/README.md index a7778bc..2b02d07 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) +[30. 串联所有单词的子串](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words) ## 链表 [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 diff --git "a/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/main.cpp" "b/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/main.cpp" new file mode 100644 index 0000000..8038b4f --- /dev/null +++ "b/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"\\\"barfoothefoobarman\\\"\",\"[\\\"foo\\\",\\\"bar\\\"]\"],[\"\\\"wordgoodgoodgoodbestword\\\"\",\"[\\\"word\\\",\\\"good\\\",\\\"best\\\",\\\"word\\\"]\"],[\"\\\"barfoofoobarthefoobarman\\\"\",\"[\\\"bar\\\",\\\"foo\\\",\\\"the\\\"]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + string arg0 = parseString(args[0]); + vector arg1 = parseStringArr(args[1]); + vector result=s->findSubstring(arg0,arg1); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/solution.h" "b/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/solution.h" new file mode 100644 index 0000000..d2ed834 --- /dev/null +++ "b/questions/30.\344\270\262\350\201\224\346\211\200\346\234\211\345\215\225\350\257\215\347\232\204\345\255\220\344\270\262/solution.h" @@ -0,0 +1,43 @@ +// @algorithm @lc id=30 lang=cpp +// @title substring-with-concatenation-of-all-words + + +// #define print(...) +// @test("barfoothefoobarman",["foo","bar"])=[0,9] +// @test("wordgoodgoodgoodbestword",["word","good","best","word"])=[] +// @test("barfoofoobarthefoobarman",["bar","foo","the"])=[6,9,12] +class Solution { +public: +vector findSubstring(string s, vector& words) { + vector res; + auto width = words[0].size(); + auto num = words.size(); + unordered_map cntWords; + for(auto &w : words) + cntWords[w]++; + for(size_t offset=0; offset cntInWin; // 窗口中有效 word 数量 + while(right < s.size()-width+1){ + auto word = s.substr(right, width); + right += width; + if(0>=cntWords.count(word)){ // word 无效 + left = right; + cntInWin.clear(); + continue; + } + cntInWin[word]++; + while(cntWords[word] < cntInWin[word]){ // word 重复次数过多 + cntInWin[s.substr(left, width)]--; + left += width; + } + if(left + width*num == right){ + res.push_back(left); + cntInWin[s.substr(left, width)]--; + left += width; + } + } + } + return res; +} +}; \ No newline at end of file -- Gitee From 3e540a983e54319354d6713a258e68a7ccaf1950 Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 19 Jul 2021 10:20:02 +0800 Subject: [PATCH 51/77] =?UTF-8?q?LC-1846.=E5=87=8F=E5=B0=8F=E5=92=8C?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E6=8E=92=E5=88=97=E6=95=B0=E7=BB=84=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E5=A4=A7=E5=85=83=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 ++++++++++++++++++ .../solution.h" | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 "questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/main.cpp" create mode 100644 "questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/solution.h" diff --git a/README.md b/README.md index 2b02d07..dc842e4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [1833. 雪糕的最大数量](https://leetcode-cn.com/problems/maximum-ice-cream-bars/) [12. 整数转罗马数字](https://leetcode-cn.com/problems/integer-to-roman/) + +[1846. 减小和重新排列数组后的最大元素](https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging) ## 动态规则 [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git "a/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/main.cpp" "b/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/main.cpp" new file mode 100644 index 0000000..0862f9a --- /dev/null +++ "b/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[2,2,1,2,1]\"],[\"[100,1,1000]\"],[\"[1,2,3,4,5]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int result=s->maximumElementAfterDecrementingAndRearranging(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/solution.h" "b/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/solution.h" new file mode 100644 index 0000000..f2756c7 --- /dev/null +++ "b/questions/1846.\345\207\217\345\260\217\345\222\214\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204\345\220\216\347\232\204\346\234\200\345\244\247\345\205\203\347\264\240/solution.h" @@ -0,0 +1,18 @@ +// @algorithm @lc id=1956 lang=cpp +// @title maximum-element-after-decreasing-and-rearranging + + +// #define print(...) +// @test([2,2,1,2,1])=2 +// @test([100,1,1000])=3 +// @test([1,2,3,4,5])=5 +class Solution { +public: + int maximumElementAfterDecrementingAndRearranging(vector& arr) { + sort(arr.begin(), arr.end()); + arr[0] = 1; + for(int i=1; i Date: Mon, 19 Jul 2021 14:41:19 +0800 Subject: [PATCH 52/77] =?UTF-8?q?LC-1838.=E6=9C=80=E9=AB=98=E9=A2=91?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E7=9A=84=E9=A2=91=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 +++++++++++ .../solution.h" | 33 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 "questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/main.cpp" create mode 100644 "questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/solution.h" diff --git a/README.md b/README.md index dc842e4..c24de2d 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) [30. 串联所有单词的子串](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words) + +[1838. 最高频元素的频数](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element) ## 链表 [19. 删除链表的倒数第 N 个结点](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)「双指针」 diff --git "a/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/main.cpp" "b/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/main.cpp" new file mode 100644 index 0000000..166d21f --- /dev/null +++ "b/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[1,2,4]\",\"5\"],[\"[1,4,8,13]\",\"5\"],[\"[3,9,6]\",\"2\"],[\"[9979,9938,9947,9916,9995,9981,9981,9931,9984,9942,9946,9946,9945,9931,9908,9920,9929,9917,9904,9945,9963,9910,9942,9965,9915,9981,9908,9919,9975,9904,9934,9922,9989,9946,9928,9928,9940,9941,9995,9905,9903,9980,9917,9940,9910,9994,9909,9965,9972,9931,9975,9913,9983,9943,9996,9917,9994,9991,9948,9961,9921,9981,9928,9933,9905,9957,9953,9940,9958,9982,9900,9912,9959,9992,9978,9988,9940,9985,9945,9900,9956,9976,9972,9914,9903,9978,9965,9987,9926,9963,9968,9962,9995,9963,9960,9986,9916,9911,9976,9988,9952,9914,9934,9929,9962,9999,9988,9901,9925,9983,9991,9915,9930,9949,9931,9944,9947,9921,9982,9984,9998,9945,9907,9900,9992,9945,9995,9941,9930,9918,9961,9960,9900,9952,9952,9954,9976,9970,9990,9947,9910,9908,9935,9971,9971,10000,9941,9983,9949,9985,9992,9996,9918,9930,9994,9970,9989,9975,9960,9973,9993,9900,9915,9974,9966,9978,9926,9937,9936,9952,9996,9996,9912,9915,9976,9976,9901,9926,9959,9989,9976,9904,9999,9925,9934,9947,9950,9985,9985,9932,9922,9962,9962,9993,9912,9924,9992,9941,9959,9954,9943,9995,9992,9928,9992,9920,9984,9917,9976,9971,9927,9917,9923,9948,9929,9990,9990,9921,9989,9910,9921]\",\"2636\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int arg1 = parseInteger(args[1]); + int result=s->maxFrequency(arg0,arg1); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/solution.h" "b/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/solution.h" new file mode 100644 index 0000000..62f7d9c --- /dev/null +++ "b/questions/1838.\346\234\200\351\253\230\351\242\221\345\205\203\347\264\240\347\232\204\351\242\221\346\225\260/solution.h" @@ -0,0 +1,33 @@ +// @algorithm @lc id=1966 lang=cpp +// @title frequency-of-the-most-frequent-element + + +#define print(...) +// @test([1,2,4],5)=3 +// @test([1,4,8,13],5)=2 +// @test([3,9,6],2)=1 +// test([9930,9923,9983,9997,9934,9952,9945,9914,9985,9982,9970,9932,9985,9902,9975,9990,9922,9990,9994,9937,9996,9964,9943,9963,9911,9925,9935,9945,9933,9916,9930,9938,10000,9916,9911,9959,9957,9907,9913,9916,9993,9930,9975,9924,9988,9923,9910,9925,9977,9981,9927,9930,9927,9925,9923,9904,9928,9928,9986,9903,9985,9954,9938,9911,9952,9974,9926,9920,9972,9983,9973,9917,9995,9973,9977,9947,9936,9975,9954,9932,9964,9972,9935,9946,9966],3056)=73 +// test([9953,9960,9908,9957,9919,9967,9941,9985,9925,9933,9989,9999,9928,9990,9973,9930,9982,9911,9986,9931,9925,9943,9937,9956,9968,9988,9929,9997,9945,9931,9922,9948,9916,9948,9998,9967,9945,9906,9914,9947,9997,9945,9923,9969,9903,9947,9938,9972,9969,9953,9926,9949,9997,9971,9913,9948,9910,9964,9900,9983,9945,9900,9951,9928,9984,9960,9903,9903,9983,9920,9909,9927,9987,9994,9987,9965,9941,9921,9914,9936,9979,9917,9965,9906,9942,9904,9920,9907,9922,9983,9970,9963,9941,9902,9968,9992,9994,9954,9904,9974,9914,9903,9934,10000,9991,9991,9986,9965,9980,9907,9911,9918,9993,9981,9986,9986,9944,9973,9918,9931,9974,9976,9958,9987,9942,9995,9970,9963,9901,9979,9995,9936,9959,9965,9905,9979,9927,9989,9926,9984,9956,9936,9931,9954,9901,9949,9943,9945,9966,9973,9931,9970,9916,9981,9995,9981,9968,9942,9960,10000,9935,9957,9931,9964,9939,9979,9924,9973,9960,9972,9915,9981,9993,9961,9963,9970,9917,9955,9993,9930,9972,9940,9921,9978,9915,9988,9904,9989,9911,9958,9914,9901,9913,9916,9909,9926,9928,9926,9920,9958,9931,9906,9973,9960,9909,9948,9983,9948,9936,9953,9974,9940],410)=48 +// @test([9979,9938,9947,9916,9995,9981,9981,9931,9984,9942,9946,9946,9945,9931,9908,9920,9929,9917,9904,9945,9963,9910,9942,9965,9915,9981,9908,9919,9975,9904,9934,9922,9989,9946,9928,9928,9940,9941,9995,9905,9903,9980,9917,9940,9910,9994,9909,9965,9972,9931,9975,9913,9983,9943,9996,9917,9994,9991,9948,9961,9921,9981,9928,9933,9905,9957,9953,9940,9958,9982,9900,9912,9959,9992,9978,9988,9940,9985,9945,9900,9956,9976,9972,9914,9903,9978,9965,9987,9926,9963,9968,9962,9995,9963,9960,9986,9916,9911,9976,9988,9952,9914,9934,9929,9962,9999,9988,9901,9925,9983,9991,9915,9930,9949,9931,9944,9947,9921,9982,9984,9998,9945,9907,9900,9992,9945,9995,9941,9930,9918,9961,9960,9900,9952,9952,9954,9976,9970,9990,9947,9910,9908,9935,9971,9971,10000,9941,9983,9949,9985,9992,9996,9918,9930,9994,9970,9989,9975,9960,9973,9993,9900,9915,9974,9966,9978,9926,9937,9936,9952,9996,9996,9912,9915,9976,9976,9901,9926,9959,9989,9976,9904,9999,9925,9934,9947,9950,9985,9985,9932,9922,9962,9962,9993,9912,9924,9992,9941,9959,9954,9943,9995,9992,9928,9992,9920,9984,9917,9976,9971,9927,9917,9923,9948,9929,9990,9990,9921,9989,9910,9921],2636)=118 +class Solution { +public: +int maxFrequency(vector& nums, int k) { + if(nums.size()<=1) return nums.size(); + sort(nums.begin(), nums.end()); + print("nums=", nums, ", k=", k, "\r\n") + auto left = nums.begin(), right = left + 1; + int maxF = 1; + while(right!=nums.end()){ + while(k<0 && left Date: Mon, 19 Jul 2021 22:08:07 +0800 Subject: [PATCH 53/77] =?UTF-8?q?LC-31.=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8E=92=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++----- .../main.cpp" | 18 +++++++++++ .../solution.h" | 30 +++++++++++++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 "questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/main.cpp" create mode 100644 "questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/solution.h" diff --git a/README.md b/README.md index c24de2d..e3dc676 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,6 @@ [1818. 绝对差值和](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/)「二分查找」 -## 代数 -[7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) - -[9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) - -[29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers/) ## 堆 [218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/)「maxheap」 ## 栈 @@ -86,4 +80,12 @@ [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/) -[25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) \ No newline at end of file +[25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) +## 代数 +[7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) + +[9. 回文数](https://leetcode-cn.com/problems/palindrome-number/) + +[29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers/) + +[31. 下一个排列](https://leetcode-cn.com/problems/next-permutation) \ No newline at end of file diff --git "a/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/main.cpp" "b/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/main.cpp" new file mode 100644 index 0000000..a924119 --- /dev/null +++ "b/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[1,2,3]\"],[\"[3,2,1]\"],[\"[1,1,5]\"],[\"[1]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + s->nextPermutation(arg0); + string resultabc =serializeIntegerArr(arg0); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/solution.h" "b/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/solution.h" new file mode 100644 index 0000000..d1465ed --- /dev/null +++ "b/questions/31.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/solution.h" @@ -0,0 +1,30 @@ +// @algorithm @lc id=31 lang=cpp +// @title next-permutation + + +#define print(...) +// @test([1,2,3])=[1,3,2] +// @test([3,2,1])=[1,2,3] +// @test([1,1,5])=[1,5,1] +// @test([1])=[1] +class Solution { +public: + void nextPermutation(vector& nums) { + if(nums.size()<=1) return; + print("nums=", nums, "\r\n") + auto turn = nums.end()-1; + while(turn!=nums.begin()) + { + if(*(turn-1) < *turn){ + auto right=nums.end()-1; + while(*(turn-1) >= *right) right--; + swap(*(turn-1), *right); + print("turn=", turn-nums.begin(),", right=", right-nums.begin(), "\r\n") + break; + } + turn--;// [turn, end) 降序 + } + // [turn, end) 必为降序, 将其翻转 + reverse(turn, nums.end()); + } +}; \ No newline at end of file -- Gitee From 0b4ab6d1ad1e8096651768a5bd1706e860cc29dd Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 19 Jul 2021 23:10:27 +0800 Subject: [PATCH 54/77] =?UTF-8?q?LC-1603.=E8=AE=BE=E8=AE=A1=E5=81=9C?= =?UTF-8?q?=E8=BD=A6=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 24 ++++++++++++++++ .../solution.h" | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 "questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/main.cpp" create mode 100644 "questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/solution.h" diff --git a/README.md b/README.md index e3dc676..b260da3 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ [1. 两数之和](https://leetcode-cn.com/problems/two-sum/)「互补 Key」 [49. 字母异位词分组](https://leetcode-cn.com/problems/group-anagrams/) 同 [面试题 10.02. 变位词组](https://leetcode-cn.com/problems/group-anagrams-lcci/) +## 位运算 +[1603. 设计停车系统](https://leetcode-cn.com/problems/design-parking-system) ## 字符串 [6. Z 字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) diff --git "a/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/main.cpp" "b/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/main.cpp" new file mode 100644 index 0000000..aa8b00a --- /dev/null +++ "b/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/main.cpp" @@ -0,0 +1,24 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + struct { + int big; + int medium; + int small; + vector cars; + } testcases[] = { + {1, 1, 0, {1, 2, 3, 1},}, + }; + for(auto &t : testcases){ + ParkingSystem sys(t.big, t.medium, t.small); + print("big=", t.big, ", medium=", t.medium, ", small=", t.small, "\n") + for(auto &car : t.cars){ + auto res = sys.addCar(car); + print("addCar(", car, ")=", res, "\n") + } + print("\n") + } + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/solution.h" "b/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/solution.h" new file mode 100644 index 0000000..968df67 --- /dev/null +++ "b/questions/1603.\350\256\276\350\256\241\345\201\234\350\275\246\347\263\273\347\273\237/solution.h" @@ -0,0 +1,28 @@ +// @algorithm @lc id=1708 lang=cpp +// @title design-parking-system + +#define FULL 0x3FF +#define GET(t) ( FULL & (_capacity >> ((t)-1)*10) ) +#define DEC(t) ( _capacity -= (1<<((t)-1)*10) ) +class ParkingSystem { + uint32_t _capacity = 0; +public: + ParkingSystem(int big, int medium, int small) { + _capacity |= big; + _capacity |= medium << 10; + _capacity |= small << 20; + } + + bool addCar(int carType) { + if(GET(carType) == 0) + return false; + DEC(carType); + return true; + } +}; + +/** + * Your ParkingSystem object will be instantiated and called as such: + * ParkingSystem* obj = new ParkingSystem(big, medium, small); + * bool param_1 = obj->addCar(carType); + */ \ No newline at end of file -- Gitee From fe02604d2d06e1bddafa00506d62e2dbcc7dd703 Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 20 Jul 2021 00:02:58 +0800 Subject: [PATCH 55/77] =?UTF-8?q?LC-32.=E6=9C=80=E9=95=BF=E6=9C=89?= =?UTF-8?q?=E6=95=88=E6=8B=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 +++++++++++++ .../solution.h" | 25 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 "questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/main.cpp" create mode 100644 "questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/solution.h" diff --git a/README.md b/README.md index b260da3..5162a74 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ [10. 正则表达式匹配](https://leetcode-cn.com/problems/regular-expression-matching/) [剑指 Offer 42.连续子数组的最大和](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/) + +[32. 最长有效括号](https://leetcode-cn.com/problems/longest-valid-parentheses) ## 排序 [451. 根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/)「桶排序」 diff --git "a/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/main.cpp" "b/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/main.cpp" new file mode 100644 index 0000000..b75cf4d --- /dev/null +++ "b/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"\\\"(()\\\"\"],[\"\\\")()())\\\"\"],[\"\\\"\\\"\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + string arg0 = parseString(args[0]); + int result=s->longestValidParentheses(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/solution.h" "b/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/solution.h" new file mode 100644 index 0000000..c2446b6 --- /dev/null +++ "b/questions/32.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/solution.h" @@ -0,0 +1,25 @@ +// @algorithm @lc id=32 lang=cpp +// @title longest-valid-parentheses + + +// #define print(...) +// @test("(()")=2 +// @test(")()())")=4 +// @test("")=0 +class Solution { +public: + int longestValidParentheses(string s) { + int maxLen = 0; + vector dp(s.size(), 0); + for(int i=1; i<(int)s.size(); i++){ + if(s[i] != ')') continue; + if(s[i-1]=='('){ // s[i-1,i] = "()" + dp[i] = 2 + (i >= 2 ? dp[i-2] : 0); + }else if( 1<=i-dp[i-1] && s[i-dp[i-1]-1]=='('){ // s[i-1,i] = "))" + dp[i] = 2 + dp[i-1] + (2<=i-dp[i-1] ? dp[i-dp[i-1]-2] : 0); + } + maxLen = max(maxLen, dp[i]); + } + return maxLen; + } +}; \ No newline at end of file -- Gitee From dfb1bdc7a7be5950723877208d4b4c2e436b6490 Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 21 Jul 2021 13:26:26 +0800 Subject: [PATCH 56/77] =?UTF-8?q?JZ-52.=E4=B8=A4=E4=B8=AA=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 26 +++++++++++++++++++ .../solution.h" | 26 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 "questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/main.cpp" create mode 100644 "questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/solution.h" diff --git a/README.md b/README.md index 5162a74..16dd230 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ [206. 反转链表](https://leetcode-cn.com/problems/reverse-linked-list/) [25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) + +[剑指 Offer 52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof) ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/main.cpp" "b/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/main.cpp" new file mode 100644 index 0000000..0f64b63 --- /dev/null +++ "b/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/main.cpp" @@ -0,0 +1,26 @@ +#include "stl.h" +#include "linkedlist.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + vector> testcases[] = {// A链表,B链表,相交部分 + { {4,1}, {5,0,1}, {8, 4,5} }, + { {3,4}, {1,2,8}, {} }, + }; + + Solution sln; + for(auto & t : testcases){ + vector vec[3]; + vector list; + for(size_t i=0; inext = vec[1].rbegin()->next = list[2]; + print("headA=", list[0], "\n") + print("headB=", list[1], "\n") + ListNode * ans = NULL; + ans = sln.getIntersectionNode(list[0], list[1]); + print("ans:", ans, "\n\n") + } + return 0; +} \ No newline at end of file diff --git "a/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/solution.h" "b/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/solution.h" new file mode 100644 index 0000000..5300007 --- /dev/null +++ "b/questions/\345\211\221\346\214\207 Offer 52.\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\350\212\202\347\202\271/solution.h" @@ -0,0 +1,26 @@ +// @algorithm @lc id=100326 lang=cpp +// @title liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof + + +// #define print(...) +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +// (A=[4,1,8],B=[5,0,1,8],common=[4,5])=8 +class Solution { +public: + ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + auto pa = headA, pb = headB; + while(pa || pb){ + if(pa == pb) return pb; + pa = pa ? pa->next : headB; + pb = pb ? pb->next : headA; + } + return NULL; + } +}; \ No newline at end of file -- Gitee From c5547b0df17c118268fc58a22b809bb91d07e227 Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 21 Jul 2021 13:49:24 +0800 Subject: [PATCH 57/77] =?UTF-8?q?LC-232.=E7=94=A8=E6=A0=88=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 20 ++++++++ .../solution.h" | 51 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 "questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/main.cpp" create mode 100644 "questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/solution.h" diff --git a/README.md b/README.md index 16dd230..11cd798 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) + +[232. 用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks) ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/main.cpp" "b/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/main.cpp" new file mode 100644 index 0000000..723e346 --- /dev/null +++ "b/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" +#define test_out(sth) print("----", sth, "----", "\nin=", myQueue.in, "\nout=", myQueue.out, "\n") + + +int main(int argc, char *argv[]){ + MyQueue myQueue; + myQueue.push(1); // queue is: [1] + myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue) + test_out("push 1 2") + myQueue.peek(); // return 1 + test_out("peek") + myQueue.pop(); // return 1, queue is [2] + test_out("pop") + auto empty = myQueue.empty(); // return false + print("empty=") + test_out(empty) + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/solution.h" "b/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/solution.h" new file mode 100644 index 0000000..c0853f0 --- /dev/null +++ "b/questions/232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227/solution.h" @@ -0,0 +1,51 @@ +// @algorithm @lc id=232 lang=cpp +// @title implement-queue-using-stacks + + +/** + * Your MyQueue object will be instantiated and called as such: + * MyQueue* obj = new MyQueue(); + * obj->push(x); + * int param_2 = obj->pop(); + * int param_3 = obj->peek(); + * bool param_4 = obj->empty(); + */ +class MyQueue { +public: + list in, out; + /** Initialize your data structure here. */ + MyQueue() { + + } + + /** Push element x to the back of queue. */ + void push(int x) { + in.push_front(x); + } + + void tryOut(){ + if(!out.empty()) return; + while(!in.empty()){ + out.push_front(in.front()); + in.pop_front(); + } + } + /** Removes the element from in front of queue and returns that element. */ + int pop() { + tryOut(); + auto data = out.front(); + out.pop_front(); + return data; + } + + /** Get the front element. */ + int peek() { + tryOut(); + return out.front(); + } + + /** Returns whether the queue is empty. */ + bool empty() { + return out.empty() && in.empty(); + } +}; \ No newline at end of file -- Gitee From c431b18f296287964e7dad499cce6b5598fdc52b Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 21 Jul 2021 22:34:18 +0800 Subject: [PATCH 58/77] =?UTF-8?q?LC-225.=E7=94=A8=E9=98=9F=E5=88=97?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 20 ++++++ .../solution.h" | 63 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 "questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/main.cpp" create mode 100644 "questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/solution.h" diff --git a/README.md b/README.md index 11cd798..6aee496 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/) [232. 用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks) +## 队列 +[225. 用队列实现栈](https://leetcode-cn.com/problems/implement-stack-using-queues) ## 指针 [11. 盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/)「双指针」 diff --git "a/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/main.cpp" "b/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/main.cpp" new file mode 100644 index 0000000..de6b985 --- /dev/null +++ "b/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "solution.h" + +int main(int argc, char *argv[]){ + MyStack myStack; + /* + myStack.push(1); + myStack.push(2); + myStack.top(); // 返回 2 + myStack.pop(); // 返回 2 + myStack.empty(); // 返回 False + */ + myStack.push(1); + myStack.push(2); + myStack.top(); // 返回 2 + myStack.push(3); + myStack.top(); // 返回 3 + print("\n------ main exit ------\n") + return 0; +} diff --git "a/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/solution.h" "b/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/solution.h" new file mode 100644 index 0000000..bfe6cfd --- /dev/null +++ "b/questions/225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210/solution.h" @@ -0,0 +1,63 @@ +// @algorithm @lc id=225 lang=cpp +// @title implement-stack-using-queues + +#define print(...) +#define queue_t list +class MyStack { +public: + int out; + vector> q; + /** Initialize your data structure here. */ + MyStack():out(0){ + q.reserve(2); + q.assign(2, queue_t()); + } + + void tryOut(){ + while(q[1-out].size()>1) { + q[out].push_back(q[1-out].front()); + q[1-out].pop_front(); + } + out = 1 - out; + } + + /** Push element x onto stack. */ + void push(int x) { + q[1-out].push_back(x); + print("push(", x, ")|", out, "|", q, "\n") + } + + /** Removes the element on top of the stack and returns that element. */ + int pop() { + tryOut(); + auto data = q[out].front(); + q[out].pop_front(); + print("pop()=", data,"|", out, "|", q, "\n") + return data; + } + + /** Get the top element. */ + int top() { + tryOut(); + auto data = q[out].front(); + q[1-out].push_back(data); + q[out].pop_front(); + print("top()=", data, "|", out, "|", q, "\n") + return data; + } + + /** Returns whether the stack is empty. */ + bool empty() { + print("empty()=", q[1-out].empty() && q[out].empty(), "|", out, "|", q, "\n") + return q[1-out].empty() && q[out].empty(); + } +}; + +/** + * Your MyStack object will be instantiated and called as such: + * MyStack* obj = new MyStack(); + * obj->push(x); + * int param_2 = obj->pop(); + * int param_3 = obj->top(); + * bool param_4 = obj->empty(); + */ \ No newline at end of file -- Gitee From 7b76574bff83019da4174268761a00f5d9102bba Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 21 Jul 2021 23:42:23 +0800 Subject: [PATCH 59/77] =?UTF-8?q?LC-34.=E5=9C=A8=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 +++++++++++ .../solution.h" | 32 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 "questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/main.cpp" create mode 100644 "questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/solution.h" diff --git a/README.md b/README.md index 6aee496..fbfc64c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ [274. H 指数](https://leetcode-cn.com/problems/h-index/)「计数(桶)排序」 ## 查找 [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)「二分查找」 + +[34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array) ## 搜索 [17. 电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)「回溯」 diff --git "a/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/main.cpp" "b/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/main.cpp" new file mode 100644 index 0000000..6940bd3 --- /dev/null +++ "b/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[5,7,7,8,8,10]\",\"8\"],[\"[5,7,7,8,8,10]\",\"6\"],[\"[1]\",\"1\"],[\"[]\",\"0\"],[\"[2,2]\",\"2\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int arg1 = parseInteger(args[1]); + vector result=s->searchRange(arg0,arg1); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/solution.h" "b/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/solution.h" new file mode 100644 index 0000000..f1f3238 --- /dev/null +++ "b/questions/34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/solution.h" @@ -0,0 +1,32 @@ +// @algorithm @lc id=34 lang=cpp +// @title find-first-and-last-position-of-element-in-sorted-array + + +// #define print(...) +// @test([5,7,7,8,8,10],8)=[3,4] +// @test([5,7,7,8,8,10],6)=[-1,-1] +// @test([1],1)=[0,0] +// @test([],0)=[-1,-1] +// @test([2,2],2)=[0,1] +class Solution { +public: + vector searchRange(vector& nums, int target) { + if(nums.empty()) return {-1,-1}; + auto left = nums.begin(), right = nums.end() - 1; + // 1st index of target + while(left < right && *left != target){ + auto mid = left + (right-left)/2; + *mid < target? left = mid+1 : right = mid; + } + if(*left != target) + return {-1, -1}; + auto lb = left - nums.begin(); + // last index of value > target + right = nums.end()-1; + while(left < right && *right != target){ + auto mid = left + (right-left+1)/2; + target < *mid ? right = mid-1 : left = mid; + } + return {(int)lb, int(*right==target?right-nums.begin():lb)}; + } +}; \ No newline at end of file -- Gitee From ae0dc1369801aae3faf9c566fed0b8a309731f69 Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 23 Jul 2021 14:10:39 +0800 Subject: [PATCH 60/77] =?UTF-8?q?LC-1893.=E6=A3=80=E6=9F=A5=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E5=8C=BA=E5=9F=9F=E5=86=85=E6=89=80=E6=9C=89=E6=95=B4?= =?UTF-8?q?=E6=95=B0=E9=83=BD=E8=A2=AB=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++- .../main.cpp" | 20 ++++++++++++++ .../solution.h" | 27 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 "questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/main.cpp" create mode 100644 "questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/solution.h" diff --git a/README.md b/README.md index fbfc64c..fd58c33 100644 --- a/README.md +++ b/README.md @@ -100,4 +100,6 @@ [29. 两数相除](https://leetcode-cn.com/problems/divide-two-integers/) -[31. 下一个排列](https://leetcode-cn.com/problems/next-permutation) \ No newline at end of file +[31. 下一个排列](https://leetcode-cn.com/problems/next-permutation) + +[1893. 检查是否区域内所有整数都被覆盖](https://leetcode-cn.com/problems/check-if-all-the-integers-in-a-range-are-covered)「差分数组 , 前缀和」 \ No newline at end of file diff --git "a/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/main.cpp" "b/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/main.cpp" new file mode 100644 index 0000000..225aa88 --- /dev/null +++ "b/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[1,2],[3,4],[5,6]]\",\"2\",\"5\"],[\"[[1,10],[10,20]]\",\"21\",\"21\"],[\"[[1,50]]\",\"1\",\"50\"],[\"[[50,50]]\",\"1\",\"1\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseIntegerArrArr(args[0]); + int arg1 = parseInteger(args[1]); + int arg2 = parseInteger(args[2]); + bool result=s->isCovered(arg0,arg1,arg2); + string resultabc =serializeBool(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/solution.h" "b/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/solution.h" new file mode 100644 index 0000000..96f064f --- /dev/null +++ "b/questions/1893.\346\243\200\346\237\245\346\230\257\345\220\246\345\214\272\345\237\237\345\206\205\346\211\200\346\234\211\346\225\264\346\225\260\351\203\275\350\242\253\350\246\206\347\233\226/solution.h" @@ -0,0 +1,27 @@ +// @algorithm @lc id=2005 lang=cpp +// @title check-if-all-the-integers-in-a-range-are-covered + + +// #define print(...) +// @test([[1,2],[3,4],[5,6]],2,5)=true +// @test([[1,10],[10,20]],21,21)=false +// @test([[1,50]],1,50)=true +// @test([[50,50]], 1, 1)=false +class Solution { +public: +bool isCovered(vector>& ranges, int left, int right) { + // 差分数组 + vector diff(52, 0); + for(auto & r : ranges){ + diff[r[0]]++; // 开始覆盖+1 + diff[r[1]+1]--; // 不再覆盖-1 + } + // 前缀和 + int i=0; + while(++i=(diff[i-1] += diff[i-2])) + return false; + return true; +} +}; \ No newline at end of file -- Gitee From c7ca34e733e4b953a91b57d475c0b5972daacff2 Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 23 Jul 2021 21:07:28 +0800 Subject: [PATCH 61/77] =?UTF-8?q?LC-138.=E5=A4=8D=E5=88=B6=E5=B8=A6?= =?UTF-8?q?=E9=9A=8F=E6=9C=BA=E6=8C=87=E9=92=88=E7=9A=84=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../solution.h" | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 "questions/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250/solution.h" diff --git a/README.md b/README.md index fd58c33..03622a5 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,8 @@ [25. K 个一组翻转链表](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) [剑指 Offer 52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof) + +[138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer) ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250/solution.h" "b/questions/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250/solution.h" new file mode 100644 index 0000000..f1af55a --- /dev/null +++ "b/questions/138.\345\244\215\345\210\266\345\270\246\351\232\217\346\234\272\346\214\207\351\222\210\347\232\204\351\223\276\350\241\250/solution.h" @@ -0,0 +1,36 @@ +// @algorithm @lc id=138 lang=cpp +// @title copy-list-with-random-headinter + + +// #define print(...) +// #define ListNode Node +// #define parseListNode parseNode +// #define serializeListNode serializeNode +// @test([[7,null],[13,0],[11,4],[10,2],[1,0]])=[[7,null],[13,0],[11,4],[10,2],[1,0]] +// @test([[1,1],[2,1]])=[[1,1],[2,1]] +// @test([[3,null],[3,0],[3,null]])=[[3,null],[3,0],[3,null]] +// @test([])=[] +class Solution { +public: + Node* copyRandomList(Node* head) { + if(!head) return NULL; + Node ans(0), *pn = &ans; + map> rd; + while(head){ + pn->next = new Node(head->val); + pn = pn->next; + rd[head].push_front(pn); + if(head->random){ + auto it = rd.find(head->random); + if(it == rd.end()) + it = rd.insert({head->random, {}}).first; + it->second.push_back(pn); + } + head=head->next; + } + for(auto & r : rd) + for(auto it=r.second.begin(); ++it!=r.second.end();) + (*it)->random = *r.second.begin(); + return ans.next; + } +}; \ No newline at end of file -- Gitee From 0fd33ec91cac83191267e4b33d03ad8991a9eb7f Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 23 Jul 2021 23:30:48 +0800 Subject: [PATCH 62/77] =?UTF-8?q?LC-36.=E6=9C=89=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E7=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++- .../main.cpp" | 28 ++++++++++++++++ .../solution.h" | 33 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 "questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/main.cpp" create mode 100644 "questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/solution.h" diff --git a/README.md b/README.md index 03622a5..b148fc2 100644 --- a/README.md +++ b/README.md @@ -104,4 +104,6 @@ [31. 下一个排列](https://leetcode-cn.com/problems/next-permutation) -[1893. 检查是否区域内所有整数都被覆盖](https://leetcode-cn.com/problems/check-if-all-the-integers-in-a-range-are-covered)「差分数组 , 前缀和」 \ No newline at end of file +[1893. 检查是否区域内所有整数都被覆盖](https://leetcode-cn.com/problems/check-if-all-the-integers-in-a-range-are-covered)「差分数组 , 前缀和」 + +[36. 有效的数独](https://leetcode-cn.com/problems/valid-sudoku) \ No newline at end of file diff --git "a/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/main.cpp" "b/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/main.cpp" new file mode 100644 index 0000000..d98e03e --- /dev/null +++ "b/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/main.cpp" @@ -0,0 +1,28 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[\\\"5\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\"6\\\",\\\".\\\",\\\".\\\",\\\"1\\\",\\\"9\\\",\\\"5\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\".\\\",\\\"9\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\"],[\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"3\\\"],[\\\"4\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"1\\\"],[\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\"],[\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\"8\\\",\\\".\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\"4\\\",\\\"1\\\",\\\"9\\\",\\\".\\\",\\\".\\\",\\\"5\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\"9\\\"]]\"],[\"[[\\\"8\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\"6\\\",\\\".\\\",\\\".\\\",\\\"1\\\",\\\"9\\\",\\\"5\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\".\\\",\\\"9\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\"],[\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"3\\\"],[\\\"4\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"1\\\"],[\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\"],[\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\"8\\\",\\\".\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\"4\\\",\\\"1\\\",\\\"9\\\",\\\".\\\",\\\".\\\",\\\"5\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\"9\\\"]]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseStringArrArr(args[0]); + vector> test; + for(auto & vec : arg0){ + test.push_back(vector()); + auto & ts = *test.rbegin(); + for(auto & c : vec){ + ts.push_back(c[0]); + print(c[0], " "); + } + print("\n") + } + bool result=s->isValidSudoku(test); + string resultabc =serializeBool(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/solution.h" "b/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/solution.h" new file mode 100644 index 0000000..00affb3 --- /dev/null +++ "b/questions/36.\346\234\211\346\225\210\347\232\204\346\225\260\347\213\254/solution.h" @@ -0,0 +1,33 @@ +// @algorithm @lc id=36 lang=cpp +// @title valid-sudoku + + +#define print(...) +// @test([["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]])=true +// @test([["8","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]])=false +class Solution { +public: + bool isValidSudoku(vector>& board) { + auto n = board.size(); + vector>> ss(3, vector>(n, map())); + for(int i=0; i 1){ + print("[", i, "][", j, "]:row=", c, "\n") + return false; + } + if(++ss[1][j][c] > 1){ + print("[", i, "][", j, "]:col=", c, "\n") + return false; + } + if(++ss[2][i/3*3+j/3][c] > 1){ + print("[", i, "][", j, "]:box[", i/3*3+j/3, "]=", c, "\n") + return false; + } + } + } + return true; + } +}; \ No newline at end of file -- Gitee From 9a50c7baf05bc2b65df4f8a0032a876e6377a245 Mon Sep 17 00:00:00 2001 From: sudo Date: Fri, 23 Jul 2021 23:32:05 +0800 Subject: [PATCH 63/77] =?UTF-8?q?supperchong.algorithm-=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E8=A6=86=E7=9B=96main.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/supperchong.algorithm/out/lang/cpp.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/supperchong.algorithm/out/lang/cpp.js b/tools/supperchong.algorithm/out/lang/cpp.js index 7ae0c87..dd6ccbb 100644 --- a/tools/supperchong.algorithm/out/lang/cpp.js +++ b/tools/supperchong.algorithm/out/lang/cpp.js @@ -358,8 +358,11 @@ class CppParse extends base_1.BaseLang { yield this.ensureCommonModuleFile(); const finalCode = yield this.handleArgsType(argsStr); const testFilePath = this.getTestFilePath(); - yield fs_extra_1.ensureFile(testFilePath); - yield util_1.writeFileAsync(testFilePath, finalCode); + const isExist = yield fs_extra_1.pathExists(testFilePath); + if (!isExist) { + yield fs_extra_1.ensureFile(testFilePath); + yield util_1.writeFileAsync(testFilePath, finalCode); + } }); } getDebugConfig(_breaks) { -- Gitee From bf7a62a32ce923068ce6cfa552278dd74a203eef Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 24 Jul 2021 12:05:15 +0800 Subject: [PATCH 64/77] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b148fc2..034d314 100644 --- a/README.md +++ b/README.md @@ -106,4 +106,9 @@ [1893. 检查是否区域内所有整数都被覆盖](https://leetcode-cn.com/problems/check-if-all-the-integers-in-a-range-are-covered)「差分数组 , 前缀和」 -[36. 有效的数独](https://leetcode-cn.com/problems/valid-sudoku) \ No newline at end of file +[36. 有效的数独](https://leetcode-cn.com/problems/valid-sudoku) + +## 引用 +[Text to ASCII Art Generator](http://patorjk.com/software/taag/#p=display&f=Ogre&t=mud) + +[vscode extension: supperchong algorithm](https://github.com/supperchong/algorithm) \ No newline at end of file -- Gitee From be1a094c77ea0a9b561b2e22b898713fd2cb122b Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 25 Jul 2021 17:35:17 +0800 Subject: [PATCH 65/77] =?UTF-8?q?LC-1743.=E4=BB=8E=E7=9B=B8=E9=82=BB?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E5=AF=B9=E8=BF=98=E5=8E=9F=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 18 +++++++++ .../solution.h" | 39 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 "questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/main.cpp" create mode 100644 "questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/solution.h" diff --git a/README.md b/README.md index 034d314..7a20cf7 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ [剑指 Offer 52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof) [138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer) +## 图 +[1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/main.cpp" "b/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/main.cpp" new file mode 100644 index 0000000..1192b10 --- /dev/null +++ "b/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[2,1],[3,4],[3,2]]\"],[\"[[4,-2],[1,4],[-3,1]]\"],[\"[[100000,-100000]]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseIntegerArrArr(args[0]); + vector result=s->restoreArray(arg0); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/solution.h" "b/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/solution.h" new file mode 100644 index 0000000..76f3ae5 --- /dev/null +++ "b/questions/1743.\344\273\216\347\233\270\351\202\273\345\205\203\347\264\240\345\257\271\350\277\230\345\216\237\346\225\260\347\273\204/solution.h" @@ -0,0 +1,39 @@ +// @algorithm @lc id=1866 lang=cpp +// @title restore-the-array-from-adjacent-pairs + + +// #define print(...) +// @test([[2,1],[3,4],[3,2]])=[1,2,3,4] +// @test([[4,-2],[1,4],[-3,1]])=[-2,4,1,-3] +// @test([[100000,-100000]])=[100000,-100000] +using iterator = vector>::iterator; +class Solution { +public: + vector restoreArray(vector>& adjacentPairs){ + print("\npairs=", adjacentPairs, "\n") + size_t n = adjacentPairs.size(); + unordered_map> adjs; + for(auto & a : adjacentPairs){ + adjs[a[0]].push_back(a[1]); + adjs[a[1]].push_back(a[0]); + } + print("adjs=", adjs, "\n") + vector ans; + for(auto & [a,d] : adjs) + if(d.size()==1){ + ans.push_back(a); + ans.push_back(d[0]); + break; + } + while(ans.size() < n+1){ + for(auto & d : adjs[*ans.rbegin()]){ + if(*(ans.rbegin()+1) != d){ + ans.push_back(d); + break; + } + } + } + print("ans=", ans, "\n") + return ans; + } +}; \ No newline at end of file -- Gitee From 7b3f8bdd72fd4cdb6ee254e14a7c15be15e2fcb0 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 25 Jul 2021 23:42:52 +0800 Subject: [PATCH 66/77] =?UTF-8?q?LC-37.=E8=A7=A3=E6=95=B0=E7=8B=AC(?= =?UTF-8?q?=E6=9A=82=E5=AD=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main.cpp" | 35 ++++++++++++++++ .../solution.h" | 41 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 "questions/37.\350\247\243\346\225\260\347\213\254/main.cpp" create mode 100644 "questions/37.\350\247\243\346\225\260\347\213\254/solution.h" diff --git "a/questions/37.\350\247\243\346\225\260\347\213\254/main.cpp" "b/questions/37.\350\247\243\346\225\260\347\213\254/main.cpp" new file mode 100644 index 0000000..8ca5c29 --- /dev/null +++ "b/questions/37.\350\247\243\346\225\260\347\213\254/main.cpp" @@ -0,0 +1,35 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[\\\"5\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\"6\\\",\\\".\\\",\\\".\\\",\\\"1\\\",\\\"9\\\",\\\"5\\\",\\\".\\\",\\\".\\\",\\\".\\\"],[\\\".\\\",\\\"9\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\"],[\\\"8\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"3\\\"],[\\\"4\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\"3\\\",\\\".\\\",\\\".\\\",\\\"1\\\"],[\\\"7\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"6\\\"],[\\\".\\\",\\\"6\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"2\\\",\\\"8\\\",\\\".\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\"4\\\",\\\"1\\\",\\\"9\\\",\\\".\\\",\\\".\\\",\\\"5\\\"],[\\\".\\\",\\\".\\\",\\\".\\\",\\\".\\\",\\\"8\\\",\\\".\\\",\\\".\\\",\\\"7\\\",\\\"9\\\"]]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseStringArrArr(args[0]); + vector> test; + print("=========================\n") + for(auto & vec : arg0){ + test.push_back(vector()); + auto & ts = *test.rbegin(); + for(auto & c : vec){ + ts.push_back(c[0]); + print(c[0], " "); + } + print("\n") + } + print("-------------------------\n") + s->solveSudoku(test); + for(auto & res : test){ + for(auto & c : res) + print(c, " "); + print("\n") + } + string resultabc =serializeStringArrArr(arg0); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" "b/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" new file mode 100644 index 0000000..2c45ad8 --- /dev/null +++ "b/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" @@ -0,0 +1,41 @@ +// @algorithm @lc id=37 lang=cpp +// @title sudoku-solver + + +// #define print(...) +// @test([["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]])=[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] +#define BOX(i,j) box[(i)/3*3+(j)/3] +#define FLIP(i,j,bit) row[i] ^= 1<<(bit),col[j] ^= 1<<(bit),BOX((i),(j)) ^= 1<<(bit) +#define CHOICES(i,j) ((~(BOX((i),(j)) | row[i] | col[j])) & 0x1FF) +#define CHOICES_CNT(i,j)__builtin_popcount(CHOICES((i),(j))) +#define LAST_CHOICE(m) ((m) & -(m)) +class Solution { +public: + void solveSudoku(vector>& board) { + int row[9]={0}, col[9]={0}, box[9]={0}; + vector> blanks; + for(int i=0; ipair{ + int cntChoices = 10, r=0, c=0; + for(auto & [i,j] : blanks){ + int n = CHOICES_CNT(i,j); + if(n < cntChoices) + r = i, c = j; + if(n == 1) break; + } + return {r,c}; + }; + } +}; \ No newline at end of file -- Gitee From 93e0ee5592a427fa0e55a7a307cf2477243fabd0 Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 26 Jul 2021 22:23:08 +0800 Subject: [PATCH 67/77] =?UTF-8?q?LC-1713.=E5=BE=97=E5=88=B0=E5=AD=90?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E7=9A=84=E6=9C=80=E5=B0=91=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 ++++++++++++++ .../solution.h" | 26 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 "questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/main.cpp" create mode 100644 "questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/solution.h" diff --git a/README.md b/README.md index 7a20cf7..b74b305 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ [12. 整数转罗马数字](https://leetcode-cn.com/problems/integer-to-roman/) +[1713. 得到子序列的最少操作次数](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence) + [1846. 减小和重新排列数组后的最大元素](https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging) ## 动态规则 [5. 最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) diff --git "a/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/main.cpp" "b/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/main.cpp" new file mode 100644 index 0000000..b50629b --- /dev/null +++ "b/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[5,1,3]\",\"[9,4,2,3,4]\"],[\"[6,4,8,1,3,2]\",\"[4,7,6,2,3,8,6,1]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + vector arg1 = parseIntegerArr(args[1]); + int result=s->minOperations(arg0,arg1); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/solution.h" "b/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/solution.h" new file mode 100644 index 0000000..9c7e414 --- /dev/null +++ "b/questions/1713.\345\276\227\345\210\260\345\255\220\345\272\217\345\210\227\347\232\204\346\234\200\345\260\221\346\223\215\344\275\234\346\254\241\346\225\260/solution.h" @@ -0,0 +1,26 @@ +// @algorithm @lc id=1832 lang=cpp +// @title minimum-operations-to-make-a-subsequence + + +// #define print(...) +// @test([5,1,3],[9,4,2,3,4])=2 +// @test([6,4,8,1,3,2],[4,7,6,2,3,8,6,1])=3 +class Solution { +public: + int minOperations(vector& target, vector& arr) { + unordered_map ti; // + for(int i=0; i ai; // target 各值在 arr 中的索引(升序) + for(auto & a : arr){ + auto tx = ti.find(a); + if(tx == ti.end()) continue; + auto ax = lower_bound(ai.begin(), ai.end(), tx->second); + if(ax != ai.end()) + *ax = tx->second; + else + ai.push_back(tx->second); + } + return target.size() - ai.size(); + } +}; \ No newline at end of file -- Gitee From 6a99c385400e5f936df31604679c0ab9f1868998 Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 26 Jul 2021 22:30:33 +0800 Subject: [PATCH 68/77] =?UTF-8?q?LC-300.=E6=9C=80=E9=95=BF=E9=80=92?= =?UTF-8?q?=E5=A2=9E=E5=AD=90=E5=BA=8F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 +++++++++++++++ .../solution.h" | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 "questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/main.cpp" create mode 100644 "questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/solution.h" diff --git a/README.md b/README.md index b74b305..0323ce3 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ [12. 整数转罗马数字](https://leetcode-cn.com/problems/integer-to-roman/) +[300. 最长递增子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence) + [1713. 得到子序列的最少操作次数](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence) [1846. 减小和重新排列数组后的最大元素](https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging) diff --git "a/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/main.cpp" "b/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/main.cpp" new file mode 100644 index 0000000..cadb12f --- /dev/null +++ "b/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[10,9,2,5,3,7,101,18]\"],[\"[0,1,0,3,2,3]\"],[\"[7,7,7,7,7,7,7]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int result=s->lengthOfLIS(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/solution.h" "b/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/solution.h" new file mode 100644 index 0000000..0662915 --- /dev/null +++ "b/questions/300.\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227/solution.h" @@ -0,0 +1,22 @@ +// @algorithm @lc id=300 lang=cpp +// @title longest-increasing-subsequence + + +// #define print(...) +// @test([10,9,2,5,3,7,101,18])=4 +// @test([0,1,0,3,2,3])=4 +// @test([7,7,7,7,7,7,7])=1 +class Solution { +public: + int lengthOfLIS(vector& nums) { + vector asc; + for(auto & a : nums){ + auto ax = lower_bound(asc.begin(), asc.end(), a); + if(ax == asc.end()) + asc.push_back(a); + else + *ax = a; + } + return asc.size(); + } +}; \ No newline at end of file -- Gitee From 61e2def2a65883947840a60d1f98494e7535d30d Mon Sep 17 00:00:00 2001 From: sudo Date: Tue, 27 Jul 2021 09:43:28 +0800 Subject: [PATCH 69/77] =?UTF-8?q?LC-671.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E4=B8=AD=E7=AC=AC=E4=BA=8C=E5=B0=8F=E7=9A=84=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 ++++++++++ .../solution.h" | 35 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 "questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/main.cpp" create mode 100644 "questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/solution.h" diff --git a/README.md b/README.md index 0323ce3..5ce7297 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ [剑指 Offer 52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof) [138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer) +## 树 +[671. 二叉树中第二小的节点](https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree) ## 图 [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) ## 代数 diff --git "a/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/main.cpp" "b/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/main.cpp" new file mode 100644 index 0000000..4b70451 --- /dev/null +++ "b/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[2,2,5,null,null,5,7]\"],[\"[2,2,2]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + TreeNode * arg0 = parseTreeNode(args[0]); + int result=s->findSecondMinimumValue(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/solution.h" "b/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/solution.h" new file mode 100644 index 0000000..f9cbdbc --- /dev/null +++ "b/questions/671.\344\272\214\345\217\211\346\240\221\344\270\255\347\254\254\344\272\214\345\260\217\347\232\204\350\212\202\347\202\271/solution.h" @@ -0,0 +1,35 @@ +// @algorithm @lc id=671 lang=cpp +// @title second-minimum-node-in-a-binary-tree + + +// #define print(...) +// @test([2,2,5,null,null,5,7])=5 +// @test([2,2,2])=-1 +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int ans = -1; + int findSecondMinimumValue(TreeNode* root) { + if(!root) return ans; + if(root->left && root->right && root->left->val != root->right->val){ + auto big = root->left, small = root->right; + if(root->left->val < root->right->val) swap(big,small); + ans = ans == -1 ? big->val : min(ans, big->val); + findSecondMinimumValue(small); + }else{ + findSecondMinimumValue(root->left); + findSecondMinimumValue(root->right); + } + return ans; + } +}; \ No newline at end of file -- Gitee From 1f3b1daf912ca62caf944d3cd4f717f5c1cda9ae Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 28 Jul 2021 14:47:19 +0800 Subject: [PATCH 70/77] =?UTF-8?q?LC-863.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E4=B8=AD=E6=89=80=E6=9C=89=E8=B7=9D=E7=A6=BB=E4=B8=BA=20K=20?= =?UTF-8?q?=E7=9A=84=E7=BB=93=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 20 +++++++++ .../solution.h" | 42 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 "questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/main.cpp" create mode 100644 "questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/solution.h" diff --git a/README.md b/README.md index 5ce7297..36e1283 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ [138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer) ## 树 [671. 二叉树中第二小的节点](https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree) + +[863. 二叉树中所有距离为 K 的结点](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree) ## 图 [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) ## 代数 diff --git "a/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/main.cpp" "b/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/main.cpp" new file mode 100644 index 0000000..c1dbeea --- /dev/null +++ "b/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[3,5,1,6,2,0,8,null,null,7,4]\",\"5\",\"2\"],[\"[1]\",\"1\",\"3\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + TreeNode * arg0 = parseTreeNode(args[0]); + TreeNode * arg1 = new TreeNode(parseInteger(args[1])); + int arg2 = parseInteger(args[2]); + vector result=s->distanceK(arg0,arg1,arg2); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/solution.h" "b/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/solution.h" new file mode 100644 index 0000000..b89eab6 --- /dev/null +++ "b/questions/863.\344\272\214\345\217\211\346\240\221\344\270\255\346\211\200\346\234\211\350\267\235\347\246\273\344\270\272 K \347\232\204\347\273\223\347\202\271/solution.h" @@ -0,0 +1,42 @@ +// @algorithm @lc id=893 lang=cpp +// @title all-nodes-distance-k-in-binary-tree + + +// #define print(...) +// @test([3,5,1,6,2,0,8,null,null,7,4],5,2)=[7,4,1] +// @test([1],1,3)=[] +class Solution { +public: + vector distanceK(TreeNode* root, TreeNode* target, int k) { + // record parents + unordered_map parents; + parents[root->val] = NULL; + print("target(", target, ")=", target->val, "\ntree=") + function IsParent = [&](TreeNode* node){ + print(node?(node->val==target->val?"["+to_string(node->val)+"]":to_string(node->val)):"-1", " ") + if(!node) return; + print(node->val==target->val ? (target=node,""):"") + for(auto &p:{node->left, node->right}){ + print(!p ? "-1 " : "") + if(!p) continue; + parents[p->val] = node; + IsParent(p); + } + }; + IsParent(root); + print("\ntarget(", target, ")=", target->val, ", k=", k, "\n") + // walk k from target to: left, right, parent + vector ans; + function dfs = [&](TreeNode*from, TreeNode*cur, int dist){ + if(dist == k){ + print("from:", from->val, ", cur:", cur->val, "\n") + ans.push_back(cur->val); + return; + } + for(auto&p:{cur->left, cur->right, parents[cur->val]}) + if(p && p!=from) dfs(cur, p, 1+dist); + }; + dfs(NULL, target, 0); + return ans; + } +}; \ No newline at end of file -- Gitee From 9368bb3e06e5eefde7f7edb208e38a3761cb6147 Mon Sep 17 00:00:00 2001 From: sudo Date: Thu, 29 Jul 2021 23:19:17 +0800 Subject: [PATCH 71/77] =?UTF-8?q?LC-1104.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E5=AF=BB=E8=B7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 +++++++++++++++ .../solution.h" | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 "questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/main.cpp" create mode 100644 "questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/solution.h" diff --git a/README.md b/README.md index 36e1283..37c8cf4 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ [671. 二叉树中第二小的节点](https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree) [863. 二叉树中所有距离为 K 的结点](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree) + +[1104. 二叉树寻路](https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree) ## 图 [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) ## 代数 diff --git "a/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/main.cpp" "b/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/main.cpp" new file mode 100644 index 0000000..948acd4 --- /dev/null +++ "b/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"14\"],[\"26\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + int arg0 = parseInteger(args[0]); + vector result=s->pathInZigZagTree(arg0); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/solution.h" "b/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/solution.h" new file mode 100644 index 0000000..4a20b36 --- /dev/null +++ "b/questions/1104.\344\272\214\345\217\211\346\240\221\345\257\273\350\267\257/solution.h" @@ -0,0 +1,22 @@ +// @algorithm @lc id=1194 lang=cpp +// @title path-in-zigzag-labelled-binary-tree + + +#define print(...) +// @test(14)=[1,3,4,14] +// @test(26)=[1,2,6,10,26] +class Solution { +public: + vector pathInZigZagTree(int label) { + int d = 1; + while(d <= label) d <<= 1; + d = __builtin_ctz(d); + vector ans(d); + for(--d; ans[d]=label,0>1 : (1<<(d-1))*3-1-(label>>1); + } + print("label=", label, ", d=", d, ", ans=", ans, "\n") + return ans; + } +}; \ No newline at end of file -- Gitee From 89831f4546d7b9608e63d66d96a3a415696cc6f7 Mon Sep 17 00:00:00 2001 From: sudo Date: Sat, 31 Jul 2021 14:42:16 +0800 Subject: [PATCH 72/77] =?UTF-8?q?LC-987.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E5=9E=82=E5=BA=8F=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 18 ++++++++ .../solution.h" | 44 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 "questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/main.cpp" create mode 100644 "questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/solution.h" diff --git a/README.md b/README.md index 37c8cf4..0eb5b84 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ [863. 二叉树中所有距离为 K 的结点](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree) [1104. 二叉树寻路](https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree) + +[987. 二叉树的垂序遍历](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree) ## 图 [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) ## 代数 diff --git "a/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/main.cpp" "b/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/main.cpp" new file mode 100644 index 0000000..6dd9cd2 --- /dev/null +++ "b/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[3,9,20,null,null,15,7]\"],[\"[1,2,3,4,5,6,7]\"],[\"[1,2,3,4,6,5,7]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + TreeNode * arg0 = parseTreeNode(args[0]); + vector> result=s->verticalTraversal(arg0); + string resultabc =serializeIntegerArrArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/solution.h" "b/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/solution.h" new file mode 100644 index 0000000..ebe1efe --- /dev/null +++ "b/questions/987.\344\272\214\345\217\211\346\240\221\347\232\204\345\236\202\345\272\217\351\201\215\345\216\206/solution.h" @@ -0,0 +1,44 @@ +// @algorithm @lc id=1029 lang=cpp +// @title vertical-order-traversal-of-a-binary-tree + + +// #define print(...) +// @test([3,9,20,null,null,15,7])=[[9],[3,15],[20],[7]] +// @test([1,2,3,4,5,6,7])=[[4],[2],[1,5,6],[3],[7]] +// @test([1,2,3,4,6,5,7])=[[4],[2],[1,5,6],[3],[7]] +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + vector> verticalTraversal(TreeNode* root) { + vector> list; // + function dfs = + [&](TreeNode*node,int col,int row){ + if(!node) return; + list.emplace_back(col, row, node->val); + if(node->left) dfs(node->left, col-1, row+1); + if(node->right)dfs(node->right,col+1, row+1); + }; + dfs(root, 0, 0); + sort(list.begin(), list.end()); + vector> ans; + int cur_col = INT_MIN; + for(auto & [col, row, val] : list){ + if(cur_col != col){ + cur_col = col; + ans.push_back({}); + } + ans.back().emplace_back(val); + } + return ans; + } +}; \ No newline at end of file -- Gitee From f8462ebc61ac08c89b11a0652f89eae04d2d6092 Mon Sep 17 00:00:00 2001 From: sudo Date: Sun, 1 Aug 2021 22:31:07 +0800 Subject: [PATCH 73/77] =?UTF-8?q?LC-1337.=E7=9F=A9=E9=98=B5=E4=B8=AD?= =?UTF-8?q?=E6=88=98=E6=96=97=E5=8A=9B=E6=9C=80=E5=BC=B1=E7=9A=84K?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 19 +++++++++++ .../solution.h" | 32 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 "questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/main.cpp" create mode 100644 "questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/solution.h" diff --git a/README.md b/README.md index 0eb5b84..930e4d8 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)「二分查找」 [34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array) + +[1337. 矩阵中战斗力最弱的 K 行](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix) ## 搜索 [17. 电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)「回溯」 diff --git "a/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/main.cpp" "b/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/main.cpp" new file mode 100644 index 0000000..0a79a89 --- /dev/null +++ "b/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/main.cpp" @@ -0,0 +1,19 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[1,1,0,0,0],[1,1,1,1,0],[1,0,0,0,0],[1,1,0,0,0],[1,1,1,1,1]]\",\"3\"],[\"[[1,0,0,0],[1,1,1,1],[1,0,0,0],[1,0,0,0]]\",\"2\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseIntegerArrArr(args[0]); + int arg1 = parseInteger(args[1]); + vector result=s->kWeakestRows(arg0,arg1); + string resultabc =serializeIntegerArr(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/solution.h" "b/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/solution.h" new file mode 100644 index 0000000..4dd9590 --- /dev/null +++ "b/questions/1337.\347\237\251\351\230\265\344\270\255\346\210\230\346\226\227\345\212\233\346\234\200\345\274\261\347\232\204 K \350\241\214/solution.h" @@ -0,0 +1,32 @@ +// @algorithm @lc id=1463 lang=cpp +// @title the-k-weakest-rows-in-a-matrix + + +// @test([[1,1,0,0,0],[1,1,1,1,0],[1,0,0,0,0],[1,1,0,0,0],[1,1,1,1,1]],3)=[2,0,3] +// @test([[1,0,0,0],[1,1,1,1],[1,0,0,0],[1,0,0,0]],2)=[0,2] +class Solution { +public: + vector kWeakestRows(vector>& mat, int k) { + // 二分查找 0 的index,即1的个数 + function)> bs0 = [&](vector ln){ + int b = 0, e = (int)ln.size(); + while(b < e){ + auto m = b + (e-b)/2; + ln[m] ? b=m+1 : e = m; + } + return b; + }; + // multimap<1的个数, matIdx> + multimap cnt; + for(int i=0; i<(int)mat.size(); i++) + cnt.insert({bs0(mat[i]), i}); + // 取最小 k 个 + vector ans; + ans.reserve(k); + for(auto &[n,i] : cnt){ + ans.push_back(i); + if(ans.size()==k)break; + } + return ans; + } +}; \ No newline at end of file -- Gitee From 5cf9a25ed9546a51ca216c2668fde93b3c0965fb Mon Sep 17 00:00:00 2001 From: sudo Date: Mon, 2 Aug 2021 19:03:19 +0800 Subject: [PATCH 74/77] =?UTF-8?q?LC-743.=E7=BD=91=E7=BB=9C=E5=BB=B6?= =?UTF-8?q?=E8=BF=9F=E6=97=B6=E9=97=B4=E3=80=8CDijkstra=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../main.cpp" | 20 +++++++ .../solution.h" | 58 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 "questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/main.cpp" create mode 100644 "questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/solution.h" diff --git a/README.md b/README.md index 930e4d8..31f4b92 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,8 @@ [987. 二叉树的垂序遍历](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree) ## 图 [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs) + +[743. 网络延迟时间](https://leetcode-cn.com/problems/network-delay-time) ## 代数 [7. 整数反转](https://leetcode-cn.com/problems/reverse-integer/) diff --git "a/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/main.cpp" "b/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/main.cpp" new file mode 100644 index 0000000..f611bc1 --- /dev/null +++ "b/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/main.cpp" @@ -0,0 +1,20 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[[2,1,1],[2,3,1],[3,4,1]]\",\"4\",\"2\"],[\"[[1,2,1]]\",\"2\",\"1\"],[\"[[1,2,1]]\",\"2\",\"2\"],[\"[[1,2,1],[2,3,2],[1,3,1]]\",\"3\",\"2\"],[\"[[1,2,1],[2,3,7],[1,3,4],[2,1,2]]\",\"4\",\"1\"],[\"[[3,5,78],[2,1,1],[1,3,0],[4,3,59],[5,3,85],[5,2,22],[2,4,23],[1,4,43],[4,5,75],[5,1,15],[1,5,91],[4,1,16],[3,2,98],[3,4,22],[5,4,31],[1,2,0],[2,5,4],[4,2,51],[3,1,36],[2,3,59]]\",\"5\",\"5\"],[\"[[2,4,10],[5,2,38],[3,4,33],[4,2,76],[3,2,64],[1,5,54],[1,4,98],[2,3,61],[2,1,0],[3,5,77],[5,1,34],[3,1,79],[5,3,2],[1,2,59],[4,3,46],[5,4,44],[2,5,89],[4,5,21],[1,3,86],[4,1,95]]\",\"5\",\"1\"],[\"[[14,1,8],[11,2,25],[14,15,37],[3,7,70],[11,7,60],[13,11,87],[15,10,67],[13,10,58],[5,4,56],[9,3,26],[5,11,51],[11,4,92],[7,6,8],[7,10,95],[14,9,0],[4,13,1],[7,9,89],[3,14,24],[11,15,30],[13,2,91],[15,8,60],[1,4,96],[8,2,71],[6,8,38],[14,13,46],[2,12,48],[10,11,92],[8,12,28],[8,7,12],[9,13,82],[8,6,27],[3,2,65],[4,10,62],[11,13,55],[1,2,52],[8,3,98],[7,12,85],[6,12,97],[9,4,90],[2,4,23],[9,11,20],[1,14,61],[8,9,77],[6,5,80],[14,11,33],[9,8,54],[13,1,42],[13,8,13],[10,14,40],[9,7,18],[14,3,50],[14,6,83],[14,8,14],[2,1,86],[9,5,54],[11,5,29],[9,12,43],[9,2,74],[14,4,87],[12,7,98],[7,14,13],[4,12,33],[5,2,60],[15,11,33],[8,4,99],[9,6,98],[4,6,57],[6,11,5],[9,15,37],[1,3,30],[9,10,60],[13,12,73],[13,14,56],[1,11,13],[14,2,8],[4,15,60],[11,3,90],[2,5,86],[11,1,1],[13,4,2],[15,7,91],[15,4,51],[11,6,70],[2,7,51],[11,9,37],[4,2,92],[10,4,4],[7,2,30],[13,9,79],[8,15,41],[11,8,18],[15,2,4],[12,14,88],[12,6,9],[12,9,44],[1,6,87],[15,14,42],[4,9,41],[7,15,90],[4,1,84],[7,11,9],[3,11,75],[5,9,2],[2,11,96],[12,5,89],[6,15,25],[5,13,7],[15,5,32],[13,5,84],[7,5,9],[15,3,14],[12,13,4],[5,3,73],[6,9,85],[6,10,29],[1,8,24],[12,3,85],[4,3,60],[1,13,6],[1,5,58],[2,3,29],[14,5,67],[13,15,70],[5,14,94],[15,1,95],[3,1,17],[10,2,6],[11,10,44],[9,14,62],[4,11,32],[15,13,48],[2,10,77],[3,13,90],[5,7,68],[10,6,78],[3,6,95],[10,12,68],[13,6,73],[10,1,8],[10,7,18],[10,5,64],[5,1,55],[13,7,90],[1,9,67],[3,12,76],[14,10,22],[12,8,83],[4,7,76],[8,13,25],[5,6,57],[13,3,90],[6,2,96],[11,14,61],[12,1,94],[12,15,12],[4,8,88],[4,14,27],[7,4,25],[3,9,57],[2,15,90],[1,12,85],[12,11,44],[5,10,13],[5,12,96],[14,7,24],[14,12,98],[10,9,36],[15,6,17],[8,10,11],[2,13,5],[10,3,78],[6,13,11],[5,15,34],[12,10,12],[9,1,68],[10,13,1],[7,13,86],[1,7,62],[2,14,53],[8,14,75],[2,6,49],[10,15,83],[7,8,88],[6,1,87],[8,1,38],[8,11,73],[3,15,1],[3,8,93],[2,8,26],[4,5,26],[3,4,58],[7,1,55],[7,3,84],[5,8,97],[12,4,42],[6,3,71],[6,7,48],[15,12,3],[1,15,30],[10,8,11],[2,9,49],[6,14,9,5],[3,10,68],[6,4,14],[11,12,29],[1,10,93],[8,5,55],[12,2,86],[3,5,26],[15,9,12]]\",\"15\",\"11\"],[\"[[10,9,79],[15,10,58],[14,4,99],[14,12,29],[12,15,26],[1,15,78],[2,11,88],[7,3,4],[3,1,52],[11,3,91],[11,12,11],[5,10,81],[1,7,44],[12,13,52],[3,14,83],[10,4,26],[5,9,72],[5,14,32],[13,10,32],[15,6,2],[3,9,18],[1,11,45],[5,8,98],[7,13,33],[1,2,59],[4,11,79],[11,1,12],[8,5,79],[2,14,93],[3,6,53],[11,10,40],[14,2,33],[4,9,61],[3,8,10],[10,7,1],[8,3,58],[1,12,20],[5,1,51],[7,1,37],[9,7,34],[9,10,48],[8,4,90],[12,1,92],[6,4,99],[2,15,3],[2,3,80],[2,4,60],[15,14,75],[2,7,20],[15,8,20],[5,12,19],[13,3,74],[7,5,6],[9,6,73],[9,14,49],[15,1,56],[8,2,10],[7,9,9],[12,5,67],[6,3,29],[9,4,38],[6,9,42],[5,3,57],[3,2,48],[12,6,77],[10,15,15],[12,4,68],[14,1,52],[13,4,80],[4,1,84],[14,10,68],[2,12,81],[2,1,31],[6,14,52],[7,8,68],[4,12,73],[8,14,88],[13,5,92],[6,1,3],[9,11,80],[3,15,23],[15,4,84],[5,11,41],[7,11,42],[11,7,86],[9,15,63],[1,4,36],[3,13,82],[6,15,91],[13,6,64],[14,11,32],[11,5,68],[6,5,55],[4,5,35],[13,1,1],[4,10,47],[12,9,1],[7,10,44],[3,7,23],[8,12,68],[8,6,13],[2,9,19],[10,6,91],[7,12,80],[8,7,12],[4,7,4],[9,2,67],[14,9,29],[15,13,80],[6,8,62],[15,12,36],[1,3,48],[2,10,67],[9,13,55],[11,6,62],[8,11,92],[13,15,30],[4,13,97],[5,4,25],[4,2,9],[15,5,5],[15,2,45],[10,8,23],[14,5,43],[5,13,98],[14,13,73],[4,8,29],[10,5,0],[11,13,68],[9,12,91],[12,2,56],[9,1,23],[14,6,80],[9,5,10],[12,11,89],[5,15,94],[7,2,20],[3,12,89],[2,13,9],[11,2,1],[10,13,85],[6,10,76],[1,10,2],[14,15,20],[3,11,15],[11,8,62],[12,7,63],[8,15,91],[8,10,30],[12,3,80],[5,7,94],[13,2,60],[14,8,77],[10,12,67],[13,8,9],[13,11,48],[5,6,77],[10,3,51],[4,15,84],[13,12,10],[13,14,28],[4,6,46],[3,10,53],[14,7,48],[10,11,21],[15,11,99],[12,10,93],[11,14,73],[15,3,81],[2,5,22],[12,8,20],[6,13,24],[8,13,41],[8,9,98],[2,6,98],[7,15,27],[6,11,15],[7,14,72],[10,14,96],[1,8,18],[1,6,2],[3,4,78],[4,3,10],[11,4,54],[12,14,40],[3,5,63],[10,2,94],[1,9,57],[6,12,12],[9,8,37],[8,1,77],[13,7,80],[10,1,25],[9,3,37],[4,14,28],[1,13,88],[1,5,45],[7,4,65],[6,2,19],[11,15,37],[7,6,90],[2,8,1],[1,14,63],[5,2,47],[15,9,34],[11,9,41],[15,7,90],[13,9,45],[14,3,34],[6,7,44]]\",\"15\",\"9\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector> arg0 = parseIntegerArrArr(args[0]); + int arg1 = parseInteger(args[1]); + int arg2 = parseInteger(args[2]); + int result=s->networkDelayTime(arg0,arg1,arg2); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/solution.h" "b/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/solution.h" new file mode 100644 index 0000000..a1e633e --- /dev/null +++ "b/questions/743.\347\275\221\347\273\234\345\273\266\350\277\237\346\227\266\351\227\264/solution.h" @@ -0,0 +1,58 @@ +// @algorithm @lc id=744 lang=cpp +// @title network-delay-time + + +#define print(...) +// @test([[2,1,1],[2,3,1],[3,4,1]],4,2)=2 +// @test([[1,2,1]],2,1)=1 +// @test([[1,2,1]],2,2)=-1 +// @test([[1,2,1],[2,3,2],[1,3,1]],3,2)=-1 +// @test([[1,2,1],[2,3,7],[1,3,4],[2,1,2]], 4, 1)=-1 +// @test([[3,5,78],[2,1,1],[1,3,0],[4,3,59],[5,3,85],[5,2,22],[2,4,23],[1,4,43],[4,5,75],[5,1,15],[1,5,91],[4,1,16],[3,2,98],[3,4,22],[5,4,31],[1,2,0],[2,5,4],[4,2,51],[3,1,36],[2,3,59]], 5, 5)=31 +// @test([[2,4,10],[5,2,38],[3,4,33],[4,2,76],[3,2,64],[1,5,54],[1,4,98],[2,3,61],[2,1,0],[3,5,77],[5,1,34],[3,1,79],[5,3,2],[1,2,59],[4,3,46],[5,4,44],[2,5,89],[4,5,21],[1,3,86],[4,1,95]], 5, 1)=69 +// @test([[14,1,8],[11,2,25],[14,15,37],[3,7,70],[11,7,60],[13,11,87],[15,10,67],[13,10,58],[5,4,56],[9,3,26],[5,11,51],[11,4,92],[7,6,8],[7,10,95],[14,9,0],[4,13,1],[7,9,89],[3,14,24],[11,15,30],[13,2,91],[15,8,60],[1,4,96],[8,2,71],[6,8,38],[14,13,46],[2,12,48],[10,11,92],[8,12,28],[8,7,12],[9,13,82],[8,6,27],[3,2,65],[4,10,62],[11,13,55],[1,2,52],[8,3,98],[7,12,85],[6,12,97],[9,4,90],[2,4,23],[9,11,20],[1,14,61],[8,9,77],[6,5,80],[14,11,33],[9,8,54],[13,1,42],[13,8,13],[10,14,40],[9,7,18],[14,3,50],[14,6,83],[14,8,14],[2,1,86],[9,5,54],[11,5,29],[9,12,43],[9,2,74],[14,4,87],[12,7,98],[7,14,13],[4,12,33],[5,2,60],[15,11,33],[8,4,99],[9,6,98],[4,6,57],[6,11,5],[9,15,37],[1,3,30],[9,10,60],[13,12,73],[13,14,56],[1,11,13],[14,2,8],[4,15,60],[11,3,90],[2,5,86],[11,1,1],[13,4,2],[15,7,91],[15,4,51],[11,6,70],[2,7,51],[11,9,37],[4,2,92],[10,4,4],[7,2,30],[13,9,79],[8,15,41],[11,8,18],[15,2,4],[12,14,88],[12,6,9],[12,9,44],[1,6,87],[15,14,42],[4,9,41],[7,15,90],[4,1,84],[7,11,9],[3,11,75],[5,9,2],[2,11,96],[12,5,89],[6,15,25],[5,13,7],[15,5,32],[13,5,84],[7,5,9],[15,3,14],[12,13,4],[5,3,73],[6,9,85],[6,10,29],[1,8,24],[12,3,85],[4,3,60],[1,13,6],[1,5,58],[2,3,29],[14,5,67],[13,15,70],[5,14,94],[15,1,95],[3,1,17],[10,2,6],[11,10,44],[9,14,62],[4,11,32],[15,13,48],[2,10,77],[3,13,90],[5,7,68],[10,6,78],[3,6,95],[10,12,68],[13,6,73],[10,1,8],[10,7,18],[10,5,64],[5,1,55],[13,7,90],[1,9,67],[3,12,76],[14,10,22],[12,8,83],[4,7,76],[8,13,25],[5,6,57],[13,3,90],[6,2,96],[11,14,61],[12,1,94],[12,15,12],[4,8,88],[4,14,27],[7,4,25],[3,9,57],[2,15,90],[1,12,85],[12,11,44],[5,10,13],[5,12,96],[14,7,24],[14,12,98],[10,9,36],[15,6,17],[8,10,11],[2,13,5],[10,3,78],[6,13,11],[5,15,34],[12,10,12],[9,1,68],[10,13,1],[7,13,86],[1,7,62],[2,14,53],[8,14,75],[2,6,49],[10,15,83],[7,8,88],[6,1,87],[8,1,38],[8,11,73],[3,15,1],[3,8,93],[2,8,26],[4,5,26],[3,4,58],[7,1,55],[7,3,84],[5,8,97],[12,4,42],[6,3,71],[6,7,48],[15,12,3],[1,15,30],[10,8,11],[2,9,49],[6,14,9,5],[3,10,68],[6,4,14],[11,12,29],[1,10,93],[8,5,55],[12,2,86],[3,5,26],[15,9,12]],15,11)=38 +// @test([[10,9,79],[15,10,58],[14,4,99],[14,12,29],[12,15,26],[1,15,78],[2,11,88],[7,3,4],[3,1,52],[11,3,91],[11,12,11],[5,10,81],[1,7,44],[12,13,52],[3,14,83],[10,4,26],[5,9,72],[5,14,32],[13,10,32],[15,6,2],[3,9,18],[1,11,45],[5,8,98],[7,13,33],[1,2,59],[4,11,79],[11,1,12],[8,5,79],[2,14,93],[3,6,53],[11,10,40],[14,2,33],[4,9,61],[3,8,10],[10,7,1],[8,3,58],[1,12,20],[5,1,51],[7,1,37],[9,7,34],[9,10,48],[8,4,90],[12,1,92],[6,4,99],[2,15,3],[2,3,80],[2,4,60],[15,14,75],[2,7,20],[15,8,20],[5,12,19],[13,3,74],[7,5,6],[9,6,73],[9,14,49],[15,1,56],[8,2,10],[7,9,9],[12,5,67],[6,3,29],[9,4,38],[6,9,42],[5,3,57],[3,2,48],[12,6,77],[10,15,15],[12,4,68],[14,1,52],[13,4,80],[4,1,84],[14,10,68],[2,12,81],[2,1,31],[6,14,52],[7,8,68],[4,12,73],[8,14,88],[13,5,92],[6,1,3],[9,11,80],[3,15,23],[15,4,84],[5,11,41],[7,11,42],[11,7,86],[9,15,63],[1,4,36],[3,13,82],[6,15,91],[13,6,64],[14,11,32],[11,5,68],[6,5,55],[4,5,35],[13,1,1],[4,10,47],[12,9,1],[7,10,44],[3,7,23],[8,12,68],[8,6,13],[2,9,19],[10,6,91],[7,12,80],[8,7,12],[4,7,4],[9,2,67],[14,9,29],[15,13,80],[6,8,62],[15,12,36],[1,3,48],[2,10,67],[9,13,55],[11,6,62],[8,11,92],[13,15,30],[4,13,97],[5,4,25],[4,2,9],[15,5,5],[15,2,45],[10,8,23],[14,5,43],[5,13,98],[14,13,73],[4,8,29],[10,5,0],[11,13,68],[9,12,91],[12,2,56],[9,1,23],[14,6,80],[9,5,10],[12,11,89],[5,15,94],[7,2,20],[3,12,89],[2,13,9],[11,2,1],[10,13,85],[6,10,76],[1,10,2],[14,15,20],[3,11,15],[11,8,62],[12,7,63],[8,15,91],[8,10,30],[12,3,80],[5,7,94],[13,2,60],[14,8,77],[10,12,67],[13,8,9],[13,11,48],[5,6,77],[10,3,51],[4,15,84],[13,12,10],[13,14,28],[4,6,46],[3,10,53],[14,7,48],[10,11,21],[15,11,99],[12,10,93],[11,14,73],[15,3,81],[2,5,22],[12,8,20],[6,13,24],[8,13,41],[8,9,98],[2,6,98],[7,15,27],[6,11,15],[7,14,72],[10,14,96],[1,8,18],[1,6,2],[3,4,78],[4,3,10],[11,4,54],[12,14,40],[3,5,63],[10,2,94],[1,9,57],[6,12,12],[9,8,37],[8,1,77],[13,7,80],[10,1,25],[9,3,37],[4,14,28],[1,13,88],[1,5,45],[7,4,65],[6,2,19],[11,15,37],[7,6,90],[2,8,1],[1,14,63],[5,2,47],[15,9,34],[11,9,41],[15,7,90],[13,9,45],[14,3,34],[6,7,44]],15,9)=49 +class Solution { +public: + int networkDelayTime(vector>& times, int n, int k) { + set us, vs; + const int INF = INT_MAX>>2; + vector< vector > A(n+1, vector(n+1, INF)); + for(auto & uvw : times){ + A[uvw[0]][uvw[1]] = uvw[2]; + if(k!=uvw[0]) vs.insert(uvw[0]); + if(k!=uvw[1]) vs.insert(uvw[1]); + } + if(vs.empty() || vs.size() < n-1) return -1; + for(int i=0;i A[k][to] + A[to][u]){ + A[k][u] = A[k][to] + A[to][u]; + print("<", A[k][u], "> ") + }else{ + print(A[k][u], " ") + } + } + vs.erase(to); + us.insert(to); + print("\nv=", to, ", dist=", dist, ", us=", us, "\n\n") + } + if(!vs.empty()) return -1; + int ans = 0; + for(int i=1; i Date: Tue, 3 Aug 2021 13:46:12 +0800 Subject: [PATCH 75/77] =?UTF-8?q?LC-581.=E6=9C=80=E7=9F=AD=E6=97=A0?= =?UTF-8?q?=E5=BA=8F=E8=BF=9E=E7=BB=AD=E5=AD=90=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ .../main.cpp" | 18 +++++++++++++++ .../solution.h" | 23 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 "questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/main.cpp" create mode 100644 "questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/solution.h" diff --git a/README.md b/README.md index 31f4b92..b015ae3 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ [16. 最接近的三数之和](https://leetcode-cn.com/problems/3sum-closest/) [18. 四数之和](https://leetcode-cn.com/problems/4sum/) + +[581. 最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray) ## 滑动窗口 [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) diff --git "a/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/main.cpp" "b/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/main.cpp" new file mode 100644 index 0000000..368397a --- /dev/null +++ "b/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/main.cpp" @@ -0,0 +1,18 @@ +#include "stl.h" +#include "parse.h" +#include "solution.h" +int main(int argc, char *argv[]) +{ + string str = "[[\"[2,6,4,8,10,9,15]\"],[\"[1,2,3,4]\"],[\"[1]\"]]"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + vector arg0 = parseIntegerArr(args[0]); + int result=s->findUnsortedSubarray(arg0); + string resultabc =serializeInteger(result); + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; +} \ No newline at end of file diff --git "a/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/solution.h" "b/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/solution.h" new file mode 100644 index 0000000..43def39 --- /dev/null +++ "b/questions/581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/solution.h" @@ -0,0 +1,23 @@ +// @algorithm @lc id=581 lang=cpp +// @title shortest-unsorted-continuous-subarray + + +#define print(...) +// @test([2,6,4,8,10,9,15])=5 +// @test([1,2,3,4])=0 +// @test([1])=0 +class Solution { +public: + // nums: [A] <= [B] <=[C] + int findUnsortedSubarray(vector& nums) { + const int n = (int)nums.size(); + int left=n, lower=INT_MAX, // left 记录A)的右开界 + right=-1, upper=INT_MIN; // right记录(C的左开界 + for(int i=0; i<(int)nums.size(); i++){ + lower Date: Wed, 4 Aug 2021 09:08:22 +0800 Subject: [PATCH 76/77] =?UTF-8?q?print(...)=E6=94=AF=E6=8C=81=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E6=95=B0=E7=BB=84=E3=80=81=E7=9F=A9=E9=98=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/virtualio.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/include/virtualio.h b/include/virtualio.h index cf69bed..0e37a0d 100644 --- a/include/virtualio.h +++ b/include/virtualio.h @@ -11,6 +11,17 @@ #define print(...) print_any(__VA_ARGS__); +template +struct Array{ + const T & Ref; + Array(const T & arr) : Ref(arr){} +}; +template +struct Mat{ + const T & Ref; + Mat(const T & mat) : Ref(mat){} +}; + class VOut{ public: virtual std::string str() {return "";} @@ -35,6 +46,15 @@ public: if(v.empty()) return *this; return Out(v.begin(), v.end()); } + template OStream&operator<<(const Array &v){ + if(!std::size(v.Ref)) return *this; + return Out(std::begin(v.Ref), std::end(v.Ref)); + } + template OStream&operator<<(const Mat &m){ + for(auto & v : m.Ref) + (*this) << v << "\n"; + return *this; + } template OStream& operator<<(const std::set &v){ if(v.empty()) return *this; return Out(v.begin(), v.end()); @@ -57,7 +77,6 @@ public: if(m.empty()) return *this; return Out(m.begin(), m.end()); } -protected: template OStream& Out(iterator src, iterator dst){ auto p = src; -- Gitee From 6cbae11369140627f15496a920ee320736f55859 Mon Sep 17 00:00:00 2001 From: sudo Date: Wed, 4 Aug 2021 21:33:17 +0800 Subject: [PATCH 77/77] =?UTF-8?q?LC-37.=E8=A7=A3=E6=95=B0=E7=8B=AC(?= =?UTF-8?q?=E5=9B=9E=E6=BA=AF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + include/stl.h | 12 ++++ .../main.cpp" | 26 ++----- .../solution.h" | 69 +++++++++++++++---- 4 files changed, 76 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b015ae3..c269a0e 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/)「DFS, DP」 +[37. 解数独](https://leetcode-cn.com/problems/sudoku-solver)「回溯」 + ## Hash [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/) diff --git a/include/stl.h b/include/stl.h index 57d67da..a73124f 100644 --- a/include/stl.h +++ b/include/stl.h @@ -1,4 +1,16 @@ #pragma once #include +#include +#include +#include #include "virtualio.h" using namespace std; + +template +void vv_conv(const vector> & from, vector> & to, + std::function conv = [](const F & f)->T{ return T(f); } +){ + for(size_t i=0; i> arr = parseStringArrArr(str); for (int i = 0; i < arr.size(); i++) { vector args = arr[i]; Solution *s = new Solution(); vector> arg0 = parseStringArrArr(args[0]); - vector> test; - print("=========================\n") - for(auto & vec : arg0){ - test.push_back(vector()); - auto & ts = *test.rbegin(); - for(auto & c : vec){ - ts.push_back(c[0]); - print(c[0], " "); - } - print("\n") - } - print("-------------------------\n") - s->solveSudoku(test); - for(auto & res : test){ - for(auto & c : res) - print(c, " "); - print("\n") - } + vector> mat(arg0.size(), vector(arg0.size())); + vv_conv(arg0, mat, [](const string&t){return t.size()?t[0]:'\0';}); + s->solveSudoku(mat); + vv_conv(mat, arg0, [](const char&t)->string{return {t};}); string resultabc =serializeStringArrArr(arg0); - cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend\n"<< endl; } return 0; } \ No newline at end of file diff --git "a/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" "b/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" index 2c45ad8..9cb7bde 100644 --- "a/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" +++ "b/questions/37.\350\247\243\346\225\260\347\213\254/solution.h" @@ -2,40 +2,83 @@ // @title sudoku-solver -// #define print(...) +#define print(...) // @test([["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]])=[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] +// @test([[".",".","9","7","4","8",".",".","."],["7",".",".",".",".",".",".",".","."],[".","2",".","1",".","9",".",".","."],[".",".","7",".",".",".","2","4","."],[".","6","4",".","1",".","5","9","."],[".","9","8",".",".",".","3",".","."],[".",".",".","8",".","3",".","2","."],[".",".",".",".",".",".",".",".","6"],[".",".",".","2","7","5","9",".","."]])=[["5","1","9","7","4","8","6","3","2"],["7","8","3","6","5","2","4","1","9"],["4","2","6","1","3","9","8","7","5"],["3","5","7","9","8","6","2","4","1"],["2","6","4","3","1","7","5","9","8"],["1","9","8","5","2","4","3","6","7"],["9","7","5","8","6","3","1","2","4"],["8","3","2","4","9","1","7","5","6"],["6","4","1","2","7","5","9","8","3"]] #define BOX(i,j) box[(i)/3*3+(j)/3] -#define FLIP(i,j,bit) row[i] ^= 1<<(bit),col[j] ^= 1<<(bit),BOX((i),(j)) ^= 1<<(bit) -#define CHOICES(i,j) ((~(BOX((i),(j)) | row[i] | col[j])) & 0x1FF) -#define CHOICES_CNT(i,j)__builtin_popcount(CHOICES((i),(j))) -#define LAST_CHOICE(m) ((m) & -(m)) +#define FLIP(i,j,bit) row[i] ^= 1<<(bit),\ + col[j] ^= 1<<(bit),\ + BOX((i),(j)) ^= 1<<(bit) +#define CHOICES(i,j) ( (~(BOX((i),(j)) | row[i] | col[j])) & 0x1FF ) +#define COUNT(m) __builtin_popcount(m) +#define LAST(m) __builtin_ctz((m) & (-(m))) +using blank_t = pair; +using iterator_t = vector::iterator; class Solution { public: void solveSudoku(vector>& board) { int row[9]={0}, col[9]={0}, box[9]={0}; - vector> blanks; + vector blanks; + print("orginal:\n") + print(Mat(board)) for(int i=0; ipair{ - int cntChoices = 10, r=0, c=0; + int minChoices = 10, r=-1, c=-1; for(auto & [i,j] : blanks){ - int n = CHOICES_CNT(i,j); - if(n < cntChoices) + if(board[i][j] != '.') continue; + int choices = CHOICES(i,j); + int n = COUNT(choices); + if(n < minChoices){ + minChoices = n; r = i, c = j; - if(n == 1) break; + } + if(minChoices == 1) break; } return {r,c}; }; + + bool solved = false; + function dfs = [&](){ + auto blk = chooseBlank(); + if(blk.first<0 || blk.second<0){ + solved = true; + return; + } + for(auto choices = CHOICES(blk.first, blk.second); + choices && !solved; choices = choices&(choices-1)){ + auto bit = LAST(choices); + FLIP(blk.first, blk.second, bit); + board[blk.first][blk.second] = '1' + bit; + dfs(); + if(solved) break; + FLIP(blk.first, blk.second, bit); + board[blk.first][blk.second] = '.'; + } + }; + dfs(); + print("solved=", solved, "\n") + print(Mat(board)) + print("-----------\n") + print(std::hex, Array(row), "\n", Array(col), "\n", Array(box), "\n") } }; \ No newline at end of file -- Gitee