Merge branch 'master' into project_euler/master2

This commit is contained in:
Krishna Vedala 2020-04-07 10:41:35 -04:00 committed by GitHub
commit 99f299d172
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 277 additions and 87 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
*.exe
*.out
.vscode/
build
build/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "function_timer"]
path = function_timer
url = https://github.com/kvedala/function_timer.git

27
.travis.yml Normal file
View File

@ -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

26
CMakeLists.txt Normal file
View File

@ -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)

View File

@ -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)

View File

@ -1,3 +1,4 @@
[![Build Status](https://travis-ci.org/kvedala/C.svg?branch=master)](https://travis-ci.org/kvedala/C)
C
========

View File

@ -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} )

1
function_timer Submodule

@ -0,0 +1 @@
Subproject commit 327ddab3e895c26026eeb39ed7e0b44d82597137

16
misc/CMakeLists.txt Normal file
View File

@ -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} )

View File

@ -1,45 +1,47 @@
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
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<n;i++)
scanf("%d", &n);
for (i = 0; i < n; i++)
{
a[i]=rand()%100;
a[i] = rand() % 100;
}
printf("Random Numbers Generated are :\n");
for(i=0;i<n;i++)
for (i = 0; i < n; i++)
{
printf("\n%d",a[i]);
printf("\n%d", a[i]);
}
printf("\n");
printf("\nSorted Data:");
for(i=0;i<n;i++)
for (i = 0; i < n; i++)
{
for(j=0;j<n;j++)
for (j = 0; j < n; j++)
{
if(a[i]<a[j])
if (a[i] < a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
for(i=0;i<n;i++)
for (i = 0; i < n; i++)
{
printf("\n%d",a[i]);
printf("\n%d", a[i]);
}
q1=a[n/4];
printf("\nFirst Quartile : %f",q1);
q3=a[(3*n)/4];
printf("\nThird Quartile : %f",q3);
iqr=q3-q1;
printf("\nInterQuartile Range is : %f",iqr);
getch();
q1 = a[n / 4];
printf("\nFirst Quartile : %f", q1);
q3 = a[(3 * n) / 4];
printf("\nThird Quartile : %f", q3);
iqr = q3 - q1;
printf("\nInterQuartile Range is : %f", iqr);
return 0;
}

67
misc/factorial_fast.c Normal file
View File

@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
/**
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;
}

View File

@ -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} )

View File

@ -1,20 +1,21 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
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;
}

View File

@ -1,8 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for memmove */
#include <stdint.h>
#include <string.h> /* 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;
}

View File

@ -1,10 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#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;
}

View File

@ -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);