Skip to content

Commit 35fe129

Browse files
Merge branch 'master' into feat/grid_unique_path
2 parents 5e5b2cd + 8541bb3 commit 35fe129

File tree

3 files changed

+202
-65
lines changed

3 files changed

+202
-65
lines changed
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));

others/postfix_evaluation.cpp

Lines changed: 98 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @file
3-
* @brief Evaluation of [Postfix Expression](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
3+
* @brief Evaluation of [Postfix
4+
* Expression](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
45
* @author [Darshana Sarma](https://github.com/Darshana-Sarma)
56
* @details
67
* Create a stack to store operands (or values).
@@ -11,10 +12,11 @@
1112
* When the expression is ended, the number in the stack is the final answer
1213
*/
1314
#include <algorithm> // for all_of
14-
#include <array> // for std::array
1515
#include <cassert> // for assert
1616
#include <iostream> // for io operations
17+
#include <stack> // for std::stack
1718
#include <string> // for stof
19+
#include <vector> // for std::vector
1820

1921
/**
2022
* @namespace others
@@ -26,36 +28,6 @@ namespace others {
2628
* @brief Functions for Postfix Expression algorithm
2729
*/
2830
namespace postfix_expression {
29-
/**
30-
* @brief Creates an array to be used as stack for storing values
31-
*/
32-
class Stack {
33-
public:
34-
std::array<float, 20> stack{}; ///< Array which will be used to store numbers in the input
35-
int stackTop = -1; ///< Represents the index of the last value added to array. -1 means array is empty
36-
};
37-
38-
/**
39-
* @brief Pushing operand, also called the number in the array to the stack
40-
* @param operand float value from the input array or evaluation
41-
* @param stack stack containing numbers
42-
* @returns none
43-
*/
44-
void push(float operand, Stack *stack) {
45-
stack->stackTop++;
46-
stack->stack[stack->stackTop] = operand;
47-
}
48-
49-
/**
50-
* @brief Popping operand, also called the number from the stack
51-
* @param stack stack containing numbers
52-
* @returns operand float on top of stack
53-
*/
54-
float pop(Stack *stack) {
55-
float operand = stack->stack[stack->stackTop];
56-
stack->stackTop--;
57-
return operand;
58-
}
5931

6032
/**
6133
* @brief Checks if scanned string is a number
@@ -74,28 +46,29 @@ bool is_number(const std::string &s) {
7446
* @param stack containing numbers
7547
* @returns none
7648
*/
77-
void evaluate(float a, float b, const std::string &operation, Stack *stack) {
49+
void evaluate(float a, float b, const std::string &operation,
50+
std::stack<float> &stack) {
7851
float c = 0;
7952
const char *op = operation.c_str();
8053
switch (*op) {
8154
case '+':
82-
c = a + b; // Addition of numbers
83-
others::postfix_expression::push(c, stack);
55+
c = a + b; // Addition of numbers
56+
stack.push(c);
8457
break;
8558

8659
case '-':
87-
c = a - b; // Subtraction of numbers
88-
others::postfix_expression::push(c, stack);
60+
c = a - b; // Subtraction of numbers
61+
stack.push(c);
8962
break;
9063

9164
case '*':
92-
c = a * b; // Multiplication of numbers
93-
others::postfix_expression::push(c, stack);
65+
c = a * b; // Multiplication of numbers
66+
stack.push(c);
9467
break;
9568

9669
case '/':
97-
c = a / b; // Division of numbers
98-
others::postfix_expression::push(c, stack);
70+
c = a / b; // Division of numbers
71+
stack.push(c);
9972
break;
10073

10174
default:
@@ -104,47 +77,54 @@ void evaluate(float a, float b, const std::string &operation, Stack *stack) {
10477
}
10578
}
10679

80+
namespace {
81+
float remove_from_stack(std::stack<float> &stack) {
82+
if (stack.empty()) {
83+
throw std::invalid_argument("Not enough operands");
84+
}
85+
const auto res = stack.top();
86+
stack.pop();
87+
return res;
88+
}
89+
} // namespace
90+
10791
/**
10892
* @brief Postfix Evaluation algorithm to compute the value from given input
10993
* array
110-
* @tparam N number of array size
111-
* @param input Array of characters consisting of numbers and operations
94+
* @param input vector of strings consisting of numbers and operations
11295
* @returns stack[stackTop] returns the top value from the stack
11396
*/
114-
template <std::size_t N>
115-
float postfix_evaluation(std::array<std::string, N> input) {
116-
Stack stack;
117-
int j = 0;
97+
float postfix_evaluation(const std::vector<std::string> &input) {
98+
std::stack<float> stack;
11899

119-
while (j < N) {
120-
std::string scan = input[j];
100+
for (const auto &scan : input) {
121101
if (is_number(scan)) {
122-
push(std::stof(scan), &stack);
102+
stack.push(std::stof(scan));
123103

124104
} else {
125-
float op2 = pop(&stack);
126-
float op1 = pop(&stack);
105+
const auto op2 = remove_from_stack(stack);
106+
const auto op1 = remove_from_stack(stack);
127107

128-
evaluate(op1, op2, scan, &stack);
108+
evaluate(op1, op2, scan, stack);
129109
}
130-
j++;
131110
}
132111

133-
std::cout << stack.stack[stack.stackTop] << "\n";
134-
135-
return stack.stack[stack.stackTop];
112+
const auto res = remove_from_stack(stack);
113+
if (!stack.empty()) {
114+
throw std::invalid_argument("Too many operands");
115+
}
116+
return res;
136117
}
137118
} // namespace postfix_expression
138119
} // namespace others
139120

140-
141121
/**
142122
* @brief Test function 1 with input array
143123
* {'2', '3', '1', '*', '+', '9', '-'}
144124
* @returns none
145125
*/
146126
static void test_function_1() {
147-
std::array<std::string, 7> input = {"2", "3", "1", "*", "+", "9", "-"};
127+
std::vector<std::string> input = {"2", "3", "1", "*", "+", "9", "-"};
148128

149129
float answer = others::postfix_expression::postfix_evaluation(input);
150130

@@ -153,24 +133,80 @@ static void test_function_1() {
153133

154134
/**
155135
* @brief Test function 2 with input array
156-
* {'1', '2', '+', '2', '/', '5', '*', '7', '+'}
136+
* {'100', '200', '+', '2', '/', '5', '*', '7', '+'}
157137
* @returns none
158138
*/
159139
static void test_function_2() {
160-
std::array<std::string, 9> input = {"100", "200", "+", "2", "/",
161-
"5", "*", "7", "+"};
140+
std::vector<std::string> input = {"100", "200", "+", "2", "/",
141+
"5", "*", "7", "+"};
162142
float answer = others::postfix_expression::postfix_evaluation(input);
163143

164144
assert(answer == 757);
165145
}
166146

147+
static void test_function_3() {
148+
std::vector<std::string> input = {
149+
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
150+
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
151+
"+", "+", "+", "+", "+", "+", "+", "+", "+", "+", "+",
152+
"+", "+", "+", "+", "+", "+", "+", "+", "+", "+"};
153+
float answer = others::postfix_expression::postfix_evaluation(input);
154+
155+
assert(answer == 22);
156+
}
157+
158+
static void test_single_input() {
159+
std::vector<std::string> input = {"1"};
160+
float answer = others::postfix_expression::postfix_evaluation(input);
161+
162+
assert(answer == 1);
163+
}
164+
165+
static void test_not_enough_operands() {
166+
std::vector<std::string> input = {"+"};
167+
bool throws = false;
168+
try {
169+
others::postfix_expression::postfix_evaluation(input);
170+
} catch (std::invalid_argument &) {
171+
throws = true;
172+
}
173+
assert(throws);
174+
}
175+
176+
static void test_not_enough_operands_empty_input() {
177+
std::vector<std::string> input = {};
178+
bool throws = false;
179+
try {
180+
others::postfix_expression::postfix_evaluation(input);
181+
} catch (std::invalid_argument &) {
182+
throws = true;
183+
}
184+
assert(throws);
185+
}
186+
187+
static void test_too_many_operands() {
188+
std::vector<std::string> input = {"1", "2"};
189+
bool throws = false;
190+
try {
191+
others::postfix_expression::postfix_evaluation(input);
192+
} catch (std::invalid_argument &) {
193+
throws = true;
194+
}
195+
assert(throws);
196+
}
197+
167198
/**
168199
* @brief Main function
169200
* @returns 0 on exit
170201
*/
171202
int main() {
172203
test_function_1();
173204
test_function_2();
205+
test_function_3();
206+
test_single_input();
207+
test_not_enough_operands();
208+
test_not_enough_operands_empty_input();
209+
test_too_many_operands();
174210

175211
std::cout << "\nTest implementations passed!\n";
176212

0 commit comments

Comments
 (0)