cpp
exercises
exercises.cpp⚙️cpp
/**
* Inline Functions and Lambda Expressions - Exercises
*
* Practice problems for understanding inline functions and lambdas.
* Each exercise includes TODO sections to complete.
*
* Compile: g++ -std=c++17 -Wall -Wextra exercises.cpp -o exercises
* Run: ./exercises
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
using namespace std;
// ============================================================
// Exercise 1: Inline Max/Min ⭐
// ============================================================
/**
* Create inline functions for max and min of two values.
*/
inline int maxOf(int a, int b) {
// TODO: Return the larger value
return 0;
}
inline int minOf(int a, int b) {
// TODO: Return the smaller value
return 0;
}
// ============================================================
// Exercise 2: Inline Clamp ⭐
// ============================================================
/**
* Clamp a value between low and high bounds.
*/
inline int clamp(int value, int low, int high) {
// TODO: Return value clamped to [low, high]
return 0;
}
// ============================================================
// Exercise 3: Basic Lambda ⭐
// ============================================================
/**
* Create lambdas stored in variables.
*/
void exercise3() {
// TODO: Create a lambda 'square' that takes int and returns its square
auto square = [](int x) { return 0; };
// TODO: Create a lambda 'isEven' that takes int and returns bool
auto isEven = [](int x) { return false; };
// TODO: Create a lambda 'greet' that takes string and prints greeting
auto greet = [](const string& name) { };
cout << "square(5) = " << square(5) << " (expected: 25)" << endl;
cout << "isEven(4) = " << boolalpha << isEven(4) << " (expected: true)" << endl;
greet("Alice");
}
// ============================================================
// Exercise 4: Capture by Value ⭐⭐
// ============================================================
/**
* Use capture by value to create a multiplier.
*/
void exercise4() {
int factor = 3;
// TODO: Create lambda that captures 'factor' by value
// and multiplies input by factor
auto multiply = [](int x) { return 0; };
factor = 100; // This should NOT affect the lambda
cout << "multiply(5) = " << multiply(5) << " (expected: 15)" << endl;
}
// ============================================================
// Exercise 5: Capture by Reference ⭐⭐
// ============================================================
/**
* Use capture by reference to create a counter.
*/
void exercise5() {
int count = 0;
// TODO: Create lambda that captures 'count' by reference
// and increments it each time called
auto increment = []() { };
increment();
increment();
increment();
cout << "Count after 3 increments: " << count << " (expected: 3)" << endl;
}
// ============================================================
// Exercise 6: Mutable Lambda ⭐⭐
// ============================================================
/**
* Create a counter using mutable capture.
*/
void exercise6() {
// TODO: Create a lambda with captured counter initialized to 0
// Use mutable to allow modifying the captured copy
// Return the current count after incrementing
auto counter = []() { return 0; };
cout << "counter() calls: ";
cout << counter() << " "; // 1
cout << counter() << " "; // 2
cout << counter() << " "; // 3
cout << "(expected: 1 2 3)" << endl;
}
// ============================================================
// Exercise 7: Sort with Lambda ⭐⭐
// ============================================================
/**
* Use lambdas with std::sort.
*/
void exercise7() {
vector<int> nums = {5, 2, 8, 1, 9, 3};
// TODO: Sort in descending order using lambda
// sort(nums.begin(), nums.end(), /* lambda */);
cout << "Descending: ";
for (int n : nums) cout << n << " ";
cout << "(expected: 9 8 5 3 2 1)" << endl;
vector<string> words = {"apple", "pie", "blueberry", "a"};
// TODO: Sort by string length using lambda
// sort(words.begin(), words.end(), /* lambda */);
cout << "By length: ";
for (const string& s : words) cout << s << " ";
cout << "(expected: a pie apple blueberry)" << endl;
}
// ============================================================
// Exercise 8: Find with Lambda ⭐⭐
// ============================================================
/**
* Use lambdas with std::find_if.
*/
void exercise8() {
vector<int> nums = {1, 3, 5, 8, 9, 12};
// TODO: Find first even number using find_if
auto it = nums.end(); // Replace with find_if
if (it != nums.end()) {
cout << "First even: " << *it << " (expected: 8)" << endl;
}
// TODO: Find first number > 10 using find_if
it = nums.end(); // Replace with find_if
if (it != nums.end()) {
cout << "First > 10: " << *it << " (expected: 12)" << endl;
}
}
// ============================================================
// Exercise 9: Count with Lambda ⭐⭐
// ============================================================
/**
* Use lambdas with std::count_if.
*/
void exercise9() {
vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// TODO: Count numbers > 5
int countGreater5 = 0; // Use count_if
// TODO: Count even numbers
int countEven = 0; // Use count_if
// TODO: Count numbers divisible by 3
int countDiv3 = 0; // Use count_if
cout << "Count > 5: " << countGreater5 << " (expected: 5)" << endl;
cout << "Count even: " << countEven << " (expected: 5)" << endl;
cout << "Count divisible by 3: " << countDiv3 << " (expected: 3)" << endl;
}
// ============================================================
// Exercise 10: Transform with Lambda ⭐⭐
// ============================================================
/**
* Use lambdas with std::transform.
*/
void exercise10() {
vector<int> nums = {1, 2, 3, 4, 5};
vector<int> result;
// TODO: Create vector of squares using transform
// transform(nums.begin(), nums.end(), back_inserter(result), /* lambda */);
cout << "Squares: ";
for (int n : result) cout << n << " ";
cout << "(expected: 1 4 9 16 25)" << endl;
vector<string> words = {"hello", "world"};
vector<size_t> lengths;
// TODO: Get lengths of each string using transform
// transform(words.begin(), words.end(), back_inserter(lengths), /* lambda */);
cout << "Lengths: ";
for (size_t len : lengths) cout << len << " ";
cout << "(expected: 5 5)" << endl;
}
// ============================================================
// Exercise 11: Filter with Lambda ⭐⭐⭐
// ============================================================
/**
* Use lambdas to filter elements.
*/
void exercise11() {
vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// TODO: Remove all even numbers using remove_if + erase
// nums.erase(remove_if(...), nums.end());
cout << "After removing evens: ";
for (int n : nums) cout << n << " ";
cout << "(expected: 1 3 5 7 9)" << endl;
}
// ============================================================
// Exercise 12: Generic Lambda ⭐⭐⭐
// ============================================================
/**
* Create generic lambdas using auto parameters.
*/
void exercise12() {
// TODO: Create a generic 'print' lambda that works with any type
auto print = [](const auto& value) { };
cout << "Generic print: ";
print(42);
print(" | ");
print(3.14);
print(" | ");
print("hello");
cout << endl;
// TODO: Create a generic 'add' lambda that works with any type
auto add = [](auto a, auto b) { return a + b; };
cout << "add(1, 2) = " << add(1, 2) << endl;
cout << "add(1.5, 2.5) = " << add(1.5, 2.5) << endl;
cout << "add(string, string) = " << add(string("Hello "), string("World")) << endl;
}
// ============================================================
// Exercise 13: Lambda Factory ⭐⭐⭐
// ============================================================
/**
* Create a function that returns lambdas.
*/
function<int(int)> makeMultiplier(int factor) {
// TODO: Return a lambda that multiplies input by factor
return [](int x) { return 0; };
}
void exercise13() {
auto times2 = makeMultiplier(2);
auto times5 = makeMultiplier(5);
auto times10 = makeMultiplier(10);
cout << "times2(7) = " << times2(7) << " (expected: 14)" << endl;
cout << "times5(7) = " << times5(7) << " (expected: 35)" << endl;
cout << "times10(7) = " << times10(7) << " (expected: 70)" << endl;
}
// ============================================================
// Exercise 14: Accumulate with Lambda ⭐⭐⭐
// ============================================================
/**
* Use lambdas with std::accumulate.
*/
void exercise14() {
vector<int> nums = {1, 2, 3, 4, 5};
// TODO: Calculate product using accumulate with lambda
int product = 1; // Use accumulate
// TODO: Calculate sum of squares using accumulate with lambda
int sumOfSquares = 0; // Use accumulate
// TODO: Find max using accumulate with lambda
int maxVal = 0; // Use accumulate
cout << "Product: " << product << " (expected: 120)" << endl;
cout << "Sum of squares: " << sumOfSquares << " (expected: 55)" << endl;
cout << "Max: " << maxVal << " (expected: 5)" << endl;
}
// ============================================================
// Exercise 15: Callback System ⭐⭐⭐
// ============================================================
/**
* Create a simple callback/event system using std::function.
*/
class EventEmitter {
private:
vector<function<void(int)>> listeners;
public:
void addListener(function<void(int)> callback) {
// TODO: Add callback to listeners
}
void emit(int value) {
// TODO: Call all listeners with value
}
};
void exercise15() {
EventEmitter emitter;
emitter.addListener([](int v) { cout << "Listener 1: " << v << endl; });
emitter.addListener([](int v) { cout << "Listener 2: " << v * 2 << endl; });
emitter.addListener([](int v) { cout << "Listener 3: " << v * v << endl; });
cout << "Emitting 5:" << endl;
emitter.emit(5);
}
// ============================================================
// TEST RUNNER
// ============================================================
void testExercise1() {
cout << "\n=== Exercise 1: Inline Max/Min ===" << endl;
cout << "maxOf(5, 3) = " << maxOf(5, 3) << " (expected: 5)" << endl;
cout << "minOf(5, 3) = " << minOf(5, 3) << " (expected: 3)" << endl;
}
void testExercise2() {
cout << "\n=== Exercise 2: Inline Clamp ===" << endl;
cout << "clamp(15, 0, 10) = " << clamp(15, 0, 10) << " (expected: 10)" << endl;
cout << "clamp(-5, 0, 10) = " << clamp(-5, 0, 10) << " (expected: 0)" << endl;
cout << "clamp(5, 0, 10) = " << clamp(5, 0, 10) << " (expected: 5)" << endl;
}
void testExercise3() {
cout << "\n=== Exercise 3: Basic Lambda ===" << endl;
exercise3();
}
void testExercise4() {
cout << "\n=== Exercise 4: Capture by Value ===" << endl;
exercise4();
}
void testExercise5() {
cout << "\n=== Exercise 5: Capture by Reference ===" << endl;
exercise5();
}
void testExercise6() {
cout << "\n=== Exercise 6: Mutable Lambda ===" << endl;
exercise6();
}
void testExercise7() {
cout << "\n=== Exercise 7: Sort with Lambda ===" << endl;
exercise7();
}
void testExercise8() {
cout << "\n=== Exercise 8: Find with Lambda ===" << endl;
exercise8();
}
void testExercise9() {
cout << "\n=== Exercise 9: Count with Lambda ===" << endl;
exercise9();
}
void testExercise10() {
cout << "\n=== Exercise 10: Transform with Lambda ===" << endl;
exercise10();
}
void testExercise11() {
cout << "\n=== Exercise 11: Filter with Lambda ===" << endl;
exercise11();
}
void testExercise12() {
cout << "\n=== Exercise 12: Generic Lambda ===" << endl;
exercise12();
}
void testExercise13() {
cout << "\n=== Exercise 13: Lambda Factory ===" << endl;
exercise13();
}
void testExercise14() {
cout << "\n=== Exercise 14: Accumulate with Lambda ===" << endl;
exercise14();
}
void testExercise15() {
cout << "\n=== Exercise 15: Callback System ===" << endl;
exercise15();
}
// ============================================================
// MAIN FUNCTION
// ============================================================
int main() {
cout << "╔════════════════════════════════════════════════════════════╗" << endl;
cout << "║ INLINE FUNCTIONS & LAMBDAS - EXERCISES ║" << endl;
cout << "╚════════════════════════════════════════════════════════════╝" << endl;
testExercise1();
testExercise2();
testExercise3();
testExercise4();
testExercise5();
testExercise6();
testExercise7();
testExercise8();
testExercise9();
testExercise10();
testExercise11();
testExercise12();
testExercise13();
testExercise14();
testExercise15();
cout << "\n╔════════════════════════════════════════════════════════════╗" << endl;
cout << "║ Complete the TODO sections and re-run! ║" << endl;
cout << "╚════════════════════════════════════════════════════════════╝" << endl;
return 0;
}
// ============================================================
// ANSWER KEY
// ============================================================
/*
// Exercise 1
inline int maxOf(int a, int b) { return (a > b) ? a : b; }
inline int minOf(int a, int b) { return (a < b) ? a : b; }
// Exercise 2
inline int clamp(int value, int low, int high) {
if (value < low) return low;
if (value > high) return high;
return value;
}
// Exercise 3
auto square = [](int x) { return x * x; };
auto isEven = [](int x) { return x % 2 == 0; };
auto greet = [](const string& name) { cout << "Hello, " << name << "!" << endl; };
// Exercise 4
auto multiply = [factor](int x) { return x * factor; };
// Exercise 5
auto increment = [&count]() { count++; };
// Exercise 6
auto counter = [count = 0]() mutable { return ++count; };
// Exercise 7
sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; });
sort(words.begin(), words.end(), [](const string& a, const string& b) { return a.length() < b.length(); });
// Exercise 8
auto it = find_if(nums.begin(), nums.end(), [](int n) { return n % 2 == 0; });
it = find_if(nums.begin(), nums.end(), [](int n) { return n > 10; });
// Exercise 9
int countGreater5 = count_if(nums.begin(), nums.end(), [](int n) { return n > 5; });
int countEven = count_if(nums.begin(), nums.end(), [](int n) { return n % 2 == 0; });
int countDiv3 = count_if(nums.begin(), nums.end(), [](int n) { return n % 3 == 0; });
// Exercise 10
transform(nums.begin(), nums.end(), back_inserter(result), [](int n) { return n * n; });
transform(words.begin(), words.end(), back_inserter(lengths), [](const string& s) { return s.length(); });
// Exercise 11
nums.erase(remove_if(nums.begin(), nums.end(), [](int n) { return n % 2 == 0; }), nums.end());
// Exercise 12
auto print = [](const auto& value) { cout << value; };
auto add = [](auto a, auto b) { return a + b; };
// Exercise 13
function<int(int)> makeMultiplier(int factor) {
return [factor](int x) { return x * factor; };
}
// Exercise 14
int product = accumulate(nums.begin(), nums.end(), 1, [](int a, int b) { return a * b; });
int sumOfSquares = accumulate(nums.begin(), nums.end(), 0, [](int a, int b) { return a + b * b; });
int maxVal = accumulate(nums.begin(), nums.end(), nums[0], [](int a, int b) { return max(a, b); });
// Exercise 15
void addListener(function<void(int)> callback) {
listeners.push_back(callback);
}
void emit(int value) {
for (auto& listener : listeners) {
listener(value);
}
}
*/