cpp

exercises

exercises.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);
    }
}
*/
Exercises - C++ Tutorial | DeepML