Bit by Bit

From fundamentals to data structures and algorithms

Beginner

Variables and Data Types Beginner
Introduction to built-in types: int, double, char, bool.

#include <iostream>

int main() {
  int a = 5;
  double b = 3.14;
  char c = 'Z';
  bool flag = true;
  std::cout << "a = " << a << "\n";
  return 0;
}
    
Basic Input and Output Beginner
Using std::cin and std::cout for console I/O.

#include <iostream>
#include <string>

int main() {
  std::string name;
  std::cout << "Enter your name: ";
  std::getline(std::cin, name);
  std::cout << "Hello, " << name << "!\n";
  return 0;
}
    
Control Flow Beginner
Conditionals: if, else if, else, and switch statements.

#include <iostream>

int main() {
  int x;
  std::cout << "Enter a number: ";
  std::cin >> x;

  if (x < 0)
    std::cout << "Negative\n";
  else if (x == 0)
    std::cout << "Zero\n";
  else
    std::cout << "Positive\n";

  return 0;
}
    
Loops Beginner
Iteration with for and while loops.

#include <iostream>

int main() {
  for (int i = 0; i < 5; i++) {
    std::cout << i << " ";
  }
  std::cout << "\n";

  int j = 5;
  while (j > 0) {
    std::cout << j-- << " ";
  }
  return 0;
}
    
Functions Beginner
Defining and invoking simple functions.

#include <iostream>

int add(int x, int y) {
  return x + y;
}

int main() {
  std::cout << "4 + 7 = " << add(4, 7) << "\n";
  return 0;
}
    

Intermediate

Pointers and References Intermediate
Working with raw pointers and references to manipulate variables.

#include <iostream>

void addOne(int& ref) {
  ref++;
}

int main() {
  int value = 5;
  addOne(value);    // value is now 6
  int* ptr = &value;
  (*ptr)++;         // value is now 7
  std::cout << "value = " << value << "\n";
  return 0;
}
    
Dynamic Memory & Smart Pointers Intermediate
Allocating on the heap and managing ownership with unique_ptr.

#include <iostream>
#include <memory>

int main() {
  // raw pointer (manual delete required)
  int* raw = new int(42);
  std::cout << *raw << "\n";
  delete raw;

  // smart pointer (automatic cleanup)
  auto smart = std::make_unique<int>(7);
  std::cout << *smart << "\n";

  return 0;
}
    
File Input/Output Intermediate
Reading from and writing to files using fstream.

#include <iostream>
#include <fstream>
#include <string>

int main() {
  std::ofstream out("data.txt");
  out << "Line one\nLine two\n";
  out.close();

  std::ifstream in("data.txt");
  std::string line;
  while (std::getline(in, line)) {
    std::cout << line << "\n";
  }
  return 0;
}
    
STL Containers Intermediate
Using std::vector and std::map for dynamic arrays and key-value storage.

#include <iostream>
#include <vector>
#include <map>

int main() {
  std::vector<int> nums = {1, 2, 3};
  nums.push_back(4);

  std::map<std::string, int> ages;
  ages["Alice"] = 30;
  ages["Bob"] = 25;

  for (auto n : nums)
    std::cout << n << " ";
  std::cout << "\n";

  std::cout << "Alice is " << ages["Alice"] << "\n";
  return 0;
}
    
Algorithms & Lambda Expressions Intermediate
Sorting, deduplication, and inline anonymous functions.

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
  std::vector<int> v = {3, 1, 4, 1, 5};
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());

  std::cout << "Unique sorted:";
  for (auto n : v) std::cout << " " << n;
  std::cout << "\n";

  int evens = std::count_if(v.begin(), v.end(),
                            [](int x) { return x % 2 == 0; });
  std::cout << "Even count: " << evens << "\n";
  return 0;
}
    

Math Algorithms

Greatest Common Divisor (GCD) Math
Euclidean algorithm for finding the GCD of two integers.

#include <iostream>

int gcd(int a, int b) {
  while (b != 0) {
    int temp = b;
    b = a % b;
    a = temp;
  }
  return a;
}

