Merge branch 'project_euler/master2'

* project_euler/master2: (26 commits)
  solution using arbitrary number of digits took 11ms
  algorithm by Dijkstra
  updating DIRECTORY.md
  move time computation inside loop + comments
  faster parallleization
  time computation inside the loop & print loop info
  added comments
  sol1 optimized by storing abundant numbers in a condensed array
  brute-force - compute abundant numbers every time
  added source text file
  updating DIRECTORY.md
  sort using both lazy sort and shell-sort
  add stats for algo 2 and use milliseconds
  create a duplicate array
  added new shell-sort algorithm
  updating DIRECTORY.md
  speed optimized solution + optional OpenMP
  added computational time
  added additional summary
  updating DIRECTORY.md
  ...
This commit is contained in:
Krishna Vedala 2020-04-02 20:16:57 -04:00
commit 22bb478c07
No known key found for this signature in database
GPG Key ID: BA19ACF8FC8792F7
11 changed files with 988 additions and 2 deletions

View File

@ -243,6 +243,17 @@
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2015/sol1.c)
* Problem 16
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2016/sol1.c)
* Problem 20
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2020/sol1.c)
* Problem 19
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2019/sol1.c)
* Problem 21
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2021/sol1.c)
* Problem 22
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2022/sol1.c)
* Problem 23
* [Sol1](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2023/sol1.c)
* [Sol2](https://github.com/TheAlgorithms/C/blob/master/project_euler/Problem%2023/sol2.c)
## Searching
* [Binary Search](https://github.com/TheAlgorithms/C/blob/master/searching/Binary_Search.c)

View File

@ -0,0 +1,120 @@
#include <stdio.h>
/**
* returns number of days in a month.
* Month is identified by an integer -
* 0 = Jan and 11 = December
* For February, adjust for leap year outside the function.
**/
char get_month_days(short month)
{
if (month == 1) /* February has 28 days. Adjust leap year in the loop */
return 28;
else if (month <= 6) /* odd months till July have 30 days - Jan = 0 (even)*/
{
if (month & 0x01)
return 30;
else
return 31;
} else if (month >= 7) /* odd months after July have 31 days*/
{
if (month & 0x01)
return 31;
else
return 30;
}
/* should never reach here! */
perror("Should never have reached this point!\n");
return -1;
}
/**
* return 1 if input year is a leap year
* otherwise, return 0
**/
char is_leap_year(short year)
{
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
return 1;
return 0;
}
#ifdef DEBUG
const char* day_string(int day)
{
switch(day)
{
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
default:
return "Shouldnt see this!";
}
}
#endif
int main(int argc, char **argv)
{
int count_sundays = 0;
const short start_year = 1901;
const short end_year = 2000;
/**
* Let us identify days i.e., Sunday thru Saturday with integers - 0 thru 6 respectively
* Jan 1 1901 was a Tuesday
**/
char start_day = 2;
for (int year = start_year; year <= end_year; year++)
{
char is_leap = is_leap_year(year);
for (char month = 0; month < 12; month ++)
{
/**
* These two for-loops count the start of day for the next month. Hence,
* we have to skip the last December count */
if (year == end_year && month == 11)
continue;
int days = get_month_days(month);
if (is_leap && month == 1) /* for a leap year february, add a day */
days ++;
#ifdef DEBUG
if (year == end_year)
{
printf("Year: %d\t Month: %d\t Days: %d\t First of day: %s\n", year, month, days, day_string(start_day));
}
#endif
/** Main Algorithm:
* every week has 7 days hence, the start of next day would be modulo 7
* add to this, the current start date and ensure the result is still
* modulo 7!
**/
start_day = ((days % 7) + start_day) % 7;
/* If start-day is a Sunday, increment counter */
if (start_day == 0)
count_sundays ++;
}
}
printf("Total number of Sundays that happened on the 1st of a month in the last century: %d\n", count_sundays);
return 0;
}

View File

@ -0,0 +1,170 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
* store arbitratily large integer values
* as a linked list of digits.
**/
typedef struct _big_int
{
char value; /** tens place (single digit) */
struct _big_int *next_digit; /** hundreds place */
struct _big_int *prev_digit; /** units place */
} big_int;
#ifdef DEBUG
void print_digit(const big_int *my_int)
{
printf("\tValue : %d\n\tNext : %p\n\tPrev : %p\n", my_int->value, my_int->next_digit, my_int->prev_digit);
}
#endif
/**
* Function that allocates memory to add another
* digit at the MSB
**/
big_int *add_digit(big_int *digit, char value)
{
if (digit == NULL)
{
digit = (big_int *)malloc(sizeof(big_int));
if (!digit)
{
perror("Unable to allocate memory!");
return NULL;
}
digit->value = value;
digit->next_digit = NULL;
digit->prev_digit = NULL;
return digit;
}
if (digit->next_digit)
{
digit->next_digit->value = value;
return digit->next_digit;
}
digit->next_digit = (big_int *)malloc(sizeof(big_int));
if (digit->next_digit == NULL)
{
perror("Unable to allocate memory!");
return NULL;
}
digit->next_digit->value = value;
digit->next_digit->next_digit = NULL;
digit->next_digit->prev_digit = digit;
return digit->next_digit;
}
/**
* Function to remove digits preceeding the
* current digit.
**/
char remove_digits(big_int *digit, int N)
{
if (digit == NULL)
return 0;
if (digit->next_digit == NULL)
{
free(digit);
digit = NULL;
return 0;
}
if (N > 0)
return remove_digits(digit->next_digit, N - 1);
return remove_digits(digit->next_digit, 0);
}
int main(int argc, char **argv)
{
unsigned int N = 5;
big_int *ptr = add_digit(NULL, 1); /* start with 1 */
const big_int *ptr0 = ptr; /* save the first location */
unsigned long sum_digits = 0;
unsigned long num_digits = 0;
if (argc == 2)
N = atoi(argv[1]);
clock_t start_time = clock();
for (unsigned int i = 1; i <= N; i++)
{
int carry = 0;
#ifdef DEBUG
printf("%3d: ", i);
#endif
ptr = (big_int *)ptr0; /* multiply every digit with i */
while (ptr)
{
#ifdef DEBUG
printf("%p\t", ptr);
#endif
unsigned int tmp = ptr->value * i + carry;
if (tmp >= 10)
{
div_t tmp2 = div(tmp, 10);
carry = tmp2.quot;
tmp = tmp2.rem;
}
else
carry = 0;
if (carry > 0 && ptr->next_digit == NULL)
add_digit(ptr, 0);
ptr->value = tmp;
if (i == N)
/**
* sum digits on the last iteration
* this avoid having another loop over all digits
**/
sum_digits += tmp;
if (ptr->next_digit)
/* more digits available */
ptr = ptr->next_digit;
else
/* no more digits left - reached MSB */
break;
}
#ifdef DEBUG
printf("\n");
#endif
}
clock_t end_time = clock();
#ifdef DEBUG
printf("ptr = %p\n", ptr);
printf("%d! = ", N);
#endif
/** Notice that in the loop above, we make sure that at the end of the loop,
* ptr is pointing to the last digit. Thus we can avoid using another loop.
**/
// ptr = &my_int;
// /* move ptr to the MSB digit */
// while (ptr->next_digit)
// ptr = ptr->next_digit;
do
{
putchar(ptr->value + 0x30); /* convert digit to ASCII char */
ptr = ptr->prev_digit;
num_digits++;
} while (ptr); /* after coming to units place, there will be no valid ptr */
printf("\nTime taken: %.4g millisecond\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("Digit Sum = %lu\tNumber of digits = %lu\tStorage space = %.3gkb\t \n",
sum_digits, num_digits, num_digits * sizeof(big_int) / 1024.0);
remove_digits((big_int *)ptr0, -1);
return 0;
}

View File

@ -0,0 +1,98 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/**
* function to return the sum of proper divisors of N
**/
unsigned int sum_of_divisors(unsigned int N)
{
unsigned int sum = 1; /* 1 is always a divisor */
/* divisors are symmertically distributed about the square-root */
for (unsigned int i = 2; (i * i) <= N; i++)
{
if (N % i != 0)
/* i is not a proper divisor */
continue;
// #ifdef DEBUG
// printf("%4d, %4d,", i, N / i);
// #endif
sum += i;
if (i * i == N)
continue;
sum += N / i;
}
// #ifdef DEBUG
// printf("\nSum of divisors of %4d: %4d\n", N, sum);
// #endif
return sum;
}
int main(int argc, char **argv)
{
unsigned long sum = 0;
unsigned int MAX_N = 500;
if (argc == 2)
MAX_N = atoi(argv[1]);
/**
* We use an array of flags to check if a number at the index was:
* not-processed = 0
* is amicable = 1
* not amicable = -1
**/
char *flags = (char *)calloc(MAX_N, sizeof(char));
clock_t start_time = clock();
#ifdef _OPENMP
#pragma omp for schedule(runtime)
#endif
/* there are no such numbers till 10. Lets search from there on */
for (unsigned int i = 10; i < MAX_N; i++)
{
if (flags[i] != 0)
/* already processed, skip */
continue;
unsigned int b = sum_of_divisors(i);
if (b >= MAX_N)
flags[i] = -1;
else if (flags[b] == -1)
continue;
unsigned int c = sum_of_divisors(b);
if (c == i && b != i)
{
/* found amicable */
flags[b] = 1;
flags[i] = 1;
sum += b + i;
#ifdef DEBUG
printf("Amicable: %4d : %4d\n", i, b);
#endif
}
else
{
flags[i] = -1;
if (b < MAX_N)
flags[b] = -1;
}
}
clock_t end_time = clock();
printf("\nTime taken: %.4g millisecond\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("Sum of all numbers = %lu\n", sum);
free(flags);
return 0;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,138 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define MAX_NAMES 6000 /* Maximum number of names to store */
#define MAX_NAME_LEN 20 /* Maximum length of each name */
/**
* Alphabetical sorting using 'shell sort' algorithm
**/
void shell_sort(char data[][MAX_NAME_LEN], int LEN)
{
const int gaps[] = {701, 301, 132, 57, 23, 10, 4, 1};
const int gap_len = 8;
int i, j, g;
for (g = 0; g < gap_len; g++)
{
int gap = gaps[g];
for (i = gap; i < LEN; i++)
{
char tmp_buffer[MAX_NAME_LEN];
strcpy(tmp_buffer, data[i]);
for (j = i; j >= gap && strcmp(data[j - gap], tmp_buffer) > 0; j -= gap)
strcpy(data[j], data[j - gap]);
strcpy(data[j], tmp_buffer);
}
}
#ifdef DEBUG
for (i = 0; i < LEN; i++)
printf("%s\t", data[i]);
#endif
}
/**
* Alphabetical sorting using 'lazy sort' algorithm
**/
void lazy_sort(char data[][MAX_NAME_LEN], int LEN)
{
int i, j;
for (i = 0; i < LEN; i++)
{
for (j = i + 1; j < LEN; j++)
{
if (strcmp(data[i], data[j]) > 0)
{
char tmp_buffer[MAX_NAME_LEN];
strcpy(tmp_buffer, data[i]);
strcpy(data[i], data[j]);
strcpy(data[j], tmp_buffer);
}
}
}
#ifdef DEBUG
for (i = 0; i < LEN; i++)
printf("%s\t", data[i]);
#endif
}
int main(int argc, char **argv)
{
unsigned long COUNT = 0;
char *fname = "names.txt";
char names[MAX_NAMES][MAX_NAME_LEN];
short method = 0; /* sorting algorithm to use. 0 = lazy, 1 = shell-sort */
if (argc == 2)
method = atoi(argv[1]);
FILE *fp = fopen(fname, "rt");
if (!fp)
{
perror("Unable to open file");
return -1;
}
/**
* Loops to get total number of rows and columns in the file
**/
do
{
int ret = fscanf(fp, "\"%[^\",]\",", names[COUNT++]);
if (ret <= 0)
continue;
// printf("%s\t", names[COUNT - 1]);
} while (!feof(fp));
fclose(fp);
printf("\nTotal number of names: %lu\n", COUNT);
if (method == 0)
{
clock_t start_time = clock();
shell_sort(names, COUNT);
clock_t end_time = clock();
printf("\nShell sort: %.4g millisecond\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
}
else if (method == 1)
{
clock_t start_time = clock();
lazy_sort(names, COUNT);
clock_t end_time = clock();
printf("\nLazy sort: %.4g millisecond\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
}
long sum_score = 0;
clock_t start_time = clock();
#ifdef _OPENMP
#pragma omp parallel for schedule(runtime) reduction(+ \
: sum_score)
#endif
#ifdef DEBUG
for (unsigned int i = 935; i < 940; i++)
#else
for (unsigned int i = 0; i < COUNT; i++)
#endif
{
unsigned int score = 0;
/* score the alphabets in i^th name */
for (int j = 0; names[i][j] != '\0'; j++)
score += names[i][j] - 'A' + 1; /* convert ASCII character to integer score */
sum_score += score * (i + 1);
#ifdef DEBUG
printf("Name: %s\tScore: %u x %u = %lu\n", names[i], score, i + 1, (unsigned long)score * (i + 1));
#endif
}
clock_t end_time = clock();
printf("Scoring time: %.4g millisecond\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("Total Score = %lu\n", sum_score);
return 0;
}

View File

@ -0,0 +1,116 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
unsigned long MAX_N = 28123;
/**
* Returns:
* -1 if N is deficient
* 1 if N is abundant
* 0 if N is perfect
**/
char get_perfect_number(unsigned long N)
{
unsigned long sum = 1;
char ret = 0;
for (unsigned long i = 2; i * i <= N; i++)
{
if (N % i == 0)
{
sum += i;
unsigned long tmp = N / i;
if (tmp != i)
sum += tmp;
}
}
ret = sum == N ? 0 : (sum > N ? 1 : -1);
// #ifdef DEBUG
// printf("%5lu: %5lu : %d\n", N, sum, ret);
// #endif
return ret;
}
/**
* Is the given number an abundant number (1) or not (0)
**/
unsigned long is_abundant(unsigned long N)
{
return get_perfect_number(N) == 1 ? 1 : 0;
}
/**
* Find the next abundant number after N and not including N
**/
unsigned long get_next_abundant(unsigned long N)
{
unsigned long i;
for (i = N + 1; !is_abundant(i); i++)
;
return i;
}
/**
* check if a given number can be represented as a sum
* of two abundant numbers.
* 1 - if yes
* 0 - if not
**/
char is_sum_of_abundant(unsigned long N)
{
/** optimized logic:
* i + j = N where both i and j should be abundant
* hence we can simply check for j = N - i as we loop through i
**/
for (unsigned long i = get_next_abundant(1); i <= (N >> 1); i = get_next_abundant(i))
if (is_abundant(N - i))
{
#ifdef DEBUG
printf("\t%4lu + %4lu = %4lu\n", i, N - i, N);
#endif
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
unsigned long sum = 0;
if (argc == 2)
MAX_N = strtoul(argv[1], NULL, 10);
#ifdef _OPENMP
printf("Using OpenMP parallleization with %d threads\n", omp_get_max_threads());
#else
printf("Not using parallleization!\n");
#endif
clock_t dt = 0;
#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();
if (!is_sum_of_abundant(i))
sum += i;
clock_t end_time = clock();
dt += end_time - start_time;
printf("... %5lu: %8lu\r", i, sum);
if (i % 100 == 0)
fflush(stdout);
}
printf("Time taken: %.4g ms\n", 1e3 * dt / CLOCKS_PER_SEC);
printf("Sum of numbers that cannot be represented as sum of two abundant numbers : %lu\n", sum);
return 0;
}

View File

@ -0,0 +1,180 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/**
* Optimization 1 - compute & store abundant numbers once
* into a look-up array
**/
unsigned long MAX_N = 28123;
/**
* This is the global array to be used to store a flag to identify
* if a particular number is abundant (1) or not (0).
* Using a whole byte to store a binary info would be redundant.
* We will use each byte to represent 8 numbers by relying on bits.
* This saves memory required by 1/8
**/
char *abundant_flags = NULL;
/**
* Returns:
* -1 if N is deficient
* 1 if N is abundant
* 0 if N is perfect
**/
char get_perfect_number(unsigned long N)
{
unsigned long sum = 1;
char ret = 0;
for (unsigned long i = 2; i * i <= N; i++)
{
if (N % i == 0)
{
sum += i;
unsigned long tmp = N / i;
if (tmp != i)
sum += tmp;
}
}
ret = sum == N ? 0 : (sum > N ? 1 : -1);
#ifdef DEBUG
printf("%5lu: %5lu : %d\n", N, sum, ret);
#endif
return ret;
}
/**
* Is the given number an abundant number (1) or not (0)
**/
char is_abundant(unsigned long N)
{
// return abundant_flags[N >> 3] & (1 << N % 8) ? 1 : 0;
return abundant_flags[N >> 3] & (1 << (N & 7)) ? 1 : 0; /* optimized modulo operation */
}
/**
* Find the next abundant number after N and not including N
**/
unsigned long get_next_abundant(unsigned long N)
{
unsigned long i;
/* keep checking successive numbers till an abundant number is found */
for (i = N + 1; !is_abundant(i); ++i)
;
return i;
}
/**
* check if a given number can be represented as a sum
* of two abundant numbers.
* 1 - if yes
* 0 - if not
**/
char is_sum_of_abundant(unsigned long N)
{
/** optimized logic:
* i + j = N where both i and j should be abundant
* hence we can simply check for j = N - i as we loop through i
**/
for (unsigned long i = get_next_abundant(1); i <= (N >> 1); i = get_next_abundant(i))
if (is_abundant(N - i))
{
#ifdef DEBUG
printf("\t%4lu + %4lu = %4lu\n", i, N - i, N);
#endif
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
unsigned long sum = 0;
if (argc == 2)
MAX_N = strtoul(argv[1], NULL, 10);
/** byte array to store flags to identify abundant numbers
* the flags are identified by bits
**/
abundant_flags = (char *)calloc(MAX_N >> 3, 1);
if (!abundant_flags)
{
perror("Unable to allocate memoey!");
return -1;
}
#ifdef _OPENMP
printf("Using OpenMP parallleization with %d threads\n", omp_get_max_threads());
#else
printf("Not using parallleization!\n");
#endif
clock_t start_time = clock();
/* Loop to set abundant flags */
#ifdef _OPENMP
#pragma omp for schedule(runtime)
#endif
for (unsigned long N = 1; N <= MAX_N; N++)
{
char ret = get_perfect_number(N);
if (ret == 1)
{
// int byte_offset = N % 8, index = N >> 3;
int byte_offset = N & 7, index = N >> 3;
#ifdef _OPENMP
#pragma omp critical
#endif
abundant_flags[index] |= ret << byte_offset;
}
// if (i % 100 == 0)
// printf("... %5lu: %8lu\r", i, sum);
}
clock_t end_time = clock();
double t1 = 1e3 * (end_time - start_time) / CLOCKS_PER_SEC;
printf("Time taken to get abundant numbers: %.4g ms\n", t1);
clock_t t2 = 0;
#ifdef _OPENMP
#pragma omp for schedule(runtime) private(start_time, end_time)
#endif
for (unsigned long i = 1; i < MAX_N; i++)
{
start_time = clock();
if (!is_sum_of_abundant(i))
#ifdef _OPENMP
#pragma omp critical
#endif
sum += i;
end_time = clock();
#ifdef _OPENMP
#pragma omp critical
#endif
t2 += end_time - start_time;
printf("... %5lu: %8lu\r", i, sum);
if (i % 100 == 0)
fflush(stdout);
}
#ifdef DEBUG
putchar('\n');
#endif
double t22 = 1e3 * t2 / CLOCKS_PER_SEC;
printf("Time taken for final sum: %.4g ms\nTotal Time taken: %.4g ms\n", t22, t1 + t22);
printf("Memory used: %lu bytes\n", MAX_N >> 3);
printf("Sum of numbers that cannot be represented as sum of two abundant numbers : %lu\n", sum);
free(abundant_flags);
return 0;
}

BIN
project_euler/Problem 24/sol1 Executable file

Binary file not shown.

View File

@ -0,0 +1,109 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define MAX_DIGITS 1000
/**
* 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)
{
uint8_t carry = 0;
unsigned int i;
for (i = 0; i < N; i++)
{
// printf("\t%d + %d + %d ", a[i], b[i], carry);
c[i] = carry + a[i] + b[i];
if (c[i] > 9) /* check for carry */
{
carry = 1;
c[i] -= 10;
}
else
carry = 0;
// printf("= %d, %d\n", carry, c[i]);
}
while (carry != 0)
{
// printf("\t\t...adding new digit\n");
// printf("\t0 + %d + %d ", b[i], carry);
c[i] = carry + c[i];
if (c[i] > 9)
{
carry = 1;
c[i] -= 10;
}
else
carry = 0;
// printf("= %d, %d\n", carry, c[i]);
i++;
}
return i;
}
int print_number(uint8_t *number, int N)
{
int start_pos = N - 1;
/* skip all initial zeros */
while (number[start_pos] == 0)
start_pos--;
for (int i = start_pos; i >= 0; i--)
putchar(number[i] + 0x30);
return 0;
}
unsigned int get_digits(uint8_t *number)
{
unsigned int digits = MAX_DIGITS;
while (number[digits] == 0)
digits--;
return digits;
}
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];
memset(fn, 0, MAX_DIGITS);
memset(fn1, 0, MAX_DIGITS);
memset(sum, 0, MAX_DIGITS);
fn[0] = 1;
fn1[1] = 1;
unsigned int index = 1, digit_count = 1;
clock_t start_time = clock();
do
{
digit_count = add_numbers(fn, fn1, sum, digit_count);
// digit_count = get_digits(sum);
// printf("%5u (%u) (%u) ", index, digit_count, get_digits(sum));
// print_number(sum, digit_count);
// putchar('\n');
if (digit_count == MAX_DIGITS)
break;
memcpy(fn, fn1, MAX_DIGITS);
memcpy(fn1, sum, MAX_DIGITS);
index++;
} while (digit_count < MAX_DIGITS);
clock_t end_time = clock();
printf("Time taken: %.4g ms\n", 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
printf("The nth term for %d digits: %u \n", MAX_DIGITS, index--);
print_number(sum, digit_count);
return 0;
}

View File

@ -2,7 +2,7 @@
#include <stdlib.h>
#include <time.h>
#define ELEMENT_NR 20
#define ELEMENT_NR 20000
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
const char *notation = "Shell Sort Big O Notation:\
\n--> Best Case: O(n log(n)) \
@ -37,10 +37,38 @@ void shellSort(int array[], int len)
swap(&array[j], &array[j + gap]);
}
/**
* Optimized algorithm - takes half the time as other
**/
void shell_sort2(int array[], int LEN)
{
const int gaps[] = {701, 301, 132, 57, 23, 10, 4, 1};
const int gap_len = 8;
int i, j, g;
for (g = 0; g < gap_len; g++)
{
int gap = gaps[g];
for (i = gap; i < LEN; i++)
{
int tmp = array[i];
for (j = i; j >= gap && (array[j - gap] - tmp) > 0; j -= gap)
array[j] = array[j - gap];
array[j] = tmp;
}
}
#ifdef DEBUG
for (i = 0; i < LEN; i++)
printf("%s\t", data[i]);
#endif
}
int main(int argc, char *argv[])
{
int i;
int array[ELEMENT_NR];
int array2[ELEMENT_NR];
int range = 500;
int size;
clock_t start, end;
@ -48,7 +76,10 @@ int main(int argc, char *argv[])
srand(time(NULL));
for (i = 0; i < ELEMENT_NR; i++)
{
array[i] = rand() % range + 1;
array2[i] = array[i];
}
size = ARRAY_LEN(array);
@ -62,7 +93,19 @@ int main(int argc, char *argv[])
show_data(array, size);
printf("%s\n", notation);
printf("Time spent sorting: %f\n", time_spent);
printf("Time spent sorting: %.4g ms\n", time_spent * 1e3);
printf("--------------------------\n");
start = clock();
shell_sort2(array2, size);
end = clock();
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
printf("Data Sorted\n");
show_data(array2, size);
printf("%s\n", notation);
printf("Time spent sorting: %.4g ms\n", time_spent * 1e3);
return 0;
}