# leezy Release 0.5.3

leezy: leetcode helper for the lazy

MIT
Install
``` pip install leezy==0.5.3 ```

# Leezy

## Install

`\$ pip install leezy`

## Examples

1. 设置工作目录
`\$ leezy config --add core.workdir <DIR>`

1. 拉取题目
`\$ leezy pull 1`

`workdir`下生成如下目录和文件

``````\$ tree
.
└── 001 - Two Sum
├── 001.html # 题目描述，在浏览器或者其他html预览器中查看
└── 001_two-sum.py # solution模板，在这里编辑解法
``````
```# 001_two-sum.py(initial)
from leezy import Solution, solution

class Q001(Solution):  # 继承Solution
@solution    # 被solution装饰的函数将参与最后的结果输出或测试
def twoSum(self, nums, target):
pass

def main():
q = Q001()
q.add_case(q.case([2, 7, 11, 15], 9)) # 添加自己的测试用例
q.run()

if __name__ == "__main__":
main()```
1. 尝试死磕多种解法
```# 001_two-sum.py(modified)
from leezy import Solution, solution

class Q001(Solution):
@solution
def twoSum(self, nums, target):
for i,x in enumerate(nums):
for j, y in enumerate(nums[i+1:], i+1):
if x + y == target:
return [i, j]

@solution
def twoSum_sort(self, nums, target):
L, i, j = len(nums), 0, len(nums)-1
sorted_i = sorted(range(L), key=nums.__getitem__)
while i < j:
s = nums[sorted_i[i]] + nums[sorted_i[j]]
if s > target:
j -= 1
elif s < target:
i += 1
else:
return [sorted_i[i], sorted_i[j]]

@solution
def twoSum_hash(self, nums, target):
hash_table = {}
for i, x in enumerate(nums):
another = target - x
if x in hash_table:
return [hash_table[x], i]
else:
hash_table[another] = i

def main():
q = Q001()
q.run()

if __name__ == "__main__":
main()
```
1. 运行/查看结果
```\$ leezy run 1
+----------+----------+---------------+---------------+
|          |  twoSum  |  twoSum_sort  |  twoSum_hash  |
+==========+==========+===============+===============+
|  case 0  |  [1, 2]  |  [1, 2]       |  [1, 2]       |
+----------+----------+---------------+---------------+
|  case 1  |  [0, 1]  |  [0, 1]       |  [0, 1]       |
+----------+----------+---------------+---------------+
|  case 2  |  [0, 1]  |  [0, 1]       |  [0, 1]       |
+----------+----------+---------------+---------------+
|  case 3  |  [0, 3]  |  [0, 3]       |  [0, 3]       |
+----------+----------+---------------+---------------+
|  case 4  |  [2, 3]  |  [2, 3]       |  [2, 3]       |
+----------+----------+---------------+---------------+```
1. 执行测试

```# 001_two-sum.py(modified, testcase-added)

...

def main():
q = Q001()
q.add_case(q.case([2, 7, 11, 15], 9).assert_equal([0, 1]))
q.add_case(q.case([2, 7, 11, 15], 17).assert_equal([0, 3]))
q.add_case(q.case([2, 7, 11, 15], 26).assert_equal([2, 3]))
q.run()```

```\$ leezy run 1
+----------+----------+-----------+
|          |  twoSum  |  two_sum  |
+==========+==========+===========+
|  case 0  |  [1, 2]  |  [1, 2]   |
+----------+----------+-----------+
|  case 1  |  [0, 1]  |  [0, 1]   |
+----------+----------+-----------+
.........                                                                   [100%]
9 passed in 0.09s```

```from itertools import chain
from collections import Counter

class Q1054(Solution):
@solution
def rearrangeBarcodes(self, barcodes):
# 452ms 92.03%
N = len(barcodes)
idx = chain(range(0, N, 2), range(1, N, 2))
counter = Counter(barcodes)
ans = [0] * N
for x, cnt in counter.most_common():
for _ in range(cnt):
ans[next(idx)] = x
return ans

def main():
q = Q1054()

def check(A):
return all(x != nx for x, nx in zip(A, A[1:])

q.add_case(q.case([1, 1, 1, 2, 2, 2]).assert_true_with(check))
q.add_case(q.case([1, 1, 1, 1, 2, 2, 3, 3]).assert_true_with(check))
q.run()```
1. 提交解法

```\$ leezy submit 3@1
Is it OK to submit function 'twoSum'?

class Solution:
def twoSum(self, nums, target):
hash_table = {}
for i, x in enumerate(nums):
another = target - x
if x in hash_table:
return [hash_table[x], i]
else:
hash_table[another] = i

> [Yes/No]? y
----------------Accepted!----------------
time used & rank: 40 ms faster than 93.07%
memory used & rank: 14.9 MB less than 6.25%

https://leetcode-cn.com/submissions/detail/55171676
https://leetcode.com/problems/two-sum/discuss/
```

## Why leezy?

leezy名字来自于leetcode和lazy的组合。懒惰就是生产力。

【第一遍刷Leetcode】【使用本地编辑器】【愿意尝试一题多解】【少些重复print、测试用例】

• 为什么不在线刷题？

首先，因为是第一次做题，希望把重点放在解题本身，环境就使用自己习惯的就好。

其次，在线run code的速度不稳定，不适合初期的debug。

最后，在本地记录解法，管理起来更直接，离线也可以随时搜索复习。

如果是第n遍刷题了，直接上web更方便。

• leezy的核心是什么？

少写print，少写重复测试用例。和上面提到的标签所暗示的那样，做题大概率不能一次成功，需要在本地用自己的测试用例反复运行，打印结果，修改。当使用多个解法时，又需要重复这些工作。所以一次性写完这些重复的print、测试用例就是leezy最平常且简单的目的

• 和其他刷题工具有什么区别？

其他的刷题工具，典型的有基于CLI的leetcode-cli, 基于VSCode的leetcode for vscode(也基于leetcode-cli)，都支持完整的刷题流程：用户登录、题目拉取、编写、测试、提交、查看统计数据。本质是把网页版的功能在用另一套接口进行实现。

leezy虽然也可以登录、拉取、测试以及提交，但相比上述工具，leezy对题目拉取后，模板文件不再和网页上提供的模板一致，更方便实现一题多解的本地调试

## More things

### 命令行

``````usage: leezy [options] COMMAND

optional arguments:
-h, --help     show this help message and exit
-V, --version  show program's version number and exit
--zone ZONE    'cn' or 'us', default is 'cn'
--dir DIR      assign a temporary workdir for this session

COMMANDS:
use 'leezy <COMMAND> -h' to see more

-⭐-
show         show basic info of problems
pull         pull problems to local files
run          run your solutions, see outputs or test them
submit       submit your solution to leetcode
plot         show a heatmap of your all accepted solutions
config       manage global configs
``````

name description default
table.max_col_width 表格列的最大宽度 40字符
table.max_content_length 每个单元格支持的最长内容长度，超过部分将被截断(-1表示不截断) 100字符
core.workdir 刷题目录，每次pull、run都将基础该目录 当前目录
core.zone 刷题网站版本，中国区还是美区 cn
log.level 日志等级 warning

### 辅助类

`leezy.assists`中导入

```from leezy.assists import TreeNode, ListNode

t = TreeNode.make_tree([1, 2, 3, 4, 5, None, 6])
print(type(t)) # <class 'leezy.assists.TreeNode'>
print(t)       # Tree(1-2-3-4-5-None-6)
print(t.left)  # Tree(2-4-5)
print(t.right) # Tree(3-None-6)

l = ListNode.make_linked_list([1, 2, 3, 4, 5])
print(type(l)) # <class 'leezy.assists.ListNode'>
print(l)       # 1->2->3->4->5
print(l.next)  # 2->3->4->5```

• TreeNode
• ListNode

```from leezy import Solution, solution
from leezy.assists import TreeContext # 导入TreeContext

class Q700(Solution):
@solution
def searchBST(self, root, val):
if root is None:
return
if root.val > val:
return self.searchBST(root.left, val)
elif root.val < val:
return self.searchBST(root.right, val)
else:
return root

@solution
def search(self, root, val):
while root:
if root.val > val:
root = root.left
elif root.val < val:
root = root.right
else:
return root
return None

def main():
q = Q700()
q.set_context(TreeContext)  # 设置TreeContex
q.add_case(q.case([4, 2, 7, 1, 3], 2)) # 这里传入的列表自动会被转化为Tree
q.run()```

``````\$ leezy pull --context tree 700 701
``````