int main() {
  int x = 48, y = 18;
  std::cout << "GCD(" << x << ", " << y << ") = " << gcd(x, y) << "\n";
  return 0;
}
    
Least Common Multiple (LCM) Math
Using GCD to compute the LCM efficiently.

#include <iostream>

int gcd(int a, int b) {
  return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
  return (a / gcd(a, b)) * b;
}

int main() {
  int x = 12, y = 18;
  std::cout << "LCM(" << x << ", " << y << ") = " << lcm(x, y) << "\n";
  return 0;
}
    
Prime Number Check Math
Efficient primality test up to √n.

#include <iostream>
#include <cmath>

bool isPrime(int n) {
  if (n <= 1) return false;
  if (n <= 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  for (int i = 5; i * i <= n; i += 6) {
    if (n % i == 0 || n % (i + 2) == 0) return false;
  }
  return true;
}

int main() {
  int num = 29;
  std::cout << num << (isPrime(num) ? " is prime\n" : " is not prime\n");
  return 0;
}
    
Sieve of Eratosthenes Math
Generate all primes up to N efficiently.

#include <iostream>
#include <vector>

void sieve(int n) {
  std::vector<bool> prime(n+1, true);
  prime[0] = prime[1] = false;
  for (int p = 2; p * p <= n; p++) {
    if (prime[p]) {
      for (int i = p * p; i <= n; i += p)
        prime[i] = false;
    }
  }
  for (int i = 2; i <= n; i++) {
    if (prime[i]) std::cout << i << " ";
  }
}

int main() {
  sieve(50);
  return 0;
}
    
Fast Exponentiation (Binary Exponentiation) Math
Exponentiation by squaring for O(log n) power calculation.

#include <iostream>

long long power(long long base, long long exp) {
  long long result = 1;
  while (exp > 0) {
    if (exp & 1) result *= base;
    base *= base;
    exp >>= 1;
  }
  return result;
}

int main() {
  std::cout << "2^10 = " << power(2, 10) << "\n";
  return 0;
}
    

Data Structures

Arrays DS
Fixed-size sequential storage for elements of the same type.

#include <iostream>

int main() {
  int arr[5] = {1, 2, 3, 4, 5};
  for (int i = 0; i < 5; i++) {
    std::cout << arr[i] << " ";
  }
  return 0;
}
    
Vectors DS
Dynamic arrays with automatic resizing from the STL.

#include <iostream>
#include <vector>

int main() {
  std::vector<int> v = {1, 2, 3};
  v.push_back(4);
  for (int n : v) {
    std::cout << n << " ";
  }
  return 0;
}
    
Linked List DS
Nodes connected via pointers for dynamic memory usage.

#include <iostream>

struct Node {
  int data;
  Node* next;
};

int main() {
  Node a{1, nullptr};
  Node b{2, nullptr};
  a.next = &b;

  Node* head = &a;
  while (head) {
    std::cout << head->data << " ";
    head = head->next;
  }
  return 0;
}
    
Stack DS
LIFO (Last In, First Out) structure using std::stack.

#include <iostream>
#include <stack>

int main() {
  std::stack<int> s;
  s.push(10);
  s.push(20);
  s.push(30);

  while (!s.empty()) {
    std::cout << s.top() << " ";
    s.pop();
  }
  return 0;
}
    
Queue DS
FIFO (First In, First Out) structure using std::queue.

#include <iostream>
#include <queue>

int main() {
  std::queue<int> q;
  q.push(1);
  q.push(2);
  q.push(3);

  while (!q.empty()) {
    std::cout << q.front() << " ";
    q.pop();
  }
  return 0;
}
    

Advanced Data Structures

Binary Search Tree (BST) Advanced DS
Hierarchical structure for ordered data with efficient search, insert, and delete.

#include <iostream>

struct Node {
  int key;
  Node* left;
  Node* right;
  Node(int k) : key(k), left(nullptr), right(nullptr) {}
};

Node* insert(Node* root, int key) {
  if (!root) return new Node(key);
  if (key < root->key) root->left = insert(root->left, key);
  else if (key > root->key) root->right = insert(root->right, key);
  return root;
}

void inorder(Node* root) {
  if (!root) return;
  inorder(root->left);
  std::cout << root->key << " ";
  inorder(root->right);
}

int main() {
  Node* root = nullptr;
  root = insert(root, 5);
  insert(root, 3);
  insert(root, 7);
  inorder(root);
  return 0;
}
    
Heap (Priority Queue) Advanced DS
Binary heap for efficient retrieval of min/max elements using std::priority_queue.

#include <iostream>
#include <queue>
#include <vector>

int main() {
  std::priority_queue<int> maxHeap;
  maxHeap.push(10);
  maxHeap.push(5);
  maxHeap.push(20);

  while (!maxHeap.empty()) {
    std::cout << maxHeap.top() << " ";
    maxHeap.pop();
  }
  return 0;
}
    
Graph (Adjacency List) Advanced DS
Graph representation using adjacency lists for efficient traversal.

#include <iostream>
#include <vector>

int main() {
  int V = 5;
  std::vector<std::vector<int>> adj(V);

  adj[0].push_back(1);
  adj[0].push_back(4);
  adj[1].push_back(2);
  adj[1].push_back(3);

  for (int i = 0; i < V; i++) {
    std::cout << i << ": ";
    for (int v : adj[i]) std::cout << v << " ";
    std::cout << "\n";
  }
  return 0;
}
    
Hash Table (unordered_map) Advanced DS
Key-value storage with average O(1) access using hashing.

#include <iostream>
#include <unordered_map>

int main() {
  std::unordered_map<std::string, int> freq;
  freq["apple"]++;
  freq["banana"] += 2;

  for (auto& [key, val] : freq) {
    std::cout << key << ": " << val << "\n";
  }
  return 0;
}
    
Trie (Prefix Tree) Advanced DS
Tree-like structure for efficient string storage and prefix queries.

#include <iostream>
#include <unordered_map>
#include <string>

struct TrieNode {
  bool isEnd;
  std::unordered_map<char, TrieNode*> children;
  TrieNode() : isEnd(false) {}
};

void insert(TrieNode* root, const std::string& word) {
  TrieNode* node = root;
  for (char c : word) {
    if (!node->children[c]) node->children[c] = new TrieNode();
    node = node->children[c];
  }
  node->isEnd = true;
}

bool search(TrieNode* root, const std::string& word) {
  TrieNode* node = root;
  for (char c : word) {
    if (!node->children[c]) return false;
    node = node->children[c];
  }
  return node->isEnd;
}

int main() {
  TrieNode* root = new TrieNode();
  insert(root, "cat");
  insert(root, "car");
  std::cout << std::boolalpha << search(root, "cat") << "\n";
  std::cout << search(root, "cap") << "\n";
  return 0;
}
    

Projects

Temperature Converter Project
Convert between Celsius and Fahrenheit using functions.

#include <iostream>

double cToF(double c) { return (c * 9/5) + 32; }
double fToC(double f) { return (f - 32) * 5/9; }

int main() {
  double c = 25;
  double f = 77;
  std::cout << c << "°C = " << cToF(c) << "°F\n";
  std::cout << f << "°F = " << fToC(f) << "°C\n";
  return 0;
}
    
Simple Calculator Project
Perform +, -, *, / operations based on user input.

#include <iostream>

int main() {
  double a, b;
  char op;
  std::cout << "Enter expression (a op b): ";
  std::cin >> a >> op >> b;

  switch (op) {
    case '+': std::cout << a + b; break;
    case '-': std::cout << a - b; break;
    case '*': std::cout << a * b; break;
    case '/': 
      if (b != 0) std::cout << a / b;
      else std::cout << "Error: divide by zero";
      break;
    default: std::cout << "Invalid operator";
  }
  return 0;
}
    
Student Grades Manager Project
Store names and grades, then display average score.

#include <iostream>
#include <vector>
#include <string>

int main() {
  std::vector<std::string> names;
  std::vector<double> grades;
  int n;
  std::cout << "Number of students: ";
  std::cin >> n;

  for (int i = 0; i < n; i++) {
    std::string name;
    double grade;
    std::cout << "Name: ";
    std::cin >> name;
    std::cout << "Grade: ";
    std::cin >> grade;
    names.push_back(name);
    grades.push_back(grade);
  }

  double sum = 0;
  for (double g : grades) sum += g;
  std::cout << "Average grade: " << sum / n << "\n";
  return 0;
}
    
To-Do List (Vector) Project
Add, view, and remove tasks using a vector of strings.

#include <iostream>
#include <vector>
#include <string>

int main() {
  std::vector<std::string> tasks;
  int choice;
  do {
    std::cout << "1. Add Task\n2. View Tasks\n3. Remove Task\n0. Exit\n";
    std::cin >> choice;
    if (choice == 1) {
      std::string task;
      std::cout << "Enter task: ";
      std::cin.ignore();
      std::getline(std::cin, task);
      tasks.push_back(task);
    } else if (choice == 2) {
      for (size_t i = 0; i < tasks.size(); i++)
        std::cout << i+1 << ". " << tasks[i] << "\n";
    } else if (choice == 3) {
      size_t idx;
      std::cout << "Task number to remove: ";
      std::cin >> idx;
      if (idx > 0 && idx <= tasks.size())
        tasks.erase(tasks.begin() + idx - 1);
    }
  } while (choice != 0);
  return 0;
}
    
Number Guessing Game Project
Randomly generate a number and let the user guess it.

#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
  std::srand(std::time(nullptr));
  int target = std::rand() % 100 + 1;
  int guess;
  do {
    std::cout << "Guess (1-100): ";
    std::cin >> guess;
    if (guess < target) std::cout << "Too low!\n";
    else if (guess > target) std::cout << "Too high!\n";
    else std::cout << "Correct!\n";
  } while (guess != target);
  return 0;
}
    
