Created
April 17, 2015 16:38
-
-
Save svdamani/43aa607f75d71dec028d to your computer and use it in GitHub Desktop.
A C library of simple and useful functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Compilation : Include this file in a C program | |
* Compile with an extra flag | |
* $compiler -std=c99 $executable $program | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdarg.h> | |
#include <string.h> | |
#include <math.h> | |
#include <time.h> | |
#include <ctype.h> | |
/** Single inclusion of file */ | |
#pragma once | |
#ifndef Type | |
#define Type int | |
#endif | |
/** Boolean definition in C */ | |
typedef enum { false, true } bool; | |
/** Find length of an array */ | |
#define arrlen(x) (sizeof x / sizeof * x) | |
#define IsEven(N) (N % 2 == 0) | |
#define IsOdd(N) (N % 2 != 0) | |
/** Max and min of two numbers */ | |
#define MaxofTwo(a, b) ((a > b) ? a : b) | |
#define MinofTwo(a, b) ((a < b) ? a : b) | |
/** Works only with GCC */ | |
#ifdef __GNUC__ | |
#define _swap(X, Y) do { __typeof__ (X) _T = X; X = Y; Y = _T; } while(0) | |
#endif | |
/** Bitwise swap of two numbers */ | |
#define BitwiseSwap(a, b) { a ^= b; b ^= a; a ^= b; } | |
/** Swapping two numbers in one line */ | |
#define OneLineSwap(a, b) (b = a + b - (a = b)) | |
/** Simple swap function through pointers */ | |
void Swap(Type *x, Type *y) { | |
Type tmp = *x; | |
*x = *y; | |
*y = tmp; | |
} | |
/** Copy function for arrays */ | |
void Copy(Type A[], const Type B[], int size) { | |
for(int i = 0; i < size; i++) A[i] = B[i]; | |
} | |
/** Find whether array is sorted or not, in O(n) */ | |
bool Sorted(Type A[], int size) { | |
for(int i = 0; i < size - 1; ++i) if(A[i] > A[i + 1]) return false; | |
return true; | |
} | |
/** Bubble sort function */ | |
void BubbleSort(Type A[], int size) { | |
for(int i = 0; i < size - 1; ++i) for(int j = i + 1; j < size; ++j) | |
if(A[i] > A[j]) Swap(&A[i], &A[j]); | |
} | |
/** Selection sort function */ | |
void SelectionSort(Type A[], int size) { | |
for(int i = 0; i < size - 1; i++) { | |
int k = i; | |
for(int j = i + 1; j < size; j++) if(A[k] > A[j]) k = j; | |
if(k != i) Swap(&A[i], &A[k]); | |
} | |
} | |
/** Insertion sort function */ | |
void InsertionSort(Type A[], int size) { | |
int i, j; | |
for(i = 1; i < size; ++i) { | |
Type tmp = A[i]; | |
for(j = i; j > 0 && A[j - 1] > tmp; j--) A[j] = A[j - 1]; | |
A[j] = tmp; | |
} | |
} | |
/** Shell sort function */ | |
void ShellSort(Type A[], int size) { | |
int i, j, k; | |
for(k = size / 2; k > 0; k /= 2) | |
for(i = k; i < size; i++) { | |
Type tmp = A[i]; | |
for(j = i; j >= k; j -= k) | |
if(tmp < A[j - k]) A[j] = A[j - k]; | |
else break; | |
A[j] = tmp; | |
} | |
} | |
/** Radix sort function */ | |
void RadixSort(Type A[], int size) { | |
int i; | |
Type m = 0, exp = 1, *b = malloc(size * sizeof(Type)); | |
for(i = 0; i < size; i++) if(A[i] > m) m = A[i]; | |
while(m / exp > 0) { | |
int bucket[10] = { 0 }; | |
for(i = 0; i < size; i++) bucket[A[i] / exp % 10]++; | |
for(i = 1; i < 10; i++) bucket[i] += bucket[i - 1]; | |
for(i = size - 1; i >= 0; i--) b[--bucket[A[i] / exp % 10]] = A[i]; | |
for(i = 0; i < size; i++) A[i] = b[i]; | |
exp *= 10; | |
} | |
} | |
/** Partition an array, used for Quick sort */ | |
int Partition(Type A[], int l, int h) { | |
int i, p = h, first = l; // counter, pivot and divider for pivot | |
for(i = l; i < h; i++) if(A[i] < A[p]) { | |
Swap(&A[i], &A[first]); | |
first++; | |
} | |
Swap(&A[p], &A[first]); | |
return first; | |
} | |
/** Method to implement Quick Sort using partition() */ | |
/** To sort the whole array start = 0, end = size - 1 */ | |
void QuickSort(Type A[], int l, int h) { | |
if((h - l) > 0) { | |
int p = Partition(A, l, h); | |
QuickSort(A, l, p - 1); | |
QuickSort(A, p + 1, h); | |
} | |
} | |
#define LeftChild(i) (2 * i + 1) | |
void PercDown(Type A[], int i, int size) { | |
int c; | |
Type tmp; | |
for(tmp = A[i]; LeftChild(i) < size; i = c) { | |
c = LeftChild(i); | |
if(c != size - 1 && A[c + 1] > A[c]) c++; | |
if(tmp < A[c]) A[i] = A[c]; | |
else break; | |
} | |
A[i] = tmp; | |
} | |
void HeapSort(Type A[], int size) { | |
for(int i = size / 2; i >= 0; i--) PercDown(A, i, size); // BuildHeap | |
for(int i = size - 1; i > 0; i--) { | |
Swap(&A[0], &A[i]); // DeleteMax | |
PercDown(A, 0, i); | |
} | |
} | |
/** Linear search function in C */ | |
bool LinearSearch(Type A[], int size, Type val) { | |
for(int i = 0; i < size; ++i) if(A[i] == val) return true; | |
return false; | |
} | |
/** Binary search function in C, Needs array to be sorted */ | |
Type BinarySearch(const Type A[], Type X, int N) { | |
Type Low = 0, Mid, High = N - 1; | |
while(Low <= High) { | |
Mid = (Low + High) / 2; | |
if(A[Mid] < X) Low = Mid + 1; | |
else if(A[Mid] > X) High = Mid - 1; | |
else return Mid; /* Found */ | |
} | |
return -1; /* NotFound is defined as -1 */ | |
} | |
bool JumpSearch(Type A[], int size, Type val) { | |
if(!Sorted(A, size)) QuickSort(A, 0, size - 1); | |
int i = 0, j = floor(sqrt(size)); | |
while(A[min(j, size) - 1] < val) { | |
i = j; | |
j += floor(sqrt(size)); | |
if(i >= size) return false; | |
} | |
for(; A[i] < val; ++i) if(i == min(j, size)) return false; | |
if(A[i] == val) return true; | |
else return false; | |
} | |
int TernarySearch(int f[], int left, int right, int absPrec) { | |
while(1) { | |
// left and right are the current bounds; the maximum is between them | |
if((right - left) < absPrec) return (left + right) / 2; | |
int leftThird = (2 * left + right) / 3; | |
int rightThird = (left + 2 * right) / 3; | |
if(f[leftThird] < f[rightThird]) left = leftThird; | |
else right = rightThird; | |
} | |
} | |
/** Find Greatest Common Divisor */ | |
int GCD(int a, int b) { | |
return (a % b == 0) ? b : GCD(b, a % b); | |
} | |
unsigned int gcd(unsigned int u, unsigned int v) { | |
// simple cases (termination) | |
if(u == v) return u; | |
if(u == 0) return v; | |
if(v == 0) return u; | |
// look for factors of 2 | |
if(~u & 1) { // u is even | |
if(v & 1) return gcd(u >> 1, v); // v is odd | |
else return gcd(u >> 1, v >> 1) << 1; // both u and v are even | |
} | |
if(~v & 1) return gcd(u, v >> 1); // u is odd, v is even | |
if(u > v) return gcd((u - v) >> 1, v); // reduce larger argument | |
return gcd((v - u) >> 1, u); | |
} | |
unsigned int Gcd(unsigned int M, unsigned int N) { | |
unsigned int Rem; | |
while(N > 0) { | |
Rem = M % N; | |
M = N; | |
N = Rem; | |
} | |
return M; | |
} | |
/** Find Lowest Common Multiple */ | |
int LCM(int a, int b) { | |
for(int i = (a > b) ? a : b;; ++i) if(i % a == 0 && i % b == 0) return i; | |
} | |
/** Find Mean */ | |
double Mean(Type A[], int size) { | |
double mean = 0; | |
for(int i = 0; i < size; ++i) mean += A[i]; | |
return mean / size; | |
} | |
/** Find Variance */ | |
double Variance(Type A[], int size) { | |
double var = 0, mean = Mean(A, size); | |
for(int i = 0; i < size; ++i) var += A[i] * A[i]; | |
return (var / size - (mean * mean)); | |
} | |
/** Check whether a string is palindrome or not */ | |
bool isPalindrome(char str[]) { | |
int len = strlen(str) - 1; | |
for(int i = 0; i <= len; ++i) if(str[i] != str[len - i]) return false; | |
return true; | |
} | |
/** Check whether a number is perfect or not */ | |
bool isPerfectNo(Type n) { | |
Type sum = 1; | |
for(Type i = 2; i <= (n / 2); ++i) if(n % i == 0) sum += i; | |
return(sum == n); | |
} | |
/** Check whether a number is Armstrong number or not */ | |
bool isArmstrongNumber(int n) { | |
int r, sum = 0, temp = n; | |
while(n != 0) { | |
r = n % 10; | |
n /= 10; | |
sum += r * r * r; | |
} | |
return(sum == temp); | |
} | |
/** Check whether a number is prime or not */ | |
bool isPrime(long int n) { | |
for(int i = 2; i <= n / 2; ++i) if(n % i == 0) return false; | |
return true; | |
} | |
/** scanf implementation with error checking */ | |
void myscanf(char *type, void *var, char *message) { | |
printf("%s", message); | |
while(scanf(type, var) != 1 && getchar() != '\n') { | |
fflush(stdin); | |
fprintf(stderr, "Wrong input, enter again : "); | |
} | |
fflush(stdin); | |
} | |
/** Print fibonacci series of specified terms */ | |
void Fibonacci(int terms) { | |
int a = 1, b = 1, c; | |
printf("1\n1\n"); | |
for(int i = 2; i < terms; ++i) { | |
printf("%d\n", c = a + b); | |
a = b; | |
b = c; | |
} | |
} | |
/** View source code of a file by giving it's path */ | |
void ViewSource(const char path[]) { | |
char c; | |
FILE *fp = fopen(path, "r"); | |
if(fp == NULL) perror(path); | |
while((c = fgetc(fp)) != EOF) putchar(c); | |
fclose(fp); | |
} | |
/** Find power X^N */ | |
long int Pow(long int X, unsigned int N) { | |
if(N == 0) return 1; | |
if(N == 1) return X; | |
if(IsEven(N)) return Pow(X * X, N / 2); | |
else return Pow(X * X, N / 2) * X; | |
} | |
/** Find factorial of a number */ | |
long int Fact(int n) { | |
return (n == 0 || n == 1) ? 1 : (long int)(n * Fact(n - 1)); | |
} | |
/** Find combination of n, r */ | |
long int nCr(int n, int r) { | |
return (n < r) ? 0 : (long int)(Fact(n) / (Fact(r) * Fact(n - r))); | |
} | |
/** Find permutation of n, r */ | |
long int nPr(int n, int r) { | |
return (n < r) ? 0 : (long int)(Fact(n) / Fact(n - r)); | |
} | |
/** Find whether a year is leap year or not */ | |
bool isLeapYear(int year) { | |
return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0); | |
} | |
/** Find whether a number is sum of squares or not in O(sqrt(n)) */ | |
bool isSumofSquares(int n) { | |
for(int i = 1; i < sqrt(n); ++i) { | |
int j = sqrt(n - (i * i)); | |
if((i * i + j * j) == n && j > 0) return true; | |
} | |
return false; | |
} | |
bool isPythagoreanTriplet(int a, int b, int c) { | |
return((a*a + b*b == c*c) || (b*b + c*c == a*a) || (c*c + a*a == b*b)); | |
} | |
/** Find Compound Interest */ | |
float CompoundInterest(int P, float r, int n) { | |
return((float)P * pow((1 + (r / 100)), n) - P); | |
} | |
/** Chomp function in C */ | |
void Chomp(char * str) { | |
int len = strlen(str); | |
if(str[len - 1] == '\n') str[len - 1] = '\0'; | |
} | |
char * CharType(char ch) { | |
if(isalpha(ch)) return "Alphabet"; | |
if(isdigit(ch)) return "Number"; | |
if(isspace(ch)) return "Whitespace"; | |
return ""; | |
} | |
/** Find anagrams of word in text */ | |
int FindAnagrams(char *word, char *text) { | |
int bin[256] = { 0 }, mismatch = 0, found = 0, len = 0, c, i; | |
for(i = 0; word[i] != '\0'; i++, bin[c]--, len++) { | |
c = word[i]; | |
if(bin[c] == 0) mismatch++; | |
} | |
for(i = 0; text[i] != '\0'; i++) { | |
c = text[i]; | |
if(bin[c] == 0) mismatch++; | |
if(bin[c] == -1) mismatch--; | |
bin[c]++; | |
if(i >= len) { | |
c = text[i - len]; | |
if(bin[c] == 0) mismatch++; | |
if(bin[c] == 1) mismatch--; | |
bin[c]--; | |
} | |
if(mismatch == 0) found++; | |
} | |
return found; | |
} | |
/** Implementing strcat() function */ | |
void mystrcat(char * dest, const char * src) { | |
while(*dest != '\0') *dest++; | |
do *dest++ = *src++; | |
while(*src != '\0'); | |
} | |
/** Implementing strlen() function */ | |
size_t mystrlen(char *str) { | |
size_t i = 0; | |
while(str[i] != '\0') ++i; | |
return i; | |
} | |
/** Implementing pow() function */ | |
Type mypow(Type base, Type exp) { | |
Type result = 1; | |
for(; exp; exp >>= 1) { | |
if(exp & 1) | |
result *= base; | |
base *= base; | |
} | |
return result; | |
} | |
/** Kadane's maximum subsequence algorithm in C */ | |
Type Kadane(Type A[], int size) { | |
Type max_here = 0, max_sum = 0; | |
for(int i = 0; i < size; ++i) { | |
max_here = max(A[i], max_here + A[i]); | |
max_sum = max(max_sum, max_here); | |
} | |
return max_sum; | |
} | |
/** Find nth fibonacci no. in O(log n) time by FastFib(1, 0, 0, 1, n) */ | |
int FastFib(int a, int b, int p, int q, int count) { | |
if(0 == count) return b; | |
if(0 == count % 2) | |
return FastFib(a, b, p*p + q*q, 2 * p*q + q*q, count / 2); | |
else return FastFib(b*q + a*q + a*p, b*p + a*q, p, q, count - 1); | |
} | |
/** Minimum of three numbers */ | |
int minimum(int a, int b, int c) { | |
if(a <= b && a <= c) return a; | |
if(b <= c && b <= a) return b; | |
return c; | |
} | |
/** Levenshtein Distance of two strings */ | |
int LevDist(char *s, int len_s, char *t, int len_t) { | |
if(len_s == 0) return len_t; | |
if(len_t == 0) return len_s; | |
int cost = (s[len_s - 1] == t[len_t - 1]) ? 0 : 1; | |
return minimum( | |
LevDist(s, len_s - 1, t, len_t) + 1, | |
LevDist(s, len_s, t, len_t - 1) + 1, | |
LevDist(s, len_s - 1, t, len_t - 1) + cost | |
); | |
} | |
/** Display Pascal Triangle */ | |
void PascalTriangle(int rows) { | |
int i, j, k, num = 50, array[15][15]; | |
for(i = 0; i < rows; i++) { | |
for(k = num - 2 * i; k >= 0; k--) printf(" "); | |
for(j = 0; j <= i; j++) { | |
if(j == 0 || i == j) array[i][j] = 1; | |
else array[i][j] = array[i - 1][j - 1] + array[i - 1][j]; | |
printf("%4d", array[i][j]); | |
} | |
printf("\n"); | |
} | |
} | |
/** Defined only for windows */ | |
#ifdef _WIN32 | |
#include <windows.h> | |
#include <conio.h> | |
#include <sys/stat.h> | |
void Stat(const char path[]) { | |
struct stat fd; | |
if(stat(Path, &fd)) perror(path); | |
printf("Name : %s\n", path); | |
printf("Size : %d bytes\n", fd.st_size); | |
printf("Location : %c: \n", 65 + fd.st_dev); | |
printf("Date created : %s", ctime(&fd.st_ctime)); | |
printf("Date accessed : %s", ctime(&fd.st_atime)); | |
printf("Date modified : %s", ctime(&fd.st_mtime)); | |
if(fd.st_mode & S_IREAD) printf("Readable, "); | |
if(fd.st_mode & S_IWRITE) printf("Writable, "); | |
if(fd.st_mode & S_IFDIR) printf("Directory, "); | |
if(fd.st_mode & S_IFCHR) printf("Character file."); | |
if(fd.st_mode & S_IFREG) printf("Regular file."); | |
} | |
double CalcTime() { | |
clock_t start, stop; | |
start = clock(); | |
/// (void*)(*fn)(void); | |
stop = clock(); | |
return (double)(stop - start) / CLOCKS_PER_SEC; | |
} | |
/** Declaration of goto-x-y() function in c */ | |
void gotoxy(int x, int y) { | |
COORD c = { x, y }; | |
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); | |
} | |
/** Declaration of clear screen / terminal in c */ | |
void clrscr() { | |
DWORD bw = 0; | |
COORD ord = { 0, 0 }; | |
HANDLE hwnd = GetStdHandle(STD_OUTPUT_HANDLE); | |
FillConsoleOutputCharacter(hwnd, 32, 80 * 25, ord, &bw); | |
SetConsoleCursorPosition(hwnd, ord); | |
} | |
#endif | |
/* Definition of simple 'die' function in C */ | |
void die(int line_number, const char * format, ...) { | |
va_list vargs; | |
va_start(vargs, format); | |
fprintf(stderr, "%d: ", line_number); | |
vfprintf(stderr, format, vargs); | |
fprintf(stderr, ".\n"); | |
exit(1); | |
} | |
/** Function to handle assertion failure and print error message */ | |
void AssertFail(char exp[], char file[], char baseFile[], int line) { | |
if(strcmp(file, baseFile)) | |
fprintf(stderr, "(included from %s)\n", baseFile); | |
fprintf(stderr, "%s:%d: Assertion failed at %s\n", file, line, exp); | |
} | |
/** Assert macro similar to one defined in <assert.h> */ | |
#define Assert(exp) if(!exp) AssertFail(#exp, __FILE__, __BASE_FILE__, __LINE__) | |
/** Evaluate an expression, similar to javascript's eval function */ | |
#define eval(expr) ((expr == false) ? "false" : "true") | |
/** var_dump macro same as eval, similar to PHP's var_dump function */ | |
#define var_dump(function) eval(function) | |
/** Add numbers in C */ | |
int add(int num, ...) { | |
va_list ap; | |
va_start(ap, num); | |
return num + add(ap); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment