Skip to content

Commit 2a74aeb

Browse files
committed
Merge branch 'electron'
2 parents a297e0d + a718d2a commit 2a74aeb

33 files changed

+3631
-201
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ build/
4646
*.sln
4747
problem_builds/
4848
.vscode/
49+
install/
50+
51+
# Temporary folders generated by openleetcode
52+
testcase_output/
4953

5054
# Imported modules
5155
nlohmann/

CMakeLists.txt

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
11
cmake_minimum_required(VERSION 3.12)
22

3-
if (NOT PROBLEM_BUILDS_NAME)
4-
set(PROBLEM_BUILDS_NAME "problem_builds")
5-
endif()
6-
7-
set(PROJECT_BUILDS_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR}/${PROBLEM_BUILDS_NAME})
8-
9-
if(NOT CMAKE_INSTALL_PREFIX)
10-
set(PROJECT_BUILDS_DIR "${PROJECT_BUILDS_DIR_NAME}")
11-
else()
12-
set(PROJECT_BUILDS_DIR "${CMAKE_INSTALL_PREFIX}")
13-
endif()
14-
15-
message (STATUS "Setting PROJECT_BUILDS_DIR to ${PROJECT_BUILDS_DIR}")
3+
option(BUILD_UI "Build the OpenLeetCode UI" OFF)
164

5+
set(PROBLEM_BUILDS_NAME "problem_builds")
176
set(CMAKE_FILE_DESTINATION_SUFIX "_destination")
187

198
if(NOT CMAKE_BUILD_TYPE)
@@ -25,8 +14,4 @@ project(openleetcode
2514
)
2615

2716
add_subdirectory(src)
28-
add_subdirectory(data)
29-
30-
if (TESTING)
31-
add_subdirectory(test)
32-
endif()
17+
add_subdirectory(data)

README.md

Lines changed: 82 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,93 +2,115 @@ OpenLeetCode - An open source version of LeetCode
22
--------------------------------------------------------
33
Welcome to the OpenLeetCode Project!
44

5-
The motivation behind this project is to be able to practice LeetCode problems on a plane without requiring an internet connection (until Starlink ramps up). It is by no means intended to replace or replicate leetcode.com.
6-
7-
## Table of Contents
8-
9-
1. [Windows Terminal](#windows-terminal)
10-
1. [Build](#build)
11-
2. [Run](#run)
12-
1. [Windows Terminal](#windows-terminal-1)
13-
2. [Unix](#unix)
14-
2. [How To Use](#how-to-use)
15-
3. [List of LeetCode Problems](#list-of-leetcode-problems)
16-
4. [Usage](#usage)
17-
5. [Note](#note)
18-
6. [Requirements](#requirements)
19-
7. [Contributing](#contributing)
20-
21-
## Windows Terminal
22-
23-
### Build
5+
The motivation behind this project is to be able to practice LeetCode problems on a plane without requiring an internet connection (until Starlink ramps up). This project is not intended to replace or replicate leetcode.com.
6+
7+
## Table of Content
8+
- [OpenLeetCode - An open source version of LeetCode](#openleetcode---an-open-source-version-of-leetcode)
9+
- [Table of Content](#table-of-content)
10+
- [Screenshot](#screenshot)
11+
- [Build](#build)
12+
- [Building without UI](#building-without-ui)
13+
- [Building with UI](#building-with-ui)
14+
- [Run](#run)
15+
- [CLI - Windows Terminal](#cli---windows-terminal)
16+
- [CLI - Unix](#cli---unix)
17+
- [UI - Windows Terminal](#ui---windows-terminal)
18+
- [UI - Unix](#ui---unix)
19+
- [How To Use](#how-to-use)
20+
- [List of LeetCode Problems](#list-of-leetcode-problems)
21+
- [Usage](#usage)
22+
- [Note](#note)
23+
- [Requirements](#requirements)
24+
- [Additional Requirements for the UI](#additional-requirements-for-the-ui)
25+
- [Contributing](#contributing)
26+
27+
28+
## Screenshot
29+
![Screenshot](./assets/images/ui_screenshot.png)
30+
31+
## Build
32+
### Building without UI
33+
```cmd
34+
cmake -B build -DCMAKE_INSTALL_PREFIX=install
35+
cmake --build build
36+
cmake --install build --prefix=install
37+
```
38+
### Building with UI
2439
```cmd
25-
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DPROBLEM_BUILDS_NAME=problem_builds
40+
cmake -B build -DCMAKE_INSTALL_PREFIX=install -DBUILD_UI=ON
2641
cmake --build build
27-
cmake --install build --config Debug
42+
cmake --install build --prefix=install
2843
```
29-
### Run
30-
#### Windows Terminal
44+
## Run
45+
### CLI - Windows Terminal
3146
```cmd
32-
./problem_builds/openleetcode --problem_builds_dir ./problem_builds --language cpp --problem TwoSum
47+
./problem_builds/openleetcode --language cpp --problem TwoSum
3348
```
34-
#### Unix
49+
### CLI - Unix
3550
```bash
36-
./problem_builds/openleetcode.sh --problem_builds_dir ./problem_builds --language cpp --problem TwoSum
51+
./problem_builds/openleetcode.sh --language cpp --problem TwoSum
3752
```
53+
### UI - Windows Terminal
54+
```cmd
55+
./problem_builds/openleetcodeui
56+
```
57+
### UI - Unix
58+
```bash
59+
./problem_builds/openleetcodeui.sh
60+
```
61+
NOTE: UI for unix is yet to be tested.
3862

3963
## How To Use
40-
The above example runs **TwoSum** problem using **C++**.
41-
After the build succeeds the following directory structure will be generated in the folder specified by ``--problem_builds_dir`` flag. In this example it's a folder called ``problem_builds`` as follows:.
64+
After the build succeeds, the following directory structure will be generated:
4265

43-
- problem_builds
44-
- problems
45-
- TwoSum
46-
- cpp
47-
- solution.cpp
48-
- ...
49-
- testcases
50-
- TestCase1.test
51-
- TestCase2.test
52-
- ...
53-
- description.md
54-
- launguage
55-
- cpp
66+
- problems
67+
- NumberOfIslands
68+
- cpp
69+
- solution.cpp
70+
- ...
71+
- testcases
72+
- TestCase1.test
73+
- TestCase2.test
74+
- ...
75+
- description.md
76+
- TwoSum
77+
- ..
78+
- launguage
79+
- cpp
5680

57-
Just like for LeetCode you have one file where you solve the problem. For example, for the problem called TwoSum there is **problem_builds/problems/TwoSum/cpp/solution.cpp**. To add new test cases you can create a file in **problem_builds/problems/TwoSum/testcases/** directory with the extension **.test** and your solution will be automatically tested against it.
81+
Just like for LeetCode, you have one file where you solve the problem. For example, the problem called TwoSum has **problems/TwoSum/cpp/solution.cpp**. To add new test cases, you can create a file in the **problems/TwoSum/testcases/** directory with the file extension **.test**, and the solution will automatically be tested against it.
5882

59-
The problem is a LeetCode problem description in the ***description.md*** file location in the directory for each problem. For example ***problem_builds/problems/TwoSum/description.md***.
83+
Each problem is described in the ***description.md*** file location in the problem's directory. For example ***problems/TwoSum/description.md***.
6084

61-
The format of the .test files are as follows
85+
The format of the .test files are as follows:
6286

6387
```text
64-
arg1
65-
arg2
66-
expected results
88+
<arg1>
89+
<arg2>
90+
<expected results>
6791
```
6892

69-
Each line is either an integral type (1, 4.6 etc.), or an array of integral types. For example:
93+
Each line is either an integral type, a string, or an array. For example:
7094

7195
```text
72-
[1, 2, 4]
96+
["1", "2", "4"]
7397
8.0
7498
[0, 0]
7599
```
76100

77-
For C++ the supported types are: integral types, strings, vector of integral types.
78-
79101
## List of LeetCode Problems
80102
* TwoSum
81103
* LongestSubstringWithoutRepeatingCharacters
82104
* NumberOfIslands
83105

84-
The problem names are automatically extracted from the folder names inside **data/problems/**.
106+
The problem names are automatically extracted from the **problems** folder.
85107

86108
## Usage
87109
```text
88110
$ python openleetcode.py --help
89111
usage: openleetcode.py [-h] [--language {cpp}] [--list-problems] [--list-testcases] [--problem problem_name] [--problem_builds_dir dir] [--testcase testcase_name] [--verbose]
90112
91-
OpenLeetCode problem builder. This script builds and tests a leetcode like problems locally. Currently, it only supports C++ language but it can be extended to support other languages.
113+
OpenLeetCode problem builder. This script builds and tests LeetCode-like problems locally. Currently, it only supports the C++ language, but it can be extended to support other languages.
92114
93115
options:
94116
-h, --help show this help message and exit
@@ -99,14 +121,16 @@ options:
99121
--problem problem_name, -p problem_name
100122
Name of the problem to build and test. Default: TwoSum. Use --list-problems to list all problems.
101123
--problem_builds_dir dir, -d dir
102-
Path to a directory with the problems. Usually ./problem_builds/ directory. Default: problem_builds.
124+
Specifies the directory with the problems. Typically, this is './problem_builds'. If not provided, the script defaults to './problem_builds' in the same directory as the executable.
125+
--run-expected-tests, -r
126+
Run the expected solution. Default: False.
103127
--testcase testcase_name, -t testcase_name
104128
Name of the testcase to run. '--testcase All' will run all testcases. Default: All.
105129
--verbose, -v Print verbose output
106130
```
107131

108132
## Note
109-
Curently only C++ is supported but the framework is setup such that other languages can be added. Also, the question description and the solution is yet to be worked on.
133+
Curently only C++ is supported but the framework is setup such that other languages can be added.
110134

111135
## Requirements
112136
This project requires the following to run:
@@ -115,6 +139,9 @@ This project requires the following to run:
115139
- CMake 3.12
116140
- Git
117141

142+
#### Additional Requirements for the UI
143+
- npm
144+
118145
## Contributing
119146
Feel free to contribute with code, test cases, or even code reviews.
120147

assets/images/ui_screenshot.PNG

1.04 MB
Loading

data/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
set(DIRECTORIES_TO_COPY problems languages)
22

33
foreach(DIR IN LISTS DIRECTORIES_TO_COPY)
4-
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${DIR} DESTINATION ${PROJECT_BUILDS_DIR})
5-
endforeach()
4+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${DIR}
5+
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6+
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${DIR} DESTINATION ${PROJECT_NAME})
7+
endforeach()

data/languages/cpp/CMakeLists.txt

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,54 @@ FetchContent_MakeAvailable(json)
3131
# Set the build type explicitly
3232
set(CMAKE_BUILD_TYPE Release)
3333

34+
set(CMAKE_BUILD_TYPE Release)
35+
3436
add_executable(solution_cpp)
37+
add_executable(solution_expected_cpp)
3538

36-
target_sources(solution_cpp PRIVATE
37-
# headers
38-
binder.h
39+
target_compile_definitions(solution_expected_cpp PRIVATE EXPECTED)
40+
41+
set(HEADER_FILES
42+
binder.h
3943
comparator.h
4044
parser.h
4145
printer.h
4246
problemtest.h
4347
solutionwrapper.h
4448
stlincludes.h
4549
typetraits.h
50+
)
4651

47-
# sources
52+
set(SOURCE_FILES
4853
main.cpp
4954
problemtest.cpp
5055
)
5156

57+
target_sources(solution_cpp PRIVATE
58+
# headers
59+
${HEADER_FILES}
60+
# sources
61+
${SOURCE_FILES}
62+
)
63+
64+
target_sources(solution_expected_cpp PRIVATE
65+
# headers
66+
${HEADER_FILES}
67+
# sources
68+
${SOURCE_FILES}
69+
)
70+
5271
target_link_libraries(solution_cpp PRIVATE nlohmann_json::nlohmann_json)
72+
target_link_libraries(solution_expected_cpp PRIVATE nlohmann_json::nlohmann_json)
5373

5474
set(CMAKE_INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin)
5575

5676
install(TARGETS solution_cpp
5777
CONFIGURATIONS Release
5878
RUNTIME DESTINATION ${CMAKE_INSTALL_DIR}
5979
)
80+
81+
install(TARGETS solution_expected_cpp
82+
CONFIGURATIONS Release
83+
RUNTIME DESTINATION ${CMAKE_INSTALL_DIR}
84+
)

data/languages/cpp/parser.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
#include "typetraits.h"
1212

13+
void removeOuterSpaces(std::string& value) {
14+
const auto start = value.find_first_not_of(' ');
15+
const auto end = value.find_last_not_of(' ');
16+
value = value.substr(start, end - start + 1);
17+
}
18+
1319
bool hasEncapsulatedTokens(const std::string& str, char start, char end) {
1420
if (str.empty()) {
1521
return false;
@@ -72,6 +78,7 @@ std::vector<std::string> splitIgnoreBrackets(const std::string& str,
7278

7379
template <typename T>
7480
std::enable_if_t<std::is_same_v<char, T>, T> parse(std::string& value) {
81+
removeOuterSpaces(value);
7582
if (value.size() != 3 || !isCharFormatOk(value)) {
7683
std::stringstream ss;
7784
ss << "Error: Invalid char format. Must be of length 3 and contain "
@@ -83,26 +90,30 @@ std::enable_if_t<std::is_same_v<char, T>, T> parse(std::string& value) {
8390

8491
template <typename T>
8592
std::enable_if_t<std::is_same_v<std::string, T>, T> parse(std::string& value) {
93+
removeOuterSpaces(value);
8694
if (!isStringFormatOk(value)) {
8795
std::stringstream ss;
88-
ss << "Error: Invalid string format. Must contain \"s. String: "
89-
<< value;
96+
ss << "Error: Invalid string format. The input string must be enclosed"
97+
" in quotes. Current value: " << value;
9098
throw std::runtime_error(ss.str());
9199
}
92100
return removeQuotes(value);
93101
}
94102

95103
template <typename T>
96104
std::enable_if_t<std::is_integral_v<T>, T> parse(const std::string& value) {
105+
std::string valueCopy = value;
106+
removeOuterSpaces(valueCopy);
97107
T ret{};
98-
std::stringstream ss(value);
108+
std::stringstream ss(valueCopy);
99109
ss >> ret;
100110
return ret;
101111
}
102112

103113
template <typename T>
104114
std::enable_if_t<is_vector_type<T>::value, T> parse(auto&& value) {
105115
using element_type = typename T::value_type;
116+
removeOuterSpaces(value);
106117
T vec;
107118
if (!isArrayFormatOk(value)) {
108119
std::stringstream ss;

0 commit comments

Comments
 (0)