Capstone: Sudoku Solver Project
Solve a 9×9 Sudoku puzzle using backtracking and recursion.

#include <iostream>

const int N = 9;

bool isSafe(int grid[N][N], int row, int col, int num) {
  for (int x = 0; x < N; x++) {
    if (grid[row][x] == num) return false;
    if (grid[x][col] == num) return false;
  }
  int startRow = row - row % 3;
  int startCol = col - col % 3;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (grid[i + startRow][j + startCol] == num) return false;
  return true;
}

bool solveSudoku(int grid[N][N]) {
  for (int row = 0; row < N; row++) {
    for (int col = 0; col < N; col++) {
      if (grid[row][col] == 0) {
        for (int num = 1; num <= 9; num++) {
          if (isSafe(grid, row, col, num)) {
            grid[row][col] = num;
            if (solveSudoku(grid)) return true;
            grid[row][col] = 0; // backtrack
          }
        }
        return false; // no valid number found
      }
    }
  }
  return true; // solved
}

void printGrid(int grid[N][N]) {
  for (int r = 0; r < N; r++) {
    for (int c = 0; c < N; c++) {
      std::cout << grid[r][c] << " ";
    }
    std::cout << "\n";
  }
}

int main() {
  int grid[N][N] = {
    {5,3,0, 0,7,0, 0,0,0},
    {6,0,0, 1,9,5, 0,0,0},
    {0,9,8, 0,0,0, 0,6,0},

    {8,0,0, 0,6,0, 0,0,3},
    {4,0,0, 8,0,3, 0,0,1},
    {7,0,0, 0,2,0, 0,0,6},

    {0,6,0, 0,0,0, 2,8,0},
    {0,0,0, 4,1,9, 0,0,5},
    {0,0,0, 0,8,0, 0,7,9}
  };

  if (solveSudoku(grid))
    printGrid(grid);
  else
    std::cout << "No solution exists\n";

  return 0;
}