diff --git a/.gitignore b/.gitignore index 2f208ece..b4b13dd8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ *.exe *.out .vscode/ -build +build/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..949b4bc7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "function_timer"] + path = function_timer + url = https://github.com/kvedala/function_timer.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..1664fe08 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,27 @@ +language: cpp +os: linux +compiler: + - gcc + - clang + +before_install: + - test -n $CC && unset CC + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libgomp1 + # - gcc-6 + +script: + - export OMP_NUM_THREADS=2 + - export LD_LIBRARY_PATH=$(if [[ $CXX == "clang++" ]]; then echo -n '/usr/local/clang/lib'; fi) + - mkdir build + - cd build + - cmake .. -DUSE_OPENMP=OFF + - make + - rm -rf * + - cmake .. -DUSE_OPENMP=ON + - make diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..6c8b0795 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.0) +project(Algorithms_in_C + LANGUAGES C CXX + VERSION 1.0.0 + DESCRIPTION "Set of algorithms implemented in C." +) + +option(USE_OPENMP "flag to use OpenMP for multithreading" ON) + +add_subdirectory(function_timer EXCLUDE_FROM_ALL) +include_directories(function_timer/include) +# link_libraries(function_timer) +# include_directories(${CMAKE_BINARY_DIR}/include) +# link_directories(${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}) + +add_subdirectory(conversions) +add_subdirectory(misc) +add_subdirectory(project_euler) + +if(USE_OPENMP) + find_package(OpenMP) +endif() + +set(CPACK_PROJECT_NAME ${PROJECT_NAME}) +set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) +include(CPack) diff --git a/DIRECTORY.md b/DIRECTORY.md index e67ff0b1..f1e8e3f6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -182,6 +182,7 @@ * [Collatz](https://github.com/TheAlgorithms/C/blob/master/misc/Collatz.c) * [Demonetization](https://github.com/TheAlgorithms/C/blob/master/misc/demonetization.c) * [Factorial](https://github.com/TheAlgorithms/C/blob/master/misc/Factorial.c) + * [Factorial Fast](https://github.com/TheAlgorithms/C/blob/master/misc/factorial_fast.c) * [Factorial Trailing Zeroes](https://github.com/TheAlgorithms/C/blob/master/misc/factorial_trailing_zeroes.c) * [Fibonacci](https://github.com/TheAlgorithms/C/blob/master/misc/Fibonacci.c) * [Fibonacci Dp](https://github.com/TheAlgorithms/C/blob/master/misc/Fibonacci_DP.c) diff --git a/README.md b/README.md index 912c5e2f..f397984c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Build Status](https://travis-ci.org/kvedala/C.svg?branch=master)](https://travis-ci.org/kvedala/C) C ======== diff --git a/conversions/CMakeLists.txt b/conversions/CMakeLists.txt new file mode 100644 index 00000000..0a98602f --- /dev/null +++ b/conversions/CMakeLists.txt @@ -0,0 +1,16 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".c" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + # Make sure YourLib is linked to each app + target_link_libraries( ${testname} function_timer ) + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE C) + install(TARGETS ${testname} DESTINATION "bin/conversions") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/function_timer b/function_timer new file mode 160000 index 00000000..327ddab3 --- /dev/null +++ b/function_timer @@ -0,0 +1 @@ +Subproject commit 327ddab3e895c26026eeb39ed7e0b44d82597137 diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt new file mode 100644 index 00000000..be8a549f --- /dev/null +++ b/misc/CMakeLists.txt @@ -0,0 +1,16 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".c" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + # Make sure YourLib is linked to each app + target_link_libraries( ${testname} function_timer ) + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE C) + install(TARGETS ${testname} DESTINATION "bin/misc") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/misc/QUARTILE.c b/misc/QUARTILE.c index a8498e64..f9ae5cc6 100644 --- a/misc/QUARTILE.c +++ b/misc/QUARTILE.c @@ -1,45 +1,47 @@ -#include -#include -#include -void main() +#include +#include +#include + +int main() { - int a[10],n,i,j,temp; - float q1,q3,iqr; - clrscr(); + int a[10], n, i, j, temp; + float q1, q3, iqr; + printf("Enter no. for Random Numbers :"); - scanf("%d",&n); - for(i=0;i +#include +#include + +/** + Returns the \f$n^{th}\f$ and \f$n+1^{th}\f$ Fibonacci number. + The return variables are C & D respectively. + */ +void fib(unsigned long n, unsigned long *C, unsigned long *D) +{ + //Out of Range checking + if (n < 0) + { + printf("\nNo Such term !\n"); + exit(0); + } + + unsigned long a, b, c, d; + + if (n == 0) + { + C[0] = 0; + if (D) + D[0] = 1; + return; + } + + fib(n >> 1, &c, &d); /**< Compute F(n/2) */ + + a = c * ((d << 1) - c); + b = c * c + d * d; + if (n % 2 == 0) /**< If n is even */ + { + C[0] = a; + if (D) + D[0] = b; + return; + } + + /**< If n is odd */ + C[0] = b; + if (D) + D[0] = a + b; + return; +} + +int main(int argc, char *argv[]) +{ + unsigned long number, result; + + setlocale(LC_NUMERIC, ""); // format the printf output + + //Asks for the number/position of term in Fibonnacci sequence + if (argc == 2) + number = atoi(argv[1]); + else + { + printf("Enter the value of n(n starts from 0 ): "); + scanf("%lu", &number); + } + + fib(number, &result, NULL); + + printf("The nth term is : %'lu \n", result); + + return 0; +} diff --git a/project_euler/CMakeLists.txt b/project_euler/CMakeLists.txt new file mode 100644 index 00000000..abb40df5 --- /dev/null +++ b/project_euler/CMakeLists.txt @@ -0,0 +1,26 @@ +if(USE_OPENMP) + find_package(OpenMP) +endif() + +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB_RECURSE APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".c" "" testname ${testsourcefile} ) + string( REPLACE "/" "-" testname ${testname} ) + string( REPLACE "\\" "-" testname ${testname} ) + string( REPLACE " " "_" testname ${testname} ) + add_executable( ${testname} ${testsourcefile} ) + # Make sure YourLib is linked to each app + target_link_libraries( ${testname} function_timer ) + if(OpenMP_C_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_C) + endif() + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE C) + install(TARGETS ${testname} DESTINATION "bin/misc") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/project_euler/Problem 08/sol1.c b/project_euler/Problem 08/sol1.c index 3577e3a0..1c57045e 100644 --- a/project_euler/Problem 08/sol1.c +++ b/project_euler/Problem 08/sol1.c @@ -1,20 +1,21 @@ #include +#include #include int64_t get_product(FILE *fp, long start_pos, int num_digits) { - char ch = ' '; /* temporary variable to store character read from file */ - uint8_t num = 0; /* temporary variable to store digit read */ - int64_t prod = 1; /* product accumulator */ - int count = 0; /* we use this variable to count number of bytes of file read */ + char ch = ' '; /* temporary variable to store character read from file */ + uint8_t num = 0; /* temporary variable to store digit read */ + int64_t prod = 1; /* product accumulator */ + int count = 0; /* we use this variable to count number of bytes of file read */ /* accumulate product for num_digits */ - for(int i = 0; i < num_digits; i++, count++) + for (int i = 0; i < num_digits; i++, count++) { /* get character from file */ ch = getc(fp); - /* the ASCII codes of digits is between 0x30 and 0x39. + /* the ASCII codes of digits is between 0x30 and 0x39. * any character not in this range implies an invalid character */ if (ch < 0x30 || ch > 0x39) @@ -24,35 +25,34 @@ int64_t get_product(FILE *fp, long start_pos, int num_digits) i--; continue; } - + num = ch - 0x30; /* convert character digit to number */ if (num == 0) { - /* If number is zero, we can skip the next 'num_digits' + /* If number is zero, we can skip the next 'num_digits' * because this '0' will repeat in the next 'num_digit' multiplications. * Hence, we also do not update the file position */ /* NOTE: this is not needed but helps get results faster :) */ return 0; } - prod *= num; /* accumulate product */ + prod *= num; /* accumulate product */ } /* set file position to the next starting character + 1 */ fseek(fp, -count + 1, SEEK_CUR); - + return prod; } - -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { int position = 0; int num_digits = 4; int64_t prod, max_prod = 0; /* if second command-line argument is ge=iven, - * use it as the number of digits to compute + * use it as the number of digits to compute * successive product for */ if (argc == 2) @@ -67,24 +67,24 @@ int main(int argc, char* argv[]) } /* loop through all digits in the file */ - do + do { /* get product of 'num_digits' from current position in file */ prod = get_product(fp, ftell(fp), num_digits); - + if (prod > max_prod) { max_prod = prod; position = ftell(fp) - 1; } - } while(!feof(fp)); /* loop till end of file is reached */ - + } while (!feof(fp)); /* loop till end of file is reached */ + printf("Maximum product: %lld\t Location: %d^th position\n\t", max_prod, position); - fseek(fp, position, SEEK_SET); /* move cursor to identified position in file */ + fseek(fp, position, SEEK_SET); /* move cursor to identified position in file */ /* loop through all digits */ for (; num_digits > 0; num_digits--) { - char ch = getc(fp); /* get character */ + char ch = getc(fp); /* get character */ /* skip invalid character */ if (ch < 0x30 || ch > 0x39) continue; @@ -94,7 +94,7 @@ int main(int argc, char* argv[]) printf("%c = %lld\n", ch, max_prod); } - fclose(fp); /* close file */ + fclose(fp); /* close file */ return 0; } diff --git a/project_euler/Problem 08/sol2.c b/project_euler/Problem 08/sol2.c index be31b11c..67371886 100644 --- a/project_euler/Problem 08/sol2.c +++ b/project_euler/Problem 08/sol2.c @@ -1,8 +1,9 @@ #include #include -#include /* for memmove */ +#include +#include /* for memmove */ -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { int position = 0, num_bad_chars = 0; int num_digits = 4; @@ -12,15 +13,15 @@ int main(int argc, char* argv[]) int64_t prod = 1, max_prod = 0; /* if second command-line argument is given, - * use it as the number of digits to compute + * use it as the number of digits to compute * successive product for */ if (argc == 2) num_digits = atoi(argv[1]); - + /* allocate memory to store past values */ buffer = calloc(num_digits, sizeof(uint8_t)); - if(!buffer) + if (!buffer) { perror("Unable to allocate memory for buffer"); return -1; @@ -31,57 +32,58 @@ int main(int argc, char* argv[]) if (!fp) { perror("Unable to open file"); - free(buffer); /* free allocated memory */ + free(buffer); /* free allocated memory */ return -1; } /* loop through all digits in the file */ - do + do { /* get character from file */ ch = getc(fp); - /* the ASCII codes of digits is between 0x30 and 0x39. + /* the ASCII codes of digits is between 0x30 and 0x39. * any character not in this range implies an invalid character */ if (ch < 0x30 || ch > 0x39) { - num_bad_chars ++; /* this is used to get the bad characters in the sequence of 13 characters */ + num_bad_chars++; /* this is used to get the bad characters in the sequence of 13 characters */ continue; - } else if (num_bad_chars > 0) - num_bad_chars --; - - num = ch - 0x30; /* convert character digit to number */ - num_prev = buffer[0]; /* previous n^th digit */ + } + else if (num_bad_chars > 0) + num_bad_chars--; + + num = ch - 0x30; /* convert character digit to number */ + num_prev = buffer[0]; /* previous n^th digit */ /* left shift the buffer - * using a for loop or a faster memory move */ - memmove(buffer, buffer+1, num_digits-1); + memmove(buffer, buffer + 1, num_digits - 1); /* for (int i = 1; i < num_digits; i++) buffer[i-1] = buffer[i]; */ - buffer[num_digits-1] = num; /* save the latest number in buffer */ + buffer[num_digits - 1] = num; /* save the latest number in buffer */ if (num_prev != 0) { - /* since product is accumulated, the new product can be obtained by simply + /* since product is accumulated, the new product can be obtained by simply * multiplying the new digit and dividing with the oldest digit */ - prod /= num_prev; /* divide first to avoid over-flows */ + prod /= num_prev; /* divide first to avoid over-flows */ prod *= num; } else { prod = 1; - for(int i = 0; i < num_digits; i++) + for (int i = 0; i < num_digits; i++) { - if(buffer[i] == 0) + if (buffer[i] == 0) { prod = 0; - break; /* break innermost for-loop */ + break; /* break innermost for-loop */ } prod *= buffer[i]; } @@ -93,14 +95,14 @@ int main(int argc, char* argv[]) max_prod = prod; position = ftell(fp) - num_bad_chars - num_digits - 1; } - } while(!feof(fp)); /* loop till end of file is reached */ - + } while (!feof(fp)); /* loop till end of file is reached */ + printf("Maximum product: %lld\t Location: %d^th position\n\t", max_prod, position); - fseek(fp, position, SEEK_SET); /* move cursor to identified position in file */ + fseek(fp, position, SEEK_SET); /* move cursor to identified position in file */ /* loop through all digits */ for (; num_digits > 0; num_digits--) { - char ch = getc(fp); /* get character */ + char ch = getc(fp); /* get character */ /* skip invalid character */ if (ch < 0x30 || ch > 0x39) continue; @@ -110,8 +112,8 @@ int main(int argc, char* argv[]) printf("%c = %lld\n", ch, max_prod); } - fclose(fp); /* close file */ - free(buffer); /* free allocated memory */ + fclose(fp); /* close file */ + free(buffer); /* free allocated memory */ return 0; } diff --git a/project_euler/Problem 23/sol1.c b/project_euler/Problem 23/sol1.c index e7145946..b72e132b 100644 --- a/project_euler/Problem 23/sol1.c +++ b/project_euler/Problem 23/sol1.c @@ -1,10 +1,10 @@ - #include #include #include #ifdef _OPENMP #include #endif +#include "function_timer.h" unsigned long MAX_N = 28123; @@ -91,26 +91,28 @@ int main(int argc, char **argv) printf("Not using parallleization!\n"); #endif - clock_t dt = 0; + double total_duration = 0; + function_timer *timer = new_timer(); #ifdef _OPENMP #pragma omp parallel for reduction(+ \ : sum) schedule(runtime) #endif for (unsigned long i = 1; i <= MAX_N; i++) { - clock_t start_time = clock(); + start_timer(timer); if (!is_sum_of_abundant(i)) sum += i; clock_t end_time = clock(); - dt += end_time - start_time; + total_duration += end_timer(timer); printf("... %5lu: %8lu\r", i, sum); if (i % 100 == 0) fflush(stdout); } - printf("Time taken: %.4g ms\n", 1e3 * dt / CLOCKS_PER_SEC); + printf("Time taken: %.4g s\n", total_duration); printf("Sum of numbers that cannot be represented as sum of two abundant numbers : %lu\n", sum); + delete_timer(timer); return 0; } diff --git a/project_euler/Problem 25/sol1.c b/project_euler/Problem 25/sol1.c index db96af96..75682022 100644 --- a/project_euler/Problem 25/sol1.c +++ b/project_euler/Problem 25/sol1.c @@ -10,9 +10,9 @@ * Function to add arbitraty length decimal integers stored in an array. * a + b = c = new b **/ -unsigned int add_numbers(uint8_t *a, uint8_t *b, uint8_t *c, int N) +unsigned int add_numbers(unsigned char *a, unsigned char *b, unsigned char *c, int N) { - uint8_t carry = 0; + unsigned char carry = 0; unsigned int i; for (i = 0; i < N; i++) @@ -47,7 +47,7 @@ unsigned int add_numbers(uint8_t *a, uint8_t *b, uint8_t *c, int N) return i; } -int print_number(uint8_t *number, int N) +int print_number(unsigned char *number, int N) { int start_pos = N - 1; @@ -61,7 +61,7 @@ int print_number(uint8_t *number, int N) return 0; } -unsigned int get_digits(uint8_t *number) +unsigned int get_digits(unsigned char *number) { unsigned int digits = MAX_DIGITS; while (number[digits] == 0) @@ -71,9 +71,9 @@ unsigned int get_digits(uint8_t *number) int main(int argc, char *argv[]) { - uint8_t fn[MAX_DIGITS + 1]; /* array to store digits of a large number */ - uint8_t fn1[MAX_DIGITS + 1]; - uint8_t sum[MAX_DIGITS + 1]; + unsigned char fn[MAX_DIGITS + 1]; /* array to store digits of a large number */ + unsigned char fn1[MAX_DIGITS + 1]; + unsigned char sum[MAX_DIGITS + 1]; memset(fn, 0, MAX_DIGITS); memset(fn1, 0, MAX_DIGITS);