Skip to content
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
52 changes: 52 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ file(GLOB CORE_SOURCES
src/graph/*.hpp
src/data_structure/*.hpp
src/sorting/*.hpp
src/math/*.hpp
)

# Collect test files
Expand All @@ -28,6 +29,7 @@ file(GLOB TEST_SOURCES
tests/graph/*.cpp
tests/data_structure/*.cpp
tests/sorting/*.cpp
tests/math/*.cpp
)

# Combine all sources
Expand Down Expand Up @@ -57,3 +59,53 @@ target_link_libraries(clavis_algorithm_test clavis_algorithm GTest::GTest GTest:

# Register test
add_test(NAME AlgorithmTest COMMAND clavis_algorithm_test)

# =============================================================================
# Code Quality Tools
# =============================================================================

# Collect all C++ files for formatting/linting
file(GLOB_RECURSE ALL_CXX_FILES
${CMAKE_SOURCE_DIR}/src/*.hpp
${CMAKE_SOURCE_DIR}/src/*.cpp
${CMAKE_SOURCE_DIR}/src/*.h
${CMAKE_SOURCE_DIR}/tests/*.cpp
)

# clang-format targets
find_program(CLANG_FORMAT clang-format
HINTS
/opt/homebrew/opt/llvm/bin
/usr/local/opt/llvm/bin
)
if(CLANG_FORMAT)
add_custom_target(format
COMMAND ${CLANG_FORMAT} -i ${ALL_CXX_FILES}
COMMENT "Running clang-format on all files"
VERBATIM
)

add_custom_target(format-check
COMMAND ${CLANG_FORMAT} --dry-run --Werror ${ALL_CXX_FILES}
COMMENT "Checking code format"
VERBATIM
)
else()
message(STATUS "clang-format not found. Format targets disabled.")
endif()

# clang-tidy target
find_program(CLANG_TIDY clang-tidy
HINTS
/opt/homebrew/opt/llvm/bin
/usr/local/opt/llvm/bin
)
if(CLANG_TIDY)
add_custom_target(lint
COMMAND ${CLANG_TIDY} -p ${CMAKE_BINARY_DIR} ${ALL_CXX_FILES}
COMMENT "Running clang-tidy"
VERBATIM
)
else()
message(STATUS "clang-tidy not found. Lint target disabled.")
endif()
4 changes: 2 additions & 2 deletions src/data_structure/binary_search_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ concept Comparable = std::totally_ordered<T> && std::copyable<T>;

template <Comparable T>
class BinarySearchTree {
private:
private:
struct Node {
T value;
std::unique_ptr<Node> left;
Expand All @@ -25,7 +25,7 @@ class BinarySearchTree {
std::unique_ptr<Node> root;
size_t nodeCount = 0;

public:
public:
BinarySearchTree() = default;

void insert(const T& value) {
Expand Down
4 changes: 2 additions & 2 deletions src/data_structure/fenwick_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// Fenwick Tree (Binary Indexed Tree) for handling
// prefix sums over a 1D array with point updates.
class FenwickTree {
public:
public:
explicit FenwickTree(std::size_t n) : size_(n), fenw_(n + 1, 0) {}

// Add 'delta' to element at index 'idx'
Expand Down Expand Up @@ -48,7 +48,7 @@ class FenwickTree {
return query(right) - (left == 0 ? 0 : query(left - 1));
}

private:
private:
std::size_t size_;
std::vector<int> fenw_;
};
Expand Down
4 changes: 2 additions & 2 deletions src/data_structure/max_heap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// This class provides the main operations of a max-heap.
template <typename T>
class MaxHeap {
public:
public:
MaxHeap() = default;

// Insert a new value into the heap
Expand Down Expand Up @@ -49,7 +49,7 @@ class MaxHeap {
// Returns the number of elements in the heap
std::size_t size() const { return data_.size(); }

private:
private:
std::vector<T> data_;

// Restore the heap property by moving the element at index 'idx'
Expand Down
4 changes: 2 additions & 2 deletions src/data_structure/segment_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/
template <typename T>
class SegmentTree {
private:
private:
int n; // Number of leaves
std::vector<T> tree; // Container to store the segment tree
std::function<T(T, T)> op; // Binary operation to merge intervals
Expand All @@ -34,7 +34,7 @@ class SegmentTree {
}
}

public:
public:
/**
* @brief Constructor
*
Expand Down
4 changes: 2 additions & 2 deletions src/data_structure/union_find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ template <typename T>
concept Integral = std::is_integral_v<T>;

class UnionFind {
private:
private:
std::vector<int> parent;
std::vector<int> rank;
int groupCount;
Expand All @@ -20,7 +20,7 @@ class UnionFind {
return x >= 0 && static_cast<size_t>(x) < parent.size();
}

public:
public:
explicit UnionFind(size_t size)
: parent(size), rank(size, 0), groupCount(static_cast<int>(size)) {
std::iota(parent.begin(), parent.end(), 0);
Expand Down
8 changes: 3 additions & 5 deletions src/graph/bfs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ concept HashableNode = GraphNode<T> && requires(T x) {

template <HashableNode NodeType>
class BFS {
private:
private:
using Graph = std::unordered_map<NodeType, std::vector<NodeType>>;
Graph adjacencyList;

void logVisit(const NodeType& node) const {
std::cout << "Visiting node: " << node << std::endl;
}
void logVisit(const NodeType& node) const { std::cout << "Visiting node: " << node << std::endl; }

public:
public:
void addEdge(const NodeType& from, const NodeType& to) {
adjacencyList[from].push_back(to);
// In the case of an isolated point, create an empty adjacent list
Expand Down
21 changes: 10 additions & 11 deletions src/graph/dfs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ concept HashableNode = GraphNode<T> && requires(T x) {

template <HashableNode NodeType>
class DFS {
private:
private:
using Graph = std::unordered_map<NodeType, std::vector<NodeType>>;
Graph adjacencyList;

void logVisit(const NodeType& node) const {
std::cout << "Visiting node: " << node << std::endl;
}
void logVisit(const NodeType& node) const { std::cout << "Visiting node: " << node << std::endl; }

// Helper function for recursive DFS traversal
void traverseRecursive(const NodeType& node, std::unordered_map<NodeType, bool>& visited,
Expand All @@ -44,7 +42,7 @@ class DFS {
}
}

public:
public:
void addEdge(const NodeType& from, const NodeType& to) {
adjacencyList[from].push_back(to);
// In the case of an isolated point, create an empty adjacent list
Expand Down Expand Up @@ -100,7 +98,8 @@ class DFS {
}

// Find path using DFS (not necessarily the shortest)
[[nodiscard]] std::vector<NodeType> findPath(const NodeType& start, const NodeType& target) const {
[[nodiscard]] std::vector<NodeType> findPath(const NodeType& start,
const NodeType& target) const {
std::stack<NodeType> stack;
std::unordered_map<NodeType, bool> visited;
std::unordered_map<NodeType, NodeType> parent;
Expand Down Expand Up @@ -161,7 +160,7 @@ class DFS {
return false;
}

private:
private:
bool hasCycleUtil(const NodeType& node, std::unordered_map<NodeType, bool>& visited,
std::unordered_map<NodeType, bool>& inStack) const {
visited[node] = true;
Expand All @@ -184,7 +183,7 @@ class DFS {
return false;
}

public:
public:
// Topological sort (only works for DAGs)
[[nodiscard]] std::vector<NodeType> topologicalSort() const {
if (hasCycle()) {
Expand All @@ -210,9 +209,9 @@ class DFS {
return result;
}

private:
private:
void topologicalSortUtil(const NodeType& node, std::unordered_map<NodeType, bool>& visited,
std::stack<NodeType>& stack) const {
std::stack<NodeType>& stack) const {
visited[node] = true;

if (auto it = adjacencyList.find(node); it != adjacencyList.end()) {
Expand All @@ -227,7 +226,7 @@ class DFS {
stack.push(node);
}

public:
public:
[[nodiscard]] size_t countConnectedComponents() const {
std::unordered_set<NodeType> unvisited;
for (const auto& [node, _] : adjacencyList) {
Expand Down
12 changes: 4 additions & 8 deletions src/graph/kruskal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,18 @@ struct KruskalEdge {
long long weight;

// Operator for sorting edges by weight
bool operator<(const KruskalEdge& other) const {
return weight < other.weight;
}
bool operator<(const KruskalEdge& other) const { return weight < other.weight; }
};

/**
* @brief Disjoint Set Union (DSU) data structure for Kruskal's algorithm
*/
class DisjointSet {
private:
private:
std::vector<int> parent;
std::vector<int> rank;

public:
public:
/**
* @brief Initialize a DSU with n elements
* @param n Number of elements
Expand Down Expand Up @@ -117,8 +115,6 @@ std::pair<std::vector<KruskalEdge>, long long> kruskal(int n, std::vector<Kruska
* @param mst The MST edges
* @return True if the graph is connected, false otherwise
*/
bool isConnected(int n, const std::vector<KruskalEdge>& mst) {
return mst.size() == n - 1;
}
bool isConnected(int n, const std::vector<KruskalEdge>& mst) { return mst.size() == n - 1; }

#endif // KRUSKAL_HPP
Loading