Skip to content

my random competitive programming solutions (and other stuff) ~ 2 years ago, yes ik i need to make a comeback

Notifications You must be signed in to change notification settings

ArchishmanSengupta/competitive-coding

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

This is the list of modern CPP tricks often used in Coding Interviews and Competitive Programming.

Contents:

No more nested min(x, min(y, ...))

Use initializer list and std::min and std::max to make life easy

small = min(x, min(y, min(z, k))); // the old way
small = min({x, y, z, k}); // life is easy

JavaScript like Destructuring using Structured Binding in C++

pair<int, int> cur = {1, 2};
auto [x, y] = cur;
// x is now 1, y is now 2
// no need of cur.first and cur.second

array<int, 3> arr = {1, 0, -1};
auto [a, b, c] = arr;
// a is now 1, b is now 0, c is now -1

Powerful Logging and Debugging

How debug macros work?

Straight to the point, I have often used the debug macro which stringifies the variable names and their values.

#define debug(x) cout << #x << " " << x 
int ten = 10;
debug(ten); // prints "ten = 10"

This is often useful in debugging.

The Problem with this macro - its not scalable

However, when you have multiple variables to log, you end up with more deb2 and deb3 macros.

#define debug(x) cout << #x << " " << x 
#define debug2(x) cout << #x << " " << x << " "  << #y << " " << y 
#define debug3(x, y, z) cout << #x << " " << x << " "  << #y << " " << y << " "  << #z << " " << z 

This is not scalable.

Solution using a powerful macro

Here is the solution using variadic macros and fold expressions,

#define debug(...) logger(#__VA_ARGS__, __VA_ARGS__)
template<typename ...Args>
void logger(string vars, Args&&... values) {
    cout << vars << " = ";
    string delim = "";
    (..., (cout << delim << values, delim = ", "));
}

int xx = 3, yy = 10, xxyy = 103;
debug(xx); // prints "xx = 3"
debug(xx, yy, xxyy); // prints "xx, yy, xxyy = 3, 10, 103"

Generic Reader and Writer for multiple variables and containers

template <typename... T>
void read(T &...args) {
    ((cin >> args), ...);
}

template <typename... T>
void write(string delimiter, T &&...args) {
    ((cout << args << delimiter), ...);
}

template <typename T>
void readContainer(T &t) {
    for (auto &e : t) {
        read(e);
    }
}

template <typename T>
void writeContainer(string delimiter, T &t) {
    for (const auto &e : t) {
        write(delimiter, e);
    }
    write("\n");
}

Usage

// Question: read three space seprated integers and print them in different lines.
	int x, y, z;
	read(x, y, z);
	write("\n", x, y, z);
	
// even works with variable data types :)
	int n;
	string s;
	read(n, s);
	write(" ", s, "has length", n, "\n");
	
// Question: read an array of `N` integers and print it to the output console.
	int N;
	read(N);
	vector<int> arr(N);
	readContainer(arr);
	writeContainer(" ", arr); // output: arr[0] arr[1] arr[2] ... arr[N - 1]
	writeContainer("\n", arr);
	/**
	* output:
	* arr[0]
	* arr[1]
	* arr[2]
	* ...
	* ...
	* ...
	* arr[N - 1]
	*/

Decorators in C++ and Multiple Parameters

Printing as many variables in one line

template<typename ...T>
void printer(T&&... args) {
    ((cout << args << " "), ...);
}

int age = 25;
string name = "Archishman";
printer("I am", name, ',', age, "years old"); 
// ^ This prints the following
// I am Archishman, 18 years old

Powerful decorator functions in C++

template<typename F>
auto debug_func(const F& func) {
    return [func](auto &&...args) { // forward reference
        cout << "input = ";
        printer(args...);
        auto res = func(forward<decltype(args)>(args)...);
        cout << "res = " << res << endl;
        return res;
    };
}

debug_func(pow)(2, 3);
// ^ this automatically prints
// input = 2 3 res = 8

Exploiting decorators by nesting them

Lets define another decorator beautify as follows.

template<typename F>
auto beautify(const F& func) {
    return [func](auto &&...args) { // forward reference
        cout << "========" << endl;
        func(forward<decltype(args)>(args)...);
        cout << "========" << endl;
    };
}

beautify(debug_func(pow(2, 3)));
// ^ this now prints
// ========
// input = 2 3 res = 8
// ========

Its amazing how much you can do by writing such generic decorators and nest them.
Think about decorators like log_time that calculates the time taken for a given function.

About

my random competitive programming solutions (and other stuff) ~ 2 years ago, yes ik i need to make a comeback

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published