This repository contains a C++ library that helps to execute Leetcode problems in one line.
header-only version will be available in the future.
- Source file
#include <local_leetcode.hpp>
/*
you solution... e.g.
class Solution {...};
*/
int main() {
// for solution type
EXECS(Solution::method_name);
// for design type
EXECX(CTOR(constructor_types, ...), &Solution::method1, &Solution::method2, ...);
}
- Input format
By default, the program will load the input in Inputs/{source_name.txt} in current working directory. And the structure of the working directory should be
.
├── 01_solution.cpp
├── 02_design.cpp
├── 03_overload.cpp
├── 04_void_return.cpp
└── Inputs
├── 01_solution.txt
├── 02_design.txt
├── 03_overload.txt
└── 04_void_return.txt
if none of the settings are changed (just as examples).
* the input directory and extension can be customized by defining specific MACROs. _LL_INPUT_DIR
and _LL_INPUT_EXT
are used for the directory and extension of input files respectively
Each line of the input file contains all the arguments to execute the {method} or {class} once. The seperator of arguments are ,
, and spaces are skipped also.
Following is the example of int, vector<int>, TreeNode*
as input
1, [1, 2], [1, null, 2]
2, [3, 2], [5, null, 2, null, 3]
For design type, the format of each line is ["{method_names}", ...], [[{arguments}], ...]
.
- Build the library
check section build
- Compilation flags
clang++ -std=c++17 {source_name.cpp} -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -O2 -Ipath/to/local_leetcode/include -Lpath/to/local_leetcode/lib -o {output_executable} -llocal_leetcode
* To use add flag libc++
on non-Mac OS,-stdlib=libc++
is added-stdlib=c++
and link -lc++abi
if -DUSE_LIBC++=on
was enabled for building the library
* to suppress memory leak error, try setting environment variable ASAN_OPTIONS=detect_leaks=0
Check the directory examples for more granular cases.
- Requirements
- cmake (3.16.3 or higher)
- clang++ (11 or higher)
- libcxx or libc++ (no longer enforce the use of libc++)
libc++-dev libc++abi-dev (to use std provided by llvm)- build tool.
make
on linux orninja
(or alike) on windows
- Other details
- to build examples, please add
-DBUILD_EXAMPLES=on
in cmake arguments - to use libc++ on non-macOS machines, please add
-DUSE_LIBC++=on
in cmake arguments- if libc++ is enabled, don't forget to add flag
-stdlib=c++
and link-lc++abi
when compiling executables against the built library
- if libc++ is enabled, don't forget to add flag
- it's not recommended to install the library in the system paths because of its limited usage
- please use soft link (
ln -s
on unix ormklink
on windows) to achieve similar goals.
- to build examples, please add
The requirements should be almost (already) be met on most unix-like OS. Thus following
mkdir build
cd build
# add
# -DBUILD_EXAMPLES=on -DUSE_LIBC++=on
# to enable building examples and use libc++ on non-macos machine
cmake .. -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release
cmake --build .
The built library should be lib/liblocal_leetcode.so (or lib/liblocal_leetcode.dylib on macOS).
Use ln -s
or update ld
configurations to make the library to be loaded at runtime.
To avoid the standard library of msvc
, which is not completely open source, it's better to install gnu/llvm on windows.
After testing several approaches on windows, msys2 is recommended because it's less likely to encounter unsolvable bugs.
As stated in the requirements, from msys2, the following libraries/tools are needed
- clang-toolchain (comes with clang targeted to gnu)
- required libraries should come with the toolchain by default
- ninja (or other preferred build tool)
After other steps like setting PATH
, one can now start building
mkdir build
cd build
:: add
:: -DBUILD_EXAMPLES=on -DUSE_LIBC++=on
:: to enable building examples and use libc++ on non-macos machine
:: please specify correct make target (e.g. Ninja)
cmake .. -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DCMAKE_BUILD_TYPE=Release
cmake --build .
The built library should be in bin/liblocal_leetcode.dll and lib/liblocal_leetcode.dll.a.
Use mklink
to put .dll file in the directory of executables or set PATH
to make the library to be loaded at runtime.
To enable correct Node
type for specific problem from various types, one needs to define macro before the header file.
For example, to use a tree node with four children as typename Node
,
#define QUAD_NODE
#include <local_leetcode>
For more definition of marcos, see the content of the header file, include/local_leetcode.hpp
The macro EXECS
supports overload.
The syntax is
EXECS(Solution::method, return_type, (arg_types, ...));
The library internally distinguishes solution and design types of problems by checking whether the class is trivially constructable.
This logic fails if Solution
has explicit constructors or non-primitive members.
To enforce the behavior of the library under the condition where explicit constructor in Solution
in unavoidable, simply define
#define _LL_NONTRIVIAL_SOLUTION_CTOR
#include <local_leetcode.hpp>
before including the library header file.
This is an optional feature which releases the memory of return pointer, thus avoid memory leaking. The module is implemented by heavy meta-programming techniques and should cover most common data types (e.g. tree). Pointers in form of vector, e.g. std::vector<Node*>
are also supported.
To enable it,
#define _LL_DELETE_RETURN_POINTER
#include <local_leetcode.hpp>
For more details of the supported data types of the feature, see the following section.
This function, ll::destroy(void *)
from include/io/destroyer.hpp, is used to release memories of the interim objects in the heap.
The original purpose of the function is to manage the memory perfectly by the user him/herself, while it came to light that the task was impossible during the development and test. The function remains specifically for someone who wants to manage the memory by oneself without setting ASAN_OPTIONS=detect_leaks=0
.
Supported objects (Node
)
- Single Node
- Linked list
- linked list with
Node* next
- circular doubly-linked list is also supported (not circular singly-linked list)
- linked list with
- Tree
- binary tree with
Node* left
andNode* right
- quad-tree with
Node* topLeft
,Node* topRight
,Node* bottomLeft
andNode* bottomLeft
- trie with
Node* children[N]
(fixed-size array),std::array<Node*, N> children
,std::map<Key, Node*> children
,std::unordered_map<Key, Node*> children
- binary tree with
- Graph
- directed graph (nary tree) with
std::vector<Node*> children
- undirected graph with
std::vector<Node*> neighbors
- directed graph (nary tree) with
- What are the purposes of the library when those websites provide online compilation and execution?
- manage code and test cases in a local directory
- further manage alternative solutions in a cpp file
- debug locally (this is the biggest plus)
- use one's favorite IDE
- Why is built version of the library preferred to header-only one?
- reduce compilation time of solutions drastically
- the exposure of STL symbols contributes (e.g.
std::vector<int>
)
- the exposure of STL symbols contributes (e.g.
- reduce the size of compiled binary of the solution
- Why is the compiler specified as
clang
and not other compilers?
- in line with the instructions from the official site
- same goes for c++ standards and the compilation flags, including asan flags
- same goes for the choice of STL library
libc++
- Can test cases be skipped to avoid some annoying inconveniences, like long outputs blocking the terminal when debugging?
-
Test cases can be commented out by
#
at the beginning of a line to skip it. -
The maximum printed output of
vector<>
type can also be adjusted macros, e.g. use#define _LL_PRINT_ARRAY_MAX_LENGTH 100
to limit the output elements of an array to be non-greater than 100.
For other more specific questions, the wiki will be available in the future.