Skip to content

GH-169: Solve Leetcode 67, 69 #280

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions collections/leetcode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
<td>64</td>
<td>65</td>
<td>66</td>
<td>67</td>
<td>🟢&nbsp;<a href='https://github.com/rain1024/datastructures-algorithms-competitive-programming/tree/main/problems/leetcode67'>67</a></td>
<td>68</td>
<td>69</td>
<td>🟢&nbsp;<a href='https://github.com/rain1024/datastructures-algorithms-competitive-programming/tree/main/problems/leetcode69'>69</a></td>
<td>70</td>
<tr>
<td>71</td>
Expand Down
6 changes: 6 additions & 0 deletions collections/leetcode/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ problems:
- name: 49
languages: cpp
level: medium
- name: 67
languages: python
level: easy
- name: 69
languages: python
level: easy
- name: 78
languages: cpp
level: medium
Expand Down
3 changes: 3 additions & 0 deletions problems/leetcode67/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
solution
*.dSYM
python/main/__pycache__
10 changes: 10 additions & 0 deletions problems/leetcode67/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Leetcode Problem

## Usage

Test program

```
# Run all tests
python solution_test.py
```
2 changes: 2 additions & 0 deletions problems/leetcode67/data/1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
11
1
1 change: 1 addition & 0 deletions problems/leetcode67/data/1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
100
2 changes: 2 additions & 0 deletions problems/leetcode67/data/2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1010
1011
1 change: 1 addition & 0 deletions problems/leetcode67/data/2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10101
10 changes: 10 additions & 0 deletions problems/leetcode67/problem_infos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "67. Add Binary",
"link": "https://leetcode.com/problems/add-binary/",
"tags": [
"Math",
"String",
"Bit Manipulation",
"Simulation"
]
}
38 changes: 38 additions & 0 deletions problems/leetcode67/python/main/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class Solution:
def addBinary(self, a: str, b: str) -> str:
len_a = len(a)
len_b = len(b)
max_len = len_a
if len_a > len_b:
gap = len_a - len_b
for i in range(0, gap):
b = '0' + b
elif len_a < len_b:
max_len = len_b
gap = len_b - len_a
for i in range(0, gap):
a = '0' + a
temp = 0
result = []
a = list(a)
b = list(b)
a.reverse()
b.reverse()
for i, bit_a in enumerate(a):
sum_bit = int(bit_a) + int(b[i]) + temp
if sum_bit == 3:
result.append('1')
temp = 1
elif sum_bit == 2:
result.append('0')
temp = 1
elif sum_bit == 1:
result.append('1')
temp = 0
elif sum_bit == 0:
result.append('0')
temp = 0
if temp == 1:
result.append('1')
result.reverse()
return ''.join(result)
47 changes: 47 additions & 0 deletions problems/leetcode67/python/tests/solution_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import sys
import unittest
from os import listdir
from os.path import abspath, dirname, join

python_source = dirname(dirname(abspath(__file__)))
sys.path.append(python_source)
from main.solution import Solution

test_data_directory = join(dirname(python_source), 'data')
test_cases = set([data_file.split('.')[0] for data_file in listdir(test_data_directory)])

def read_input(input_file):
with open(input_file, 'r') as f:
a = f.readline().strip()
b = f.readline().strip()
return a, b

def read_output(output_file):
with open(output_file, 'r') as f:
k = f.readline().strip()
return k

class TestSequenceMeta(type):
def __new__(mcs, name, bases, dict):

def gen_test(input_file, output_file):
def test(self):
solution = Solution()
nums, val = read_input(input_file)
expected_k = read_output(output_file)
actual_k = solution.addBinary(nums, val)
self.assertEqual(actual_k, expected_k)
return test

for test_case in test_cases:
test_name = f'test_{test_case}'
input_file = join(test_data_directory, f'{test_case}.in')
output_file = join(test_data_directory, f'{test_case}.out')
dict[test_name] = gen_test(input_file, output_file)
return type.__new__(mcs, name, bases, dict)

class TestSequence(unittest.TestCase, metaclass=TestSequenceMeta):
pass

if __name__ == '__main__':
unittest.main()
3 changes: 3 additions & 0 deletions problems/leetcode69/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
solution
*.dSYM
python/main/__pycache__
10 changes: 10 additions & 0 deletions problems/leetcode69/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Leetcode Problem

## Usage

Test program

```
# Run all tests
python solution_test.py
```
1 change: 1 addition & 0 deletions problems/leetcode69/data/1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4
1 change: 1 addition & 0 deletions problems/leetcode69/data/1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
1 change: 1 addition & 0 deletions problems/leetcode69/data/2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8
1 change: 1 addition & 0 deletions problems/leetcode69/data/2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
8 changes: 8 additions & 0 deletions problems/leetcode69/problem_infos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "69. Sqrt(x)",
"link": "https://leetcode.com/problems/sqrtx/",
"tags": [
"Math",
"Binary Search"
]
}
16 changes: 16 additions & 0 deletions problems/leetcode69/python/main/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def mySqrt(self, x: int) -> int:
low = 0
high = x
while True:
mid = low + (high - low) // 2
if mid * mid == x:
return mid
elif mid * mid < x:
if (mid+1)*(mid+1)>x:
return mid
if (mid+1)*(mid+1)==x:
return mid+1
low = mid
else:
high = mid
46 changes: 46 additions & 0 deletions problems/leetcode69/python/tests/solution_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import sys
import unittest
from os import listdir
from os.path import abspath, dirname, join

python_source = dirname(dirname(abspath(__file__)))
sys.path.append(python_source)
from main.solution import Solution

test_data_directory = join(dirname(python_source), 'data')
test_cases = set([data_file.split('.')[0] for data_file in listdir(test_data_directory)])

def read_input(input_file):
with open(input_file, 'r') as f:
x = int(f.readline().strip())
return x

def read_output(output_file):
with open(output_file, 'r') as f:
k = int(f.readline().strip())
return k

class TestSequenceMeta(type):
def __new__(mcs, name, bases, dict):

def gen_test(input_file, output_file):
def test(self):
solution = Solution()
x = read_input(input_file)
expected_k = read_output(output_file)
actual_k = solution.mySqrt(x)
self.assertEqual(actual_k, expected_k)
return test

for test_case in test_cases:
test_name = f'test_{test_case}'
input_file = join(test_data_directory, f'{test_case}.in')
output_file = join(test_data_directory, f'{test_case}.out')
dict[test_name] = gen_test(input_file, output_file)
return type.__new__(mcs, name, bases, dict)

class TestSequence(unittest.TestCase, metaclass=TestSequenceMeta):
pass

if __name__ == '__main__':
unittest.main()
23 changes: 15 additions & 8 deletions tools/craft/craft.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import os
from os.path import dirname, join
import sys
import shutil
import sys
from os.path import dirname, join

CURRENT_DIR = dirname(__file__)
PROBLEMS_DIR = join(dirname(dirname(CURRENT_DIR)), "problems")
print(PROBLEMS_DIR)
SUPPORTED_LANGUAGE = ['cpp','python']


def replace_string_in_file(filename, old, new):
Expand All @@ -17,23 +18,27 @@ def replace_string_in_file(filename, old, new):


class CodeGenerator:
def __init__(self, domain, problem_id):
def __init__(self, domain, problem_id, language):
self.domain = domain
self.problem_id = problem_id
self.language = language

def generate(self):
domain = self.domain
problem_id = self.problem_id
problem_dir = join(PROBLEMS_DIR, f"{domain}{problem_id}")
try:
shutil.copytree(join(CURRENT_DIR, "templates", domain), problem_dir)
if self.language not in SUPPORTED_LANGUAGE:
raise Exception(f'{language} is not yet supported.')
exclude_folders = [folder for folder in SUPPORTED_LANGUAGE if folder != language]
shutil.copytree(join(CURRENT_DIR, "templates", domain), problem_dir, ignore=shutil.ignore_patterns(*exclude_folders))
except Exception as e:
print(e)
sys.exit(1)

class CodeforcesGenerator(CodeGenerator):
def __init__(self, domain, problem_id):
super().__init__(domain, problem_id)
def __init__(self, domain, problem_id, language):
super().__init__(domain, problem_id, language)

def generate(self):
super().generate()
Expand All @@ -60,19 +65,21 @@ def task_rename_files(self):
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Boilderplate to generate workspace for solving problem.\n")
print("Usage: python crape.py domain problem_id\n\n")
print("Usage: python craft.py domain problem_id language\n\n")
print("Examples:\n")
print("\tpython craft.py codeforces 100A")
print("\tpython craft.py leetcode 217")
print("\tpython craft.py leetcode 217 python")
print("\tpython craft.py aoc 2022day2")
print("\tpython craft.py codejam 2022PunchedCards")
print("\tpython craft.py dsas _aog_week1_graph_decomposition1_1_finding_exit_from_maze")
sys.exit(1)
domain = sys.argv[1]
problem_id = sys.argv[2]
language = sys.argv[3] if len(sys.argv) == 4 else 'cpp'
if domain == "codeforces":
GeneratorClass = CodeforcesGenerator
else:
GeneratorClass = CodeGenerator
generator = GeneratorClass(domain, problem_id)
generator = GeneratorClass(domain, problem_id, language)
generator.generate()
3 changes: 2 additions & 1 deletion tools/craft/templates/leetcode/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
solution
*.dSYM
*.dSYM
python/main/__pycache__
3 changes: 3 additions & 0 deletions tools/craft/templates/leetcode/python/main/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Solution:
def solve():
pass
47 changes: 47 additions & 0 deletions tools/craft/templates/leetcode/python/tests/solution_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import sys
import unittest
from os import listdir
from os.path import abspath, dirname, join

python_source = dirname(dirname(abspath(__file__)))
sys.path.append(python_source)
from main.solution import Solution

test_data_directory = join(dirname(python_source), 'data')
test_cases = set([data_file.split('.')[0] for data_file in listdir(test_data_directory)])

def read_input(input_file):
with open(input_file, 'r') as f:
nums = [int(num) if num != '_' else None for num in f.readline().strip().strip('][').split(',') ]
val = int(f.readline().strip())
return nums, val

def read_output(output_file):
with open(output_file, 'r') as f:
k = int(f.readline().strip())
return k

class TestSequenceMeta(type):
def __new__(mcs, name, bases, dict):

def gen_test(input_file, output_file):
def test(self):
solution = Solution()
nums, val = read_input(input_file)
expected_k = read_output(output_file)
actual_k = solution.searchInsert(nums, val)
self.assertEqual(actual_k, expected_k)
return test

for test_case in test_cases:
test_name = f'test_{test_case}'
input_file = join(test_data_directory, f'{test_case}.in')
output_file = join(test_data_directory, f'{test_case}.out')
dict[test_name] = gen_test(input_file, output_file)
return type.__new__(mcs, name, bases, dict)

class TestSequence(unittest.TestCase, metaclass=TestSequenceMeta):
pass

if __name__ == '__main__':
unittest.main()