Skip to content
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

feat: added LeetCode problem 1,2 #2450

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
39 changes: 39 additions & 0 deletions .github/workflows/leetcode_directory_writer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# The objective of this GitHub Action is to update the leetcode DIRECTORY.md file (if needed)
# when doing a git push
name: leetcode_directory_writer
on:
push:
realstealthninja marked this conversation as resolved.
Show resolved Hide resolved
realstealthninja marked this conversation as resolved.
Show resolved Hide resolved
paths:
- 'leetcode/src/**.cpp'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Add python dependencies
run: |
pip install requests
- name: Write LeetCode DIRECTORY.md
run: |
python3 scripts/leetcode_directory_md.py 2>&1 | tee leetcode/DIRECTORY.md
git pull || true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, this is not needed if we use fetch-depth in actions/checkout.
CC: @tjgurwara99.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is not needed.

- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
id: commit-push
with:
commit_message: 'docs: updating `leetcode/DIRECTORY.md`'
branch: 'leetcode-directory-${{ github.sha }}'
create_branch: true
- name: Creating and merging the PR
shell: bash
if: steps.commit-push.outputs.changes_detected == 'true'
run: |
gh pr create --base ${GITHUB_REF##*/} --head leetcode-directory-${{ github.sha }} --title 'docs: updating `leetcode/DIRECTORY.md`' --body 'Updated LeetCode directory (see the diff. for changes).'
gh pr merge --admin --merge --subject 'docs: updating `leetcode/DIRECTORY.md' --delete-branch
realstealthninja marked this conversation as resolved.
Show resolved Hide resolved
env:
GH_TOKEN: ${{ github.token }}
69 changes: 69 additions & 0 deletions leetcode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 📚 Contributing 📚

We're glad you're interested in adding C++ LeetCode solutions to the repository.\
Here we'll be explaining how to contribute to LeetCode solutions properly.

## 💻 Cloning/setting up the project 💻

First off, you'll need to fork the repository [**here**](https://github.com/TheAlgorithms/C-Plus-Plus/fork).\
Then, you'll need to clone the repository to your local machine.

```bash
git clone https://github.com/your-username/C-Plus-Plus.git
```

After that, you'll need to create a new branch for your solution.

```bash
git checkout -b solution/your-solution-name
```

## 📝 Adding a new solution 📝

All LeetCode problems can be found [**here**](https://leetcode.com/problemset/all/).\
If you have a solution to any of these problems (which are not being **repeated**, that's great! Here are the steps:

1. Add a new file in `leetcode/src` with the number of the problem.
- For example: if the problem's number is 98, the filename should be `98.cpp`.
2. Provide a small description of the solution at the top of the file. A function should go below that. For example:

```c
/**
* Return an vector of vector of size returnSize.
* The sizes of the vectors are returned as returnColumnSizes vector.
* Note: Both returned vector and columnSizes vector must be dynamically allocated, assume caller calls free.
*/
```

3. Do not provide a `main` function. Use the required standalone functions instead.
4. Doxygen documentation isn't used in LeetCode solutions. Simple/small documentation or comments should be fine.
5. Don't include libraries/headers such as `iostream`. Your file should be the solution to the problem only.
realstealthninja marked this conversation as resolved.
Show resolved Hide resolved

> **Note**
> There was a requirement to update the `leetcode/DIRECTORY.md` file with details of the solved problem. It's not required anymore. The information about the problem is fetched automatically throughout the LeetCode API.

## 📦 Committing your changes 📦

Once you're done with adding a new LeetCode solution, it's time we make a pull request.

1. First, stage your changes.

```bash
git add leetcode/src/98.cpp # Use `git add .` to stage all changes.
```

2. Then, commit your changes.

```bash
git commit -m "feat: add LeetCode problem 98" -m "Commit description" # Optional
```

3. Finally, push your changes to your forked repository.

```bash
git push origin solution/your-solution-name:solution/your-solution-name
```

4. You're done now! You just have to make a [**pull request**](https://github.com/TheAlgorithms/C-Plus-Plus/compare). 🎉

If you need any help, don't hesitate to ask and join our [**Discord server**](https://the-algorithms.com/discord)! 🙂
24 changes: 24 additions & 0 deletions leetcode/src/1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
* You may assume that each input would have exactly one solution, and you may not use the same element twice.
*/

class Solution {
public:
std::vector<int> twoSum(std::vector<int>& nums, int target) {
std::unordered_map<int, int> mp; // value:index
std::vector<int> res;

for (int i = 0; i < nums.size(); i++) {
int diff = target - nums[i];

if (mp.find(diff) != mp.end()) {
res.push_back(mp[diff]);
res.push_back(i);
return res;
}
mp[nums[i]] = i;
}
return res;
}
};
37 changes: 37 additions & 0 deletions leetcode/src/2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* You are given two non - empty linked lists representing two non - negative integers.
* The digits are stored in reverse order, and each of their nodes contains a single digit.
* Add the two numbersand return the sum as a linked list.
*/

/*
* 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) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
ListNode head;
ListNode* sum = &head;

while (l1 || l2) {
int val = carry + (l1 ? l1->val : 0) + (l2 ? l2->val : 0);
carry = val / 10;
sum->next = new ListNode(val % 10);
sum = sum->next;
l1 = (l1 ? l1->next : nullptr);
l2 = (l2 ? l2->next : nullptr);
}
if (carry) {
sum->next = new ListNode(carry);
}

return head.next;
}
};
124 changes: 124 additions & 0 deletions scripts/leetcode_directory_md.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python3

from dataclasses import dataclass
from os import listdir
from pathlib import Path

import requests


@dataclass
class Task:
"""The task dataclass. Container for task info"""

id: str
title: str
solution: str
difficulty: str


def fetch_leetcode_folder_tasks(solutions_folder: Path) -> list[Task]:
"""Fetch leetcode tasks from the Leetcode"""

# Fetch tasks info from the leetcode API.
resp = requests.get("https://leetcode.com/api/problems/algorithms/", timeout=10)
content_dict = resp.json()

raw_tasks_id_dict = {}

for task in content_dict["stat_status_pairs"]:
task_stat = task["stat"]
raw_tasks_id_dict[str(task_stat["frontend_question_id"])] = task

# Generate result tasks info to be inserted into the document
tasks_list = []

difficulty = {1: "Easy", 2: "Medium", 3: "Hard"}

for fl in listdir(solutions_folder):
task_id = fl.split(".")[0]

raw_task = raw_tasks_id_dict.get(task_id, None)
if raw_task is None:
continue

raw_task_stat = raw_task["stat"]
tasks_list.append(
Task(
id=f'{raw_task_stat["frontend_question_id"]}',
title=f'[{raw_task_stat["question__title"]}](https://leetcode.com/problems/{raw_task_stat["question__title_slug"]})',
solution=f"[C++](./src/{fl})",
difficulty=f'{difficulty.get(raw_task["difficulty"]["level"], "")}',
)
)

return tasks_list


HEADER_ID = "#"
HEADER_TITLE = "Title"
HEADER_SOLUTION = "Solution"
HEADER_DIFFICULTY = "Difficulty"
SEPARATOR = "-"


def print_directory_md(tasks_list: list[Task]) -> None:
"""Print tasks into the stdout"""

def get_max_len(get_item):
return max(list(map(lambda x: len(get_item(x)), tasks_list)))

id_max_length = max(get_max_len(lambda x: x.id), len(HEADER_ID))
title_max_length = max(get_max_len(lambda x: x.title), len(HEADER_TITLE))
solution_max_length = max(get_max_len(lambda x: x.solution), len(HEADER_SOLUTION))
difficulty_max_length = max(
get_max_len(lambda x: x.difficulty), len(HEADER_DIFFICULTY)
)

def formatted_string(header, title, solution, difficulty):
return (
f"| {header.rjust(id_max_length)} "
+ f"| {title.ljust(title_max_length)} "
+ f"| {solution.ljust(solution_max_length)} "
+ f"| {difficulty.ljust(difficulty_max_length)} |"
)

tasks_rows = []

tasks_rows.append(
formatted_string(HEADER_ID, HEADER_TITLE, HEADER_SOLUTION, HEADER_DIFFICULTY)
)
tasks_rows.append(
formatted_string(
id_max_length * SEPARATOR,
title_max_length * SEPARATOR,
solution_max_length * SEPARATOR,
difficulty_max_length * SEPARATOR,
)
)

tasks_list.sort(key=lambda x: int(x.id.strip()))

for task in tasks_list:
tasks_rows.append(
formatted_string(task.id, task.title, task.solution, task.difficulty)
)

print(
"""
# LeetCode

### LeetCode Algorithm
"""
)

for item in tasks_rows:
print(item)


if __name__ == "__main__":
top_dir = Path(".")
solutions_folder = top_dir / "leetcode" / "src"

tasks_list = fetch_leetcode_folder_tasks(solutions_folder)
print_directory_md(tasks_list)
nageshnnazare marked this conversation as resolved.
Show resolved Hide resolved