Skip to content

Commit 98d7352

Browse files
Merge branch 'master' into ctest
2 parents 3863389 + 643e0a9 commit 98d7352

15 files changed

+449
-97
lines changed

.github/workflows/awesome_workflow.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Awesome CI Workflow
22
on: [push, pull_request]
33
permissions:
4+
pull-requests: write
45
contents: write
56

67
jobs:
@@ -13,10 +14,10 @@ jobs:
1314
fetch-depth: 0
1415
- uses: actions/setup-python@v4
1516
- name: requirements
16-
run: |
17+
run: |
1718
sudo apt-get -qq update
1819
sudo apt-get -qq install clang-tidy clang-format
19-
# checks are passing with less errors when used with this version.
20+
# checks are passing with less errors when used with this version.
2021
# The default installs v6.0 which did not work out well in my tests
2122
- name: Setup Git Specs
2223
run: |
@@ -33,8 +34,8 @@ jobs:
3334
git diff --diff-filter=dr --name-only origin/master > git_diff.txt
3435
echo "Files changed-- `cat git_diff.txt`"
3536
- name: Configure for static lint checks
36-
# compiling first gives clang-tidy access to all the header files and settings used to compile the programs.
37-
# This will check for macros, if any, on linux and not for Windows. But the use of portability checks should
37+
# compiling first gives clang-tidy access to all the header files and settings used to compile the programs.
38+
# This will check for macros, if any, on linux and not for Windows. But the use of portability checks should
3839
# be able to catch any errors for other platforms.
3940
run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
4041
- name: Lint modified files

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# The Algorithms - C++ # {#mainpage}
2+
23
<!-- the suffix in the above line is required for doxygen to consider this as the index page of the generated documentation site -->
34

45
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus)
@@ -18,13 +19,13 @@ This repository is a collection of open-source implementation of a variety of al
1819

1920
## Features
2021

21-
* The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B).
22-
* Well documented source code with detailed explanations provide a valuable resource for educators and students alike.
23-
* Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus, the fundamentals of the algorithms can be studied in much depth.
24-
* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS, and Ubuntu (Linux) using MSVC 19 2022, AppleClang 14.0.0, and GNU 11.3.0 respectively.
25-
* Strict adherence to [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) standard ensures portability of code to embedded systems as well like [ESP32](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/cplusplus.html#c-language-standard), [ARM Cortex](https://developer.arm.com/documentation/101458/2404/Standards-support/Supported-C-C---standards-in-Arm-C-C---Compiler), etc. with little to no changes.
26-
* Self-checks within programs ensure correct implementations with confidence.
27-
* Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications.
22+
- The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B).
23+
- Well documented source code with detailed explanations provide a valuable resource for educators and students alike.
24+
- Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus, the fundamentals of the algorithms can be studied in much depth.
25+
- Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS, and Ubuntu (Linux) using MSVC 19 2022, AppleClang 15.0.15, and GNU 13.3.0 respectively.
26+
- Strict adherence to [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) standard ensures portability of code to embedded systems as well like [ESP32](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/cplusplus.html#c-language-standard), [ARM Cortex](https://developer.arm.com/documentation/101458/2404/Standards-support/Supported-C-C---standards-in-Arm-C-C---Compiler), etc. with little to no changes.
27+
- Self-checks within programs ensure correct implementations with confidence.
28+
- Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications.
2829

2930
## Documentation
3031

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* @file
3+
* @brief Implementation to [Check if a number is Even or Odd using Bitwise Operator]
4+
* (https://www.log2base2.com/c-examples/bitwise/odd-or-even-program-in-c-using-bitwise-operator.html)
5+
*
6+
* @details
7+
* Given an integer N, determine whether it is even or odd using bitwise manipulation.
8+
* The least significant bit (LSB) of a binary number determines its parity:
9+
* - If the LSB is 0, the number is even.
10+
* - If the LSB is 1, the number is odd.
11+
*
12+
* This can be checked efficiently using the bitwise AND operator (&) with 1.
13+
* - If (N & 1) == 0, N is even.
14+
* - If (N & 1) == 1, N is odd.
15+
*
16+
* Example:
17+
* Consider 8-bit binary representations of two numbers:
18+
* Number: 10 (decimal) -> 00001010 (binary)
19+
* LSB = 0 -> Even number
20+
*
21+
* Number: 13 (decimal) -> 00001101 (binary)
22+
* LSB = 1 -> Odd number
23+
*
24+
* In both cases, evaluating (N & 1) isolates the LSB:
25+
* - For 10: 00001010 & 00000001 = 0 (Even)
26+
* - For 13: 00001101 & 00000001 = 1 (Odd)
27+
*
28+
* Worst Case Time Complexity: O(1)
29+
* Space Complexity: O(1)
30+
*
31+
* @author [Vedant Mukhedkar](https://github.com/git5v)
32+
*/
33+
34+
#include <cassert> /// for assert
35+
#include <cstdint> /// for uint32_t
36+
#include <iostream> /// for IO operations
37+
#include <string> /// for std::string
38+
39+
/**
40+
* @namespace bit_manipulation
41+
* @brief Bit manipulation algorithms
42+
*/
43+
namespace bit_manipulation {
44+
/**
45+
* @namespace even_odd
46+
* @brief Functions for checking if a number is even or odd using bitwise operations
47+
*/
48+
namespace even_odd {
49+
50+
/**
51+
* @brief Checks if a number is even or odd using bitwise AND.
52+
* @param N The number to check.
53+
* @returns "Even" if N is even, "Odd" if N is odd.
54+
*/
55+
bool is_even(std::int64_t N) {
56+
return (N & 1) == 0 ? true : false;
57+
}
58+
59+
} // namespace even_odd
60+
} // namespace bit_manipulation
61+
62+
/**
63+
* @brief Self-test implementations
64+
* @returns void
65+
*/
66+
static void test() {
67+
using bit_manipulation::even_odd::is_even;
68+
69+
// Test Even numbers
70+
assert(is_even(0) == true);
71+
assert(is_even(2) == true);
72+
assert(is_even(100) == true);
73+
assert(is_even(-4) == true);
74+
assert(is_even(-1000) == true);
75+
76+
// Test Odd numbers
77+
assert(is_even(1) == false);
78+
assert(is_even(3) == false);
79+
assert(is_even(101) == false);
80+
assert(is_even(-5) == false);
81+
assert(is_even(-999) == false);
82+
83+
std::cout << "All test cases successfully passed!" << std::endl;
84+
}
85+
86+
/**
87+
* @brief Main function
88+
* @returns 0 on exit
89+
*/
90+
int main() {
91+
test(); // run self-test implementations
92+
return 0;
93+
}

bit_manipulation/count_of_set_bits.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ namespace count_of_set_bits {
3636
* @returns total number of set-bits in the binary representation of number `n`
3737
*/
3838
std::uint64_t countSetBits(
39-
std ::int64_t n) { // int64_t is preferred over int so that
39+
std ::uint64_t n) { // uint64_t is preferred over int so that
4040
// no Overflow can be there.
41+
//It's preferred over int64_t because it Guarantees that inputs are always non-negative,
42+
//which matches the algorithmic problem statement.
43+
//set bit counting is conceptually defined only for non-negative numbers.
44+
//Provides a type Safety: Using an unsigned type helps prevent accidental negative values,
45+
46+
std::uint64_t count = 0; // "count" variable is used to count number of set-bits('1')
47+
// in binary representation of number 'n'
48+
//Count is uint64_t because it Prevents theoretical overflow if someone passes very large integers.
49+
// Behavior stays the same for all normal inputs.
50+
// Safer for edge cases.
4151

42-
int count = 0; // "count" variable is used to count number of set-bits('1')
43-
// in binary representation of number 'n'
4452
while (n != 0) {
4553
++count;
4654
n = (n & (n - 1));

ciphers/uint128_t.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class uint128_t {
350350
* @brief operator -- (post-decrement)
351351
* @returns decremented value of this
352352
*/
353-
inline uint128_t operator--(int p) {
353+
inline uint128_t operator--(int) {
354354
--*this;
355355
return *this;
356356
}

ciphers/uint256_t.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ class uint256_t {
319319
* @brief operator -- (post-decrement)
320320
* @returns decremented value of this
321321
*/
322-
inline uint256_t operator--(int p) {
322+
inline uint256_t operator--(int) {
323323
--*this;
324324
return *this;
325325
}

data_structures/cll/cll.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Simple data structure CLL (Cicular Linear Linked List)
2+
* Simple data structure CLL (Circular Linear Linked List)
33
* */
44
#include <cctype>
55
#include <cstdlib>

graph/max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ class Graph {
2727
visited.reset();
2828
std::queue<int> q;
2929
q.push(source);
30-
bool is_path_found = false;
31-
while (q.empty() == false && is_path_found == false) {
30+
while (q.empty() == false) {
3231
int current_node = q.front();
3332
visited.set(current_node);
3433
q.pop();

graph/number_of_paths.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* @file
3+
* @brief Algorithm to count paths between two nodes in a directed graph using DFS
4+
* @details
5+
* This algorithm implements Depth First Search (DFS) to count the number of
6+
* possible paths between two nodes in a directed graph. It is represented using
7+
* an adjacency matrix. The algorithm recursively traverses the graph to find
8+
* all paths from the source node `u` to the destination node `v`.
9+
*
10+
* @author [Aditya Borate](https://github.com/adi776borate)
11+
* @see https://en.wikipedia.org/wiki/Path_(graph_theory)
12+
*/
13+
14+
#include <vector> /// for std::vector
15+
#include <iostream> /// for IO operations
16+
#include <cassert> /// for assert
17+
#include <cstdint> /// for fixed-size integer types (e.g., std::uint32_t)
18+
19+
/**
20+
* @namespace graph
21+
* @brief Graph algorithms
22+
*/
23+
namespace graph {
24+
25+
/**
26+
* @brief Helper function to perform DFS and count the number of paths from node `u` to node `v`
27+
* @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
28+
* @param u the starting node
29+
* @param v the destination node
30+
* @param n the number of nodes in the graph
31+
* @param visited a vector to keep track of visited nodes in the current DFS path
32+
* @returns the number of paths from node `u` to node `v`
33+
*/
34+
std::uint32_t count_paths_dfs(const std::vector<std::vector<std::uint32_t>>& A,
35+
std::uint32_t u,
36+
std::uint32_t v,
37+
std::uint32_t n,
38+
std::vector<bool>& visited) {
39+
if (u == v) {
40+
return 1; // Base case: Reached the destination node
41+
}
42+
43+
visited[u] = true; // Mark the current node as visited
44+
std::uint32_t path_count = 0; // Count of all paths from `u` to `v`
45+
46+
for (std::uint32_t i = 0; i < n; i++) {
47+
if (A[u][i] == 1 && !visited[i]) { // Check if there is an edge and the node is not visited
48+
path_count += count_paths_dfs(A, i, v, n, visited); // Recursively explore paths from `i` to `v`
49+
}
50+
}
51+
52+
visited[u] = false; // Unmark the current node as visited (backtracking)
53+
return path_count;
54+
}
55+
56+
57+
/**
58+
* @brief Counts the number of paths from node `u` to node `v` in a directed graph
59+
* using Depth First Search (DFS)
60+
*
61+
* @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
62+
* @param u the starting node
63+
* @param v the destination node
64+
* @param n the number of nodes in the graph
65+
* @returns the number of paths from node `u` to node `v`
66+
*/
67+
std::uint32_t count_paths(const std::vector<std::vector<std::uint32_t>>& A,
68+
std::uint32_t u,
69+
std::uint32_t v,
70+
std::uint32_t n) {
71+
// Check for invalid nodes or empty graph
72+
if (u >= n || v >= n || A.empty() || A[0].empty()) {
73+
return 0; // No valid paths if graph is empty or nodes are out of bounds
74+
}
75+
76+
std::vector<bool> visited(n, false); // Initialize a visited vector for tracking nodes
77+
return count_paths_dfs(A, u, v, n, visited); // Start DFS
78+
}
79+
80+
} // namespace graph
81+
82+
/**
83+
* @brief Self-test implementations
84+
* @returns void
85+
*/
86+
static void test() {
87+
// Test case 1: Simple directed graph with multiple paths
88+
std::vector<std::vector<std::uint32_t>> graph1 = {
89+
{0, 1, 0, 1, 0},
90+
{0, 0, 1, 0, 1},
91+
{0, 0, 0, 0, 1},
92+
{0, 0, 1, 0, 0},
93+
{0, 0, 0, 0, 0}
94+
};
95+
std::uint32_t n1 = 5, u1 = 0, v1 = 4;
96+
assert(graph::count_paths(graph1, u1, v1, n1) == 3); // There are 3 paths from node 0 to 4
97+
98+
// Test case 2: No possible path (disconnected graph)
99+
std::vector<std::vector<std::uint32_t>> graph2 = {
100+
{0, 1, 0, 0, 0},
101+
{0, 0, 0, 0, 0},
102+
{0, 0, 0, 0, 1},
103+
{0, 0, 1, 0, 0},
104+
{0, 0, 0, 0, 0}
105+
};
106+
std::uint32_t n2 = 5, u2 = 0, v2 = 4;
107+
assert(graph::count_paths(graph2, u2, v2, n2) == 0); // No path from node 0 to 4
108+
109+
// Test case 3: Cyclic graph with multiple paths
110+
std::vector<std::vector<std::uint32_t>> graph3 = {
111+
{0, 1, 0, 0, 0},
112+
{0, 0, 1, 1, 0},
113+
{1, 0, 0, 0, 1},
114+
{0, 0, 1, 0, 1},
115+
{0, 0, 0, 0, 0}
116+
};
117+
std::uint32_t n3 = 5, u3 = 0, v3 = 4;
118+
assert(graph::count_paths(graph3, u3, v3, n3) == 3); // There are 3 paths from node 0 to 4
119+
120+
// Test case 4: Single node graph (self-loop)
121+
std::vector<std::vector<std::uint32_t>> graph4 = {
122+
{0}
123+
};
124+
std::uint32_t n4 = 1, u4 = 0, v4 = 0;
125+
assert(graph::count_paths(graph4, u4, v4, n4) == 1); // There is self-loop, so 1 path from node 0 to 0
126+
127+
// Test case 5: Empty graph (no nodes, no paths)
128+
std::vector<std::vector<std::uint32_t>> graph5 = {{}};
129+
int n5 = 0, u5 = 0, v5 = 0;
130+
assert(graph::count_paths(graph5, u5, v5, n5) == 0); // There are no paths in an empty graph
131+
132+
// Test case 6: Invalid nodes (out of bounds)
133+
std::vector<std::vector<std::uint32_t>> graph6 = {
134+
{0, 1, 0},
135+
{0, 0, 1},
136+
{0, 0, 0}
137+
};
138+
int n6 = 3, u6 = 0, v6 = 5; // Node `v` is out of bounds (n = 3, so valid indices are 0, 1, 2)
139+
assert(graph::count_paths(graph6, u6, v6, n6) == 0); // Should return 0 because `v = 5` is invalid
140+
141+
std::cout << "All tests have successfully passed!\n";
142+
}
143+
144+
/**
145+
* @brief Main function
146+
* @returns 0 on exit
147+
*/
148+
int main() {
149+
test(); // Run self-test implementations
150+
return 0;
151+
}

0 commit comments

Comments
 (0)