├── .gitignore ├── Recursion ├── factorial.c ├── sum_of_digits.c ├── tower_of_hanoi.c ├── ackermann.c ├── linear_search.c ├── nth_fibonacci_number.c ├── binary_search.c ├── palindrome.c ├── char_replace.c └── str_reverse.c ├── Math ├── is_prime.c ├── euclid_gcd.c ├── factors.c ├── prime_factors.c ├── gcd.c └── common_factors.c ├── Eular ├── sum_of_multiples_of_3_5.c ├── lattice_paths.c ├── special_pythagorean_triplet.c ├── longest_collatz_sequence.c ├── power_digit_sum.c ├── sieve_of_eratosthenes.c ├── highly_divisible_triangular_number.c ├── fibonacci_series.c ├── palindrome_of_numbers.c ├── sum_square_difference.c ├── maximum_path_sum_1.c ├── largest_product_in_series.c ├── smallest_multiple.c ├── largest_product_in_grid.c ├── number_to_words_and_letters_count.c └── large_sum.c ├── DSA ├── Sorting │ ├── insertion_sort.c │ ├── bubble_sort.c │ ├── selection_sort.c │ ├── shell_sort.c │ ├── quick_sort.c │ ├── merge_sort.c │ └── randomized_quick_sort.c ├── Search │ ├── linear_search.c │ └── binary_search.c ├── Misc │ ├── reservoir_sample.c │ └── luhn.c ├── Tree │ └── binary_search_tree.c └── LinkedList │ ├── doubly_linked_list.c │ └── singly_linked_list.c ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Recursion/factorial.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long long factorial(int n) 4 | { 5 | if (n < 2) { 6 | return n; 7 | } 8 | 9 | return n * factorial(n - 1); 10 | } 11 | 12 | int main() 13 | { 14 | assert(2 == factorial(2)); 15 | assert(6 == factorial(3)); 16 | assert(120 == factorial(5)); 17 | assert(3628800 == factorial(10)); 18 | assert(1307674368000 == factorial(15)); 19 | assert(2432902008176640000 == factorial(20)); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Recursion/sum_of_digits.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long long sum_of_digits(long long n) 4 | { 5 | if (n <= 0) { 6 | return 0; 7 | } 8 | 9 | return (n % 10) + sum_of_digits(n / 10); 10 | } 11 | 12 | int main() 13 | { 14 | assert(1 == sum_of_digits(1)); 15 | assert(3 == sum_of_digits(12)); 16 | assert(6 == sum_of_digits(123)); 17 | assert(15 == sum_of_digits(12345)); 18 | assert(45 == sum_of_digits(123456789)); 19 | assert(59 == sum_of_digits(12345678959)); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Recursion/tower_of_hanoi.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void tower_of_hanoi(int disk, char from, char aux, char to) 4 | { 5 | if (disk <= 1) { 6 | printf("Move disk %d from pole %c to %c\n", disk, from, to); 7 | 8 | return; 9 | } 10 | 11 | tower_of_hanoi(disk - 1, from, to, aux); 12 | printf("Move disk %d from pole %c to %c\n", disk, from, to); 13 | tower_of_hanoi(disk - 1, aux, from, to); 14 | } 15 | 16 | int main() 17 | { 18 | tower_of_hanoi(3, 'A', 'B', 'C'); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Recursion/ackermann.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long long ackermann(unsigned int m, unsigned long long n) 4 | { 5 | if (m == 0) { 6 | return n + 1; 7 | } 8 | 9 | if (n == 0) { 10 | return ackermann(m - 1, 1); 11 | } 12 | 13 | return ackermann(m - 1, ackermann(m, n - 1)); 14 | } 15 | 16 | int main() 17 | { 18 | assert(2 == ackermann(1, 0)); 19 | assert(11 == ackermann(2, 4)); 20 | assert(13 == ackermann(3, 1)); 21 | assert(125 == ackermann(3, 4)); 22 | assert(65533 == ackermann(4, 1)); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Recursion/linear_search.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int linear_search(int *a, int find, int index, int n) 4 | { 5 | if (index > n) { 6 | return -1; 7 | } 8 | 9 | if (a[index] == find) { 10 | return index; 11 | } 12 | 13 | return linear_search(a, find, index + 1, n); 14 | } 15 | 16 | int main() 17 | { 18 | int test_array[10] = {9, 2, 3, 5, 8, 7, 13, 17, 23, 48}; 19 | 20 | for (int i = 0; i < 10; i++) { 21 | assert(i == linear_search(test_array, test_array[i], 0, 10)); 22 | } 23 | 24 | assert(-1 == linear_search(test_array, 81, 0, 10)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Math/is_prime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | bool is_prime(int number) 6 | { 7 | int root = (int) sqrt(number); 8 | 9 | for (int i = 2; i <= root; i++) { 10 | if (number % i == 0) { 11 | return false; 12 | } 13 | } 14 | 15 | return true; 16 | } 17 | 18 | int main() 19 | { 20 | int primes[] = {2, 3, 7, 11, 13, 17}; 21 | int non_primes[] = {4, 6, 8, 12, 14, 15}; 22 | 23 | for (int i = 0; i < 6; i++) { 24 | assert(is_prime(primes[i])); 25 | assert(is_prime(non_primes[i]) == false); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Eular/sum_of_multiples_of_3_5.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Multiples of 3 and 5. 3 | * https://projecteuler.net/problem=1 4 | */ 5 | #include 6 | 7 | int sum_multiple_of(int num, int limit) 8 | { 9 | int sum = num; 10 | 11 | for (int i = num * 2; i < limit; i += num) { 12 | sum += i; 13 | } 14 | 15 | return sum; 16 | } 17 | 18 | int main() 19 | { 20 | int limit = 1000, operand_first = 3, operand_second = 5; 21 | 22 | int sum = sum_multiple_of(operand_first, limit) + sum_multiple_of(operand_second, limit) - sum_multiple_of(operand_first * operand_second, limit); 23 | 24 | printf("Sum: %d", sum); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Eular/lattice_paths.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Lattice paths. 3 | * https://projecteuler.net/problem=15 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | unsigned long long lattice_path(int grid) 10 | { 11 | double path = 1.0; 12 | 13 | for (int i = 1; i <= grid; i++) { 14 | path *= ((double) (grid + i) / i);; 15 | } 16 | 17 | return (unsigned long long) ceil(path); 18 | } 19 | 20 | int main() 21 | { 22 | assert(6 == lattice_path(2)); 23 | assert(252 == lattice_path(5)); 24 | assert(184756 == lattice_path(10)); 25 | assert(155117520 == lattice_path(15)); 26 | assert(137846528820 == lattice_path(20)); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Recursion/nth_fibonacci_number.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long int nth_fibonacci_number(unsigned int n) 4 | { 5 | if (n == 0) { 6 | return 0; 7 | } 8 | 9 | if (n <= 2) { 10 | return 1; 11 | } 12 | 13 | return nth_fibonacci_number(n - 1) + nth_fibonacci_number(n - 2); 14 | } 15 | 16 | int main() 17 | { 18 | int fibonacci_numbers[13] = { 19 | 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 233, 75025, 102334155 20 | }; 21 | 22 | unsigned int fibonacci_number_positions[13] = { 23 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 25, 40 24 | }; 25 | 26 | for (int i = 0; i < 13; i++) { 27 | assert(fibonacci_numbers[i] == nth_fibonacci_number(fibonacci_number_positions[i])); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Recursion/binary_search.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int binary_search(int *a, int find, int start, int end) 4 | { 5 | if (start > end) { 6 | return -1; 7 | } 8 | 9 | int mid = (start + end) / 2; 10 | 11 | if (a[mid] == find) { 12 | return mid; 13 | } 14 | 15 | if (find < a[mid]) { 16 | end = mid - 1; 17 | } else { 18 | start = mid + 1; 19 | } 20 | 21 | return binary_search(a, find, start, end); 22 | } 23 | 24 | int main() 25 | { 26 | int test_array[10] = {2, 3, 5, 7, 8, 9, 13, 17, 23, 48}; 27 | 28 | for (int i = 0; i < 10; i++) { 29 | assert(i == binary_search(test_array, test_array[i], 0, 9)); 30 | } 31 | 32 | assert(-1 == binary_search(test_array, 81, 0, 10)); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Recursion/palindrome.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool is_palindrome(char *str, int index, int size) 5 | { 6 | if (index > size / 2) { 7 | return true; 8 | } 9 | 10 | if (str[index] != str[size - index]) { 11 | return false; 12 | } 13 | 14 | return is_palindrome(str, index + 1, size); 15 | } 16 | 17 | int main() 18 | { 19 | assert(!is_palindrome("ankit", 0, 4)); 20 | assert(!is_palindrome("lirxil", 0, 5)); 21 | assert(!is_palindrome("kaayak", 0, 5)); 22 | assert(!is_palindrome("ka ya k", 0, 6)); 23 | assert(!is_palindrome("namasman", 0, 7)); 24 | 25 | assert(is_palindrome("liril", 0, 4)); 26 | assert(is_palindrome("kayak", 0, 4)); 27 | assert(is_palindrome("racecar", 0, 6)); 28 | assert(is_palindrome("rotator", 0, 6)); 29 | assert(is_palindrome("rottaattor", 0, 9)); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Math/euclid_gcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int euclid_gcd(int dividend, int divisor) 4 | { 5 | while (divisor != 0) { 6 | int remainder = dividend % divisor; 7 | 8 | dividend = divisor; 9 | divisor = remainder; 10 | } 11 | 12 | return dividend; 13 | } 14 | 15 | int euclid_gcd_recursive(int dividend, int divisor) 16 | { 17 | return divisor == 0 ? dividend : euclid_gcd_recursive(divisor, dividend % divisor); 18 | } 19 | 20 | int main() 21 | { 22 | assert(6 == euclid_gcd(888, 78)); 23 | assert(5 == euclid_gcd(45, 25)); 24 | assert(2 == euclid_gcd(142, 872)); 25 | assert(111 == euclid_gcd(999, 111)); 26 | assert(250 == euclid_gcd(4500, 1250)); 27 | 28 | assert(6 == euclid_gcd_recursive(888, 78)); 29 | assert(5 == euclid_gcd_recursive(45, 25)); 30 | assert(2 == euclid_gcd_recursive(142, 872)); 31 | assert(111 == euclid_gcd_recursive(999, 111)); 32 | assert(250 == euclid_gcd_recursive(4500, 1250)); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Eular/special_pythagorean_triplet.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Special pythagorean triplet. 3 | * https://projecteuler.net/problem=9 4 | */ 5 | 6 | #include 7 | 8 | unsigned long long pythagorean(int a, int b) 9 | { 10 | return (unsigned long long) a * a + b * b; 11 | } 12 | 13 | /** 14 | * a^2 + b^2 = (s-a-b)^2 where a < b < c 15 | * 16 | * @param int limit 17 | * 18 | * @return 19 | */ 20 | unsigned long long product_pythagorean_triplet(int limit) 21 | { 22 | for (int a = 3; a < (limit - 3) / 3; a++) { 23 | for (int b = a + 1; b < (limit - a - 1) / 2; b++) { 24 | int c = limit - a - b; 25 | if (c * c == pythagorean(a, b)) { 26 | return (unsigned long long) a * b * c; 27 | } 28 | } 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | int main() 35 | { 36 | assert(12180 == product_pythagorean_triplet(70)); 37 | assert(31875000 == product_pythagorean_triplet(1000)); 38 | assert(31875000000 == product_pythagorean_triplet(10000)); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /DSA/Sorting/insertion_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Insertion sort algorithm. 6 | * 7 | * @param int input Array to sort 8 | * @param int n Number of data in search array 9 | * 10 | * @return void 11 | */ 12 | void insertion_sort(int *input, int n) 13 | { 14 | int gap, key; 15 | 16 | for (int i = 1; i < n; i++) { 17 | key = input[i]; 18 | gap = i - 1; 19 | 20 | while (gap >= 0 && input[gap] > key) { 21 | input[gap + 1] = input[gap]; 22 | gap--; 23 | } 24 | 25 | input[gap + 1] = key; 26 | } 27 | } 28 | 29 | int main() 30 | { 31 | int n; 32 | 33 | printf("How many numbers? "); 34 | scanf("%d", &n); 35 | 36 | int *input = (int *) malloc(n * sizeof(int)); 37 | 38 | printf("Enter %d numbers: ", n); 39 | for (int i = 0; i < n; i++) { 40 | scanf("%d", input + i); 41 | } 42 | 43 | insertion_sort(input, n); 44 | 45 | for (int i = 0; i < n; i++) { 46 | printf("%d\t", *(input + i)); 47 | } 48 | 49 | free(input); 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ankit Pokhrel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Math/factors.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct FACTOR 7 | { 8 | int *factors; 9 | int count; 10 | } Factor; 11 | 12 | Factor get_factors(int n) 13 | { 14 | int root = (int) sqrt(n); 15 | 16 | int *factors = (int *) malloc((n / 2) * sizeof(int)); 17 | 18 | int j = 0; 19 | for (int i = 1; i <= root; i++) { 20 | if (n % i == 0) { 21 | factors[j++] = i; 22 | if (i != (n / i)) { 23 | factors[j++] = n / i; 24 | } 25 | } 26 | } 27 | 28 | Factor factor = { 29 | .factors = factors, 30 | .count = j 31 | }; 32 | 33 | return factor; 34 | } 35 | 36 | int main() 37 | { 38 | int n; 39 | Factor factors; 40 | 41 | printf("%s", "Enter n: "); 42 | scanf("%d", &n); 43 | 44 | factors = get_factors(n); 45 | 46 | printf("Total factors: %d\n", factors.count); 47 | for (int i = 0; i < factors.count; i++) { 48 | printf("%d ", factors.factors[i]); 49 | assert((n % factors.factors[i]) == 0); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /DSA/Search/linear_search.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Linear search algorithm. 6 | * 7 | * @param int a Search array 8 | * @param int find Data to search 9 | * @param int n Number of data in search array 10 | * 11 | * @return int Index of found data or -1 12 | */ 13 | int linear_search(int *a, int find, int n) 14 | { 15 | for (int i = 0; i < n; i++) { 16 | if (find == *(a+i)) { 17 | return i; 18 | } 19 | } 20 | 21 | return -1; 22 | } 23 | 24 | int main() 25 | { 26 | int n, find; 27 | 28 | printf("How many items? "); 29 | scanf("%d", &n); 30 | 31 | int *input = (int *) malloc(n * sizeof(int)); 32 | 33 | printf("Enter numbers: "); 34 | for (int i = 0; i < n; i++) { 35 | scanf("%d", input + i); 36 | } 37 | 38 | printf("Find: "); 39 | scanf("%d", &find); 40 | 41 | int position = linear_search(input, find, n); 42 | 43 | if (position != -1) { 44 | printf("Data found at position %d", position); 45 | } else { 46 | printf("Data not found"); 47 | } 48 | 49 | free(input); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /DSA/Sorting/bubble_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int *, int *); 5 | 6 | /** 7 | * Bubble sort algorithm. 8 | * 9 | * @param int input Array to sort 10 | * @param int n Number of data in search array 11 | * 12 | * @return void 13 | */ 14 | void bubble_sort(int *input, int n) 15 | { 16 | for (int i = 0; i < n - 1; i++) { 17 | for (int j = 0; j < n - i - 1; j++) { 18 | if (input[j] > input[j + 1]) { 19 | swap(input + j, input + j + 1); 20 | } 21 | } 22 | } 23 | } 24 | 25 | void swap(int *a, int *b) 26 | { 27 | int temp = *b; 28 | 29 | *b = *a; 30 | *a = temp; 31 | } 32 | 33 | int main() 34 | { 35 | int n; 36 | 37 | printf("How many numbers? "); 38 | scanf("%d", &n); 39 | 40 | int *input = (int *) malloc(n * sizeof(int)); 41 | 42 | printf("Enter %d numbers: ", n); 43 | for (int i = 0; i < n; i++) { 44 | scanf("%d", input + i); 45 | } 46 | 47 | bubble_sort(input, n); 48 | 49 | for (int i = 0; i < n; i++) { 50 | printf("%d\t", *(input + i)); 51 | } 52 | 53 | free(input); 54 | } 55 | -------------------------------------------------------------------------------- /Math/prime_factors.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAX_FACTORS 25 6 | 7 | typedef struct PRIME_FACTORS 8 | { 9 | unsigned long *factors; 10 | unsigned long count; 11 | } Prime_Factor; 12 | 13 | Prime_Factor prime_factors(unsigned long n) 14 | { 15 | int root = (int) sqrt(n); 16 | unsigned long *factors = (unsigned long *) malloc(MAX_FACTORS * sizeof(unsigned long)); 17 | 18 | unsigned long j = 0; 19 | for (unsigned long i = 2; i <= root; i++) { 20 | if (n % i == 0) { 21 | while (n % i == 0) { 22 | n = n / i; 23 | factors[j++] = i; 24 | } 25 | } 26 | } 27 | 28 | if (n != 1) { 29 | factors[j++] = n; 30 | } 31 | 32 | Prime_Factor factor = { 33 | .factors = factors, 34 | .count = j 35 | }; 36 | 37 | return factor; 38 | } 39 | 40 | int main() 41 | { 42 | unsigned long n; 43 | 44 | printf("%s", "Enter n: "); 45 | scanf("%lu", &n); 46 | 47 | Prime_Factor factor = prime_factors(n); 48 | 49 | for (int i = 0; i < factor.count; i++) { 50 | printf("%lu ", factor.factors[i]); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Eular/longest_collatz_sequence.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Longest Collatz sequence. 3 | * https://projecteuler.net/problem=14 4 | */ 5 | 6 | #include 7 | 8 | unsigned long next_collatz_sequence(unsigned long n) 9 | { 10 | if (n % 2 == 0) { 11 | return n / 2; 12 | } 13 | 14 | return 3 * n + 1; 15 | } 16 | 17 | int collatz_sequence(unsigned long n) 18 | { 19 | int num_sequence = 1; 20 | 21 | while (n > 1) { 22 | ++num_sequence; 23 | 24 | n = next_collatz_sequence(n); 25 | } 26 | 27 | return num_sequence; 28 | } 29 | 30 | unsigned long longest_collatz_sequence(unsigned long limit) 31 | { 32 | int sequence, largest = 0; 33 | unsigned long num = limit; 34 | 35 | for (unsigned long i = limit / 2; i <= limit; i++) { 36 | sequence = collatz_sequence(i); 37 | 38 | if (sequence > largest) { 39 | num = i; 40 | largest = sequence; 41 | } 42 | } 43 | 44 | return num; 45 | } 46 | 47 | int main() 48 | { 49 | assert(9 == longest_collatz_sequence(13)); 50 | assert(871 == longest_collatz_sequence(1000)); 51 | assert(6171 == longest_collatz_sequence(10000)); 52 | assert(77031 == longest_collatz_sequence(100000)); 53 | assert(837799 == longest_collatz_sequence(1000000)); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /DSA/Sorting/selection_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int *, int *); 5 | 6 | /** 7 | * Selection sort algorithm. 8 | * 9 | * @param int input Array to sort 10 | * @param int n Number of data in search array 11 | * 12 | * @return void 13 | */ 14 | void selection_sort(int *input, int n) 15 | { 16 | int min; 17 | 18 | for (int i = 0; i < n - 1; i++) { 19 | min = i; 20 | 21 | for (int j = i + 1; j < n; j++) { 22 | if (input[j] < input[min]) { 23 | min = j; 24 | } 25 | } 26 | 27 | if (min != i) { 28 | swap(input + i, input + min); 29 | } 30 | } 31 | } 32 | 33 | /** 34 | * Swap two integers. 35 | * 36 | * @param int a 37 | * @param int b 38 | * 39 | * @return void 40 | */ 41 | void swap(int *a, int *b) 42 | { 43 | int temp = *b; 44 | 45 | *b = *a; 46 | *a = temp; 47 | } 48 | 49 | int main() 50 | { 51 | int n; 52 | 53 | printf("How many numbers? "); 54 | scanf("%d", &n); 55 | 56 | int *input = (int *) malloc(n * sizeof(int)); 57 | 58 | printf("Enter %d numbers: ", n); 59 | for (int i = 0; i < n; i++) { 60 | scanf("%d", input + i); 61 | } 62 | 63 | selection_sort(input, n); 64 | 65 | for (int i = 0; i < n; i++) { 66 | printf("%d\t", *(input + i)); 67 | } 68 | 69 | free(input); 70 | } 71 | -------------------------------------------------------------------------------- /Eular/power_digit_sum.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Power digit sum. 3 | * https://projecteuler.net/problem=16 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int array_sum(int *arr, int length) 11 | { 12 | int sum = 0; 13 | 14 | for (int i = 0; i < length; i++) { 15 | sum = sum + arr[i]; 16 | } 17 | 18 | return sum; 19 | } 20 | 21 | int power_digit_sum(int n) 22 | { 23 | size_t max_required_space = (size_t) ceil(0.35 * n); 24 | 25 | int *power = (int *) calloc(max_required_space, sizeof(int)); 26 | 27 | power[0] = 1; 28 | 29 | for (int i = 1; i <= n; i++) { 30 | power[0] = 2 * power[0]; 31 | 32 | for (int k = 1; k < max_required_space; k++) { 33 | power[k] = 2 * power[k] + power[k - 1] / 10; 34 | } 35 | 36 | for (int j = 0; j < max_required_space; j++) { 37 | power[j] = power[j] % 10; 38 | } 39 | } 40 | 41 | return array_sum(power, (int) max_required_space); 42 | } 43 | 44 | int main() 45 | { 46 | assert(5 == power_digit_sum(5)); 47 | assert(26 == power_digit_sum(15)); 48 | assert(115 == power_digit_sum(100)); 49 | assert(679 == power_digit_sum(500)); 50 | assert(1366 == power_digit_sum(1000)); 51 | assert(2035 == power_digit_sum(1500)); 52 | assert(2704 == power_digit_sum(2000)); 53 | assert(3871 == power_digit_sum(3000)); 54 | } 55 | -------------------------------------------------------------------------------- /DSA/Search/binary_search.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Binary search algorithm. 6 | * 7 | * @param int a Search array 8 | * @param int find Data to search 9 | * @param int n Number of data in search array 10 | * 11 | * @return int Index of found data or -1 12 | */ 13 | int binary_search(int *a, int find, int n) 14 | { 15 | int start = 0; 16 | int end = n - 1; 17 | int mid = n / 2; 18 | 19 | while (start <= end) { 20 | if (a[mid] == find) { 21 | return mid; 22 | } 23 | 24 | if (find < a[mid]) { 25 | end = mid - 1; 26 | } else { 27 | start = mid + 1; 28 | } 29 | 30 | mid = (start + end) / 2; 31 | } 32 | 33 | return -1; 34 | } 35 | 36 | int main() 37 | { 38 | int n, find; 39 | 40 | printf("How many items? "); 41 | scanf("%d", &n); 42 | 43 | int *input = (int *) malloc(n * sizeof(int)); 44 | 45 | printf("Enter numbers: "); 46 | for (int i = 0; i < n; i++) { 47 | scanf("%d", input + i); 48 | } 49 | 50 | printf("Find: "); 51 | scanf("%d", &find); 52 | 53 | int position = binary_search(input, find, n); 54 | 55 | if (position != -1) { 56 | printf("Data found at position %d", position); 57 | } else { 58 | printf("Data not found"); 59 | } 60 | 61 | free(input); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Eular/sieve_of_eratosthenes.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Sieve of eratosthenes. 3 | * 4 | * https://projecteuler.net/problem=7 5 | * https://projecteuler.net/problem=10 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | bool is_prime(int number) 15 | { 16 | int root = (int) sqrt(number); 17 | 18 | for (int i = 2; i <= root; i++) { 19 | if (number % i == 0) { 20 | return false; 21 | } 22 | } 23 | 24 | return true; 25 | } 26 | 27 | int *sieve_of_eratosthenes(int n) 28 | { 29 | int root, *primes; 30 | 31 | primes = (int *) malloc(n * sizeof(int)); 32 | 33 | primes[0] = primes[1] = 0; 34 | for (int i = 2; i < n; i++) { 35 | primes[i] = 1; 36 | } 37 | 38 | root = (int) sqrt(n); 39 | 40 | for (int i = 2; i <= root; i++) { 41 | if (is_prime(i)) { 42 | for (int j = 2; (i * j) <= n; j++) { 43 | primes[i * j] = 0; 44 | } 45 | } 46 | } 47 | 48 | return primes; 49 | } 50 | 51 | int main() 52 | { 53 | int n, *primes; 54 | 55 | printf("%s", "How many data? "); 56 | scanf("%d", &n); 57 | 58 | primes = sieve_of_eratosthenes(n); 59 | 60 | for (int i = 0; i < n; i++) { 61 | if (primes[i]) { 62 | printf("%d ", i); 63 | assert(is_prime(i)); 64 | } 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Math/gcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct FACTOR 7 | { 8 | int *factors; 9 | int count; 10 | } Factor; 11 | 12 | Factor get_common_factors(int a, int b) 13 | { 14 | int root = (int) sqrt(a); 15 | 16 | int *factors = (int *) malloc((a / 2) * sizeof(int)); 17 | 18 | int j = 0; 19 | for (int i = 1; i <= root; i++) { 20 | if (a % i == 0) { 21 | if (b % i == 0) { 22 | factors[j++] = i; 23 | } 24 | 25 | int f = a / i; 26 | if (f != i && b % f == 0) { 27 | factors[j++] = a / i; 28 | } 29 | } 30 | } 31 | 32 | Factor factor = { 33 | .factors = factors, 34 | .count = j 35 | }; 36 | 37 | return factor; 38 | } 39 | 40 | int gcd(int a, int b) 41 | { 42 | Factor common_factors = get_common_factors(a, b); 43 | 44 | int largest = common_factors.factors[0]; 45 | for (int i = 1; i < common_factors.count; i++) { 46 | if (common_factors.factors[i] > largest) { 47 | largest = common_factors.factors[i]; 48 | } 49 | } 50 | 51 | return largest; 52 | } 53 | 54 | int main() 55 | { 56 | assert(6 == gcd(888, 78)); 57 | assert(5 == gcd(45, 25)); 58 | assert(2 == gcd(142, 872)); 59 | assert(111 == gcd(999, 111)); 60 | assert(250 == gcd(4500, 1250)); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /DSA/Misc/reservoir_sample.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Reservoir sampling is a family of randomized algorithms for randomly choosing a sample 3 | * of k items from a list P containing n items, where n is either a very large or unknown 4 | * number. Typically n is large enough that the list doesn't fit into main memory. 5 | * 6 | * https://en.wikipedia.org/wiki/Reservoir_sampling 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #define POPULATION_SIZE 2000 13 | #define SAMPLE_SIZE 100 14 | 15 | unsigned int get_random_value(unsigned int min, unsigned int max) 16 | { 17 | return arc4random_uniform(max - min) + min; 18 | } 19 | 20 | int *reservoir_sample(int *population) 21 | { 22 | unsigned int i, j; 23 | 24 | int *sample = (int *) calloc(SAMPLE_SIZE, sizeof(int)); 25 | 26 | for (i = 0; i < SAMPLE_SIZE; i++) { 27 | sample[i] = population[i]; 28 | } 29 | 30 | for (i = SAMPLE_SIZE + 1; i < POPULATION_SIZE; i++) { 31 | j = get_random_value(1, i + 1); 32 | if (j <= SAMPLE_SIZE) { 33 | sample[j] = population[i]; 34 | } 35 | } 36 | 37 | return sample; 38 | } 39 | 40 | int main() 41 | { 42 | int population[POPULATION_SIZE]; 43 | 44 | for (int i = 0; i < POPULATION_SIZE; i++) { 45 | population[i] = get_random_value(1, POPULATION_SIZE); 46 | } 47 | 48 | int *sample = reservoir_sample(population); 49 | 50 | for (int i = 0; i < SAMPLE_SIZE; i++) { 51 | printf("%d ", sample[i]); 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Math/common_factors.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct FACTOR 7 | { 8 | int *factors; 9 | int count; 10 | } Factor; 11 | 12 | Factor get_common_factors(int a, int b) 13 | { 14 | int root = (int) sqrt(a); 15 | 16 | int *factors = (int *) malloc((a / 2) * sizeof(int)); 17 | 18 | int j = 0; 19 | for (int i = 1; i <= root; i++) { 20 | if (a % i == 0) { 21 | if (b % i == 0) { 22 | factors[j++] = i; 23 | } 24 | 25 | int f = a / i; 26 | if (f != i && b % f == 0) { 27 | factors[j++] = a / i; 28 | } 29 | } 30 | } 31 | 32 | Factor factor = { 33 | .factors = factors, 34 | .count = j 35 | }; 36 | 37 | return factor; 38 | } 39 | 40 | int main() 41 | { 42 | int test_data[3][2] = { 43 | {54, 27}, 44 | {350, 105}, 45 | {81, 405} 46 | }; 47 | 48 | Factor factors; 49 | for (int i = 0; i < 3; i++) { 50 | factors = get_common_factors(test_data[i][0], test_data[i][1]); 51 | 52 | printf("\n%d common factors for (%d, %d): ", factors.count, test_data[i][0], test_data[i][1]); 53 | for (int k = 0; k < factors.count; k++) { 54 | printf("%d ", factors.factors[k]); 55 | assert(test_data[i][0] % factors.factors[k] == 0); 56 | assert(test_data[i][1] % factors.factors[k] == 0); 57 | } 58 | } 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /DSA/Sorting/shell_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Insertion sort algorithm. 6 | * 7 | * @param int input Array to sort 8 | * @param int n Number of data in search array 9 | * 10 | * @return void 11 | */ 12 | void insertion_sort(int *input, int n, int span) 13 | { 14 | int gap, key; 15 | 16 | for (int i = span; i < n; i += span) { 17 | key = input[i]; 18 | gap = i - span; 19 | 20 | while (gap >= 0 && input[gap] > key) { 21 | input[gap + span] = input[gap]; 22 | gap -= span; 23 | } 24 | 25 | input[gap + span] = key; 26 | } 27 | } 28 | 29 | /** 30 | * Shell sort algorithm. 31 | * 32 | * @param int input Array to sort 33 | * @param int n Number of data in search array 34 | * 35 | * @return void 36 | */ 37 | void shell_sort(int *input, int n) 38 | { 39 | int span = n / 2; 40 | 41 | while (span > 0) { 42 | //perform insertion sort on subset 43 | insertion_sort(input, n, span); 44 | 45 | span = span / 2; 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | int n; 52 | 53 | printf("How many numbers? "); 54 | scanf("%d", &n); 55 | 56 | int *input = (int *) malloc(n * sizeof(int)); 57 | 58 | printf("Enter %d numbers: ", n); 59 | for (int i = 0; i < n; i++) { 60 | scanf("%d", input + i); 61 | } 62 | 63 | shell_sort(input, n); 64 | 65 | for (int i = 0; i < n; i++) { 66 | printf("%d\t", *(input + i)); 67 | } 68 | 69 | free(input); 70 | } 71 | -------------------------------------------------------------------------------- /Eular/highly_divisible_triangular_number.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Highly divisible traingular number. 3 | * https://projecteuler.net/problem=12 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct FACTOR 11 | { 12 | int *factors; 13 | int count; 14 | } Factor; 15 | 16 | Factor get_factors(int n) 17 | { 18 | int root = (int) sqrt(n); 19 | 20 | int *factors = (int *) malloc((n / 2) * sizeof(int)); 21 | 22 | int j = 0; 23 | for (int i = 1; i <= root; i++) { 24 | if (n % i == 0) { 25 | factors[j++] = i; 26 | if (i != (n / i)) { 27 | factors[j++] = n / i; 28 | } 29 | } 30 | } 31 | 32 | Factor factor = { 33 | .factors = factors, 34 | .count = j 35 | }; 36 | 37 | return factor; 38 | } 39 | 40 | unsigned long highly_divisible_triangular_number(int divisors) 41 | { 42 | int factorCount = 0; 43 | unsigned long triangularNumber = 1; 44 | 45 | Factor factor; 46 | 47 | unsigned long i = 1; 48 | while (factorCount <= divisors) { 49 | factor = get_factors((int) triangularNumber); 50 | 51 | factorCount = factor.count; 52 | 53 | triangularNumber += (++i); 54 | 55 | free(factor.factors); 56 | } 57 | 58 | return triangularNumber - i; 59 | } 60 | 61 | int main() 62 | { 63 | assert(28 == highly_divisible_triangular_number(5)); 64 | assert(73920 == highly_divisible_triangular_number(100)); 65 | assert(76576500 == highly_divisible_triangular_number(500)); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /DSA/Misc/luhn.c: -------------------------------------------------------------------------------- 1 | /** 2 | * The Luhn algorithm or Luhn formulam is a simple checksum formula 3 | * used to validate a variety of identification numbers, such as 4 | * credit card numbers, IMEI numbers etc. 5 | * 6 | * https://en.wikipedia.org/wiki/Luhn_algorithm 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | int *get_array(char *str, int len) 14 | { 15 | int *arr = (int *) malloc(len * sizeof(int)); 16 | 17 | for (int i = 0; i < len; i++) { 18 | arr[i] = str[i] - '0'; 19 | } 20 | 21 | return arr; 22 | } 23 | 24 | int array_sum(int *arr, int len) 25 | { 26 | int sum = 0; 27 | for (int i = 0; i < len; i++) { 28 | sum += arr[i]; 29 | } 30 | 31 | return sum; 32 | } 33 | 34 | int luhn_check_sum(char *str) 35 | { 36 | int len = (int) strlen(str); 37 | 38 | int *arr = get_array(str, len); 39 | 40 | for (int i = len - 1; i >= 0; i -= 2) { 41 | int multiple = arr[i] * 2; 42 | 43 | if (multiple > 9) { 44 | multiple -= 9; 45 | } 46 | 47 | arr[i] = multiple; 48 | } 49 | 50 | int sum = array_sum(arr, len); 51 | 52 | return sum * 9 % 10; 53 | } 54 | 55 | int main() 56 | { 57 | char *test_card_numbers[] = { 58 | "601100099013942", "37828224631000", 59 | "37144963539843", "555555555555444", 60 | "501971701010374", "552263411203590" 61 | }; 62 | 63 | int check_bits[] = {4, 5, 1, 4, 2, 6}; 64 | 65 | for (int i = 0; i < 6; i++) { 66 | assert(check_bits[i] == luhn_check_sum(test_card_numbers[i])); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Recursion/char_replace.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Replace char ch with given character in a string. 6 | * 7 | * @param char* str 8 | * @param char ch Character to replace 9 | * @param char with Replacing character 10 | * @param int index Current index 11 | * 12 | * return void 13 | */ 14 | void char_replace(char *str, char ch, char with, int index) 15 | { 16 | if (str[index] == '\0') { 17 | return; 18 | } 19 | 20 | if (str[index] == ch) { 21 | str[index] = with; 22 | } 23 | 24 | char_replace(str, ch, with, index + 1); 25 | } 26 | 27 | int main() 28 | { 29 | char test_str[7][120] = { 30 | "ankit", "ankit pokhrel", "namaste", "This is a crazy world!", "C programming language", 31 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 32 | "Pellentesque varius, lorem id consequat elementum, elit dolor suscipit neque, vel rhoncus turpis est vitae lacus." 33 | }; 34 | 35 | char test_replace[7][2] = { 36 | {'n', 'e'}, {'k', 'x'}, {'a', 'p'}, {'i', 'q'}, 37 | {'m', 'z'}, {'m', 'y'}, {'e', 'x'} 38 | }; 39 | 40 | char expected_output[7][120] = { 41 | "aekit", "anxit poxhrel", "npmpste", "Thqs qs a crazy world!", "C prograzzing language", 42 | "Lorey ipsuy dolor sit ayet, consectetur adipiscing elit.", 43 | "Pxllxntxsqux varius, lorxm id consxquat xlxmxntum, xlit dolor suscipit nxqux, vxl rhoncus turpis xst vitax lacus." 44 | }; 45 | 46 | for (int i = 0; i < 7; i++) { 47 | char_replace(test_str[i], test_replace[i][0], test_replace[i][1], 0); 48 | 49 | assert(strcmp(expected_output[i], test_str[i]) == 0); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Eular/fibonacci_series.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Fibonacci series and even Fibonacci numbers. 3 | * https://projecteuler.net/problem=2 4 | */ 5 | 6 | #include 7 | 8 | #define LIMIT 4000000 9 | 10 | /** 11 | * Print fibonacci series less than LIMIT. 12 | * 13 | * @param int a 14 | * @param int b 15 | * 16 | * @return void 17 | */ 18 | void print_fibonacci_series(int a, int b) 19 | { 20 | int sum = a + b; 21 | 22 | if (sum > LIMIT) { 23 | return; 24 | } 25 | 26 | printf("%d ", sum); 27 | 28 | print_fibonacci_series(b, sum); 29 | } 30 | 31 | /** 32 | * Print N fibonacci series. 33 | * 34 | * @param int n 35 | * 36 | * @return unsigned long 37 | */ 38 | unsigned long num_fibonacci(int n) 39 | { 40 | if (n < 2) { 41 | return (unsigned long) n; 42 | } 43 | 44 | return num_fibonacci(n - 1) + num_fibonacci(n - 2); 45 | } 46 | 47 | /** 48 | * Get sum of even fibonacci series up to LIMIT. 49 | * 50 | * @param int a 51 | * @param int b 52 | * @param int c 53 | * 54 | * @return unsigned long 55 | */ 56 | unsigned long sum_even_fibonacci(int a, int b, int c) 57 | { 58 | static unsigned long sum = 0; 59 | 60 | if (c > LIMIT) { 61 | return 0; 62 | } 63 | 64 | sum += c; 65 | a = b + c; 66 | b = c + a; 67 | 68 | sum_even_fibonacci(a, b, a + b); 69 | 70 | return sum; 71 | } 72 | 73 | int main() 74 | { 75 | int limit; 76 | 77 | print_fibonacci_series(-1, 1); 78 | 79 | printf("\n\nSum of even fibonacci up to %d is %lu", LIMIT, sum_even_fibonacci(1, 1, 2)); 80 | 81 | printf("\n\nEnter N to print N fibonacci numbers: "); 82 | scanf("%d", &limit); 83 | 84 | for (int i = 0; i < limit; i++) { 85 | printf("%lu ", num_fibonacci(i)); 86 | } 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /DSA/Sorting/quick_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int *, int *); 5 | 6 | /** 7 | * Partitioning logic. 8 | * 9 | * @param integer input Input array 10 | * @param int start Start index of an array 11 | * @param int end End index of an array 12 | * 13 | * @return int Partitioning pivot 14 | */ 15 | int partition(int *input, int start, int end) 16 | { 17 | int pivot = start; 18 | 19 | for (int i = start; i < end; i++) { 20 | if (input[i] < input[end]) { 21 | swap(input + i, input + pivot); 22 | pivot++; 23 | } 24 | } 25 | 26 | swap(input + pivot, input + end); 27 | 28 | return pivot; 29 | } 30 | 31 | /** 32 | * Quick sort algorithm. 33 | * 34 | * @param int input Array to sort 35 | * @param int start Start index of an array 36 | * @param int end End index of an array 37 | * 38 | * @return void 39 | */ 40 | void quick_sort(int *input, int start, int end) 41 | { 42 | if (start >= end) { 43 | return; 44 | } 45 | 46 | int pivot = partition(input, start, end); 47 | 48 | quick_sort(input, start, pivot - 1); 49 | quick_sort(input, pivot + 1, end); 50 | } 51 | 52 | /** 53 | * Swap two integers. 54 | * 55 | * @param int a 56 | * @param int b 57 | * 58 | * @return void 59 | */ 60 | void swap(int *a, int *b) 61 | { 62 | int temp = *b; 63 | 64 | *b = *a; 65 | *a = temp; 66 | } 67 | 68 | int main() 69 | { 70 | int n; 71 | 72 | printf("How many numbers? "); 73 | scanf("%d", &n); 74 | 75 | int *input = (int *) malloc(n * sizeof(int)); 76 | 77 | printf("Enter %d numbers: ", n); 78 | for (int i = 0; i < n; i++) { 79 | scanf("%d", input + i); 80 | } 81 | 82 | quick_sort(input, 0, n - 1); 83 | 84 | for (int i = 0; i < n; i++) { 85 | printf("%d\t", *(input + i)); 86 | } 87 | 88 | free(input); 89 | } 90 | -------------------------------------------------------------------------------- /Eular/palindrome_of_numbers.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Largest palindrome product. 3 | * https://projecteuler.net/problem=4 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /** 10 | * Check if a number is palindrome. 11 | * 12 | * @param unsigned long long num 13 | * 14 | * @return bool 15 | */ 16 | bool is_palindrome(unsigned long long num) 17 | { 18 | int digit; 19 | unsigned long long n = num; 20 | unsigned long long reverse = 0; 21 | 22 | while (n > 0) { 23 | digit = (int) (n % 10); 24 | reverse = reverse * 10 + digit; 25 | n /= 10; 26 | } 27 | 28 | return num == reverse; 29 | } 30 | 31 | /** 32 | * Find largest palindrome made from the product 33 | * of two n-digit numbers. 34 | * 35 | * @param int digit 36 | * 37 | * @return unsigned long long 38 | */ 39 | unsigned long long largest_palindrome(int digit) 40 | { 41 | int first_digit = digit / 10; 42 | unsigned long long multiple = 0; 43 | unsigned long long largest = 0; 44 | 45 | for (int i = digit - 1; i >= first_digit; i--) { 46 | for (int j = digit - 1; j >= i; j--) { 47 | multiple = (unsigned long long) i * j; 48 | if (multiple < largest) { 49 | break; 50 | } 51 | 52 | if (is_palindrome(multiple)) { 53 | largest = multiple; 54 | } 55 | } 56 | } 57 | 58 | return largest; 59 | } 60 | 61 | int main(void) 62 | { 63 | unsigned long long palindromes[] = {0, 11, 121, 10201, 9009, 12321}; 64 | unsigned long long non_palindromes[] = {12, 123, 11210, 9109, 12345}; 65 | 66 | for (int i = 0; i < 6; i++) { 67 | assert(is_palindrome(palindromes[i])); 68 | assert(is_palindrome(non_palindromes[i]) == false); 69 | } 70 | 71 | assert(9009 == largest_palindrome(100)); 72 | assert(222222 == largest_palindrome(500)); 73 | assert(906609 == largest_palindrome(1000)); 74 | assert(99000099 == largest_palindrome(10000)); 75 | assert(9966006699 == largest_palindrome(100000)); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /DSA/Sorting/merge_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void merge(int *, int, int); 6 | 7 | /** 8 | * Merge sort algorithm. 9 | * 10 | * @param int input Array to sort 11 | * @param int n Number of data in search array 12 | * 13 | * @return void 14 | */ 15 | void merge_sort(int *data, int start, int end) 16 | { 17 | if (start == end) { 18 | return; 19 | } 20 | 21 | int mid = (start + end) / 2; 22 | 23 | if (start < end) { 24 | merge_sort(data, start, mid); 25 | merge_sort(data, mid + 1, end); 26 | 27 | merge(data, start, end); 28 | } 29 | } 30 | 31 | /** 32 | * Merge two sub arrays. 33 | * 34 | * @param int data Array 35 | * @param int start Start index of an array 36 | * @param int end End index of an array 37 | * 38 | * @return void 39 | */ 40 | void merge(int *data, int start, int end) 41 | { 42 | int mid = (start + end) / 2; 43 | 44 | int i = start, j = mid + 1, k = 0; 45 | 46 | int *temp = (int *) malloc((end - start) * sizeof(int)); 47 | 48 | while (i <= mid && j <= end) { 49 | if (*(data + i) < *(data + j)) { 50 | temp[k++] = data[i++]; 51 | } else { 52 | temp[k++] = data[j++]; 53 | } 54 | } 55 | 56 | //leftovers from left sub array 57 | while (i <= mid) { 58 | temp[k++] = data[i++]; 59 | } 60 | 61 | //leftovers from right sub array 62 | while (j <= end) { 63 | temp[k++] = data[j++]; 64 | } 65 | 66 | //copy items to original array 67 | memcpy(data + start, temp, (end - start + 1) * sizeof(int)); 68 | 69 | free(temp); 70 | } 71 | 72 | int main() 73 | { 74 | int n; 75 | 76 | printf("How many numbers? "); 77 | scanf("%d", &n); 78 | 79 | int *input = (int *) malloc(n * sizeof(int)); 80 | 81 | printf("Enter %d numbers: ", n); 82 | for (int i = 0; i < n; i++) { 83 | scanf("%d", &input[i]); 84 | } 85 | 86 | merge_sort(input, 0, n - 1); 87 | 88 | for (int i = 0; i < n; i++) { 89 | printf("%d\t", *(input + i)); 90 | } 91 | 92 | free(input); 93 | } 94 | -------------------------------------------------------------------------------- /Eular/sum_square_difference.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Sum square difference. 3 | * https://projecteuler.net/problem=6 4 | */ 5 | 6 | #include 7 | 8 | /** 9 | * General approach to find sum of squares 10 | * for sequence N. 11 | * 12 | * @param int limit 13 | * @return 14 | */ 15 | unsigned long long sum_of_squares(int limit) 16 | { 17 | unsigned long long sum = 0; 18 | 19 | for (int i = 1; i <= limit; i++) { 20 | sum += (i * i); 21 | } 22 | 23 | return sum; 24 | } 25 | 26 | /** 27 | * General approach to find square of sum 28 | * for sequence N. 29 | * 30 | * @param int limit 31 | * @return 32 | */ 33 | unsigned long long square_of_sum(int limit) 34 | { 35 | unsigned long long sum = 0; 36 | 37 | for (int i = 1; i <= limit; i++) { 38 | sum += i; 39 | } 40 | 41 | return sum * sum; 42 | } 43 | 44 | /** 45 | * Sum of squares of N sequence is given by 46 | * (N * (N+1) * (2N+1)) / 6. 47 | * 48 | * @param int limit 49 | * 50 | * @return unsigned long long 51 | */ 52 | unsigned long long sum_of_squares_efficient(int limit) 53 | { 54 | return (unsigned long long) (limit * (limit + 1) * (2 * limit + 1)) / 6; 55 | } 56 | 57 | /** 58 | * Sum of digits of N sequence is given by 59 | * (N * (N+1)) / 2. 60 | * 61 | * @param int limit 62 | * 63 | * @return unsigned long long 64 | */ 65 | unsigned long long square_of_sum_efficient(int limit) 66 | { 67 | int sum = (limit * (limit + 1)) / 2; 68 | 69 | return (unsigned long long) sum * sum; 70 | } 71 | 72 | int main() 73 | { 74 | assert(2640 == (square_of_sum(10) - sum_of_squares(10))); 75 | assert(41230 == (square_of_sum(20) - sum_of_squares(20))); 76 | assert(1582700 == (square_of_sum(50) - sum_of_squares(50))); 77 | assert(25164150 == (square_of_sum(100) - sum_of_squares(100))); 78 | 79 | assert(2640 == (square_of_sum_efficient(10) - sum_of_squares_efficient(10))); 80 | assert(41230 == (square_of_sum_efficient(20) - sum_of_squares_efficient(20))); 81 | assert(1582700 == (square_of_sum_efficient(50) - sum_of_squares_efficient(50))); 82 | assert(25164150 == (square_of_sum_efficient(100) - sum_of_squares_efficient(100))); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /DSA/Sorting/randomized_quick_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void swap(int *, int *); 5 | 6 | /** 7 | * Partitioning logic. 8 | * 9 | * @param integer input Input array 10 | * @param int start Start index of an array 11 | * @param int end End index of an array 12 | * 13 | * @return int Partitioning pivot 14 | */ 15 | int partition(int *input, int start, int end) 16 | { 17 | int pivot = start; 18 | 19 | for (int i = start; i < end; i++) { 20 | if (input[i] < input[end]) { 21 | swap(input + i, input + pivot); 22 | pivot++; 23 | } 24 | } 25 | 26 | swap(input + pivot, input + end); 27 | 28 | return pivot; 29 | } 30 | 31 | /** 32 | * Randomized partitioning logic. 33 | * 34 | * @param integer input Input array 35 | * @param int start Start index of an array 36 | * @param int end End index of an array 37 | * 38 | * @return int Partitioning pivot 39 | */ 40 | int randomized_partition(int *input, int start, int end) 41 | { 42 | int pivot_element_index = rand() % (end + 1 - start) + start; 43 | 44 | swap(input + pivot_element_index, input + end); 45 | 46 | return partition(input, start, end); 47 | } 48 | 49 | /** 50 | * Quick sort algorithm. 51 | * 52 | * @param int input Array to sort 53 | * @param int start Start index of an array 54 | * @param int end End index of an array 55 | * 56 | * @return void 57 | */ 58 | void quick_sort(int *input, int start, int end) 59 | { 60 | if (start >= end) { 61 | return; 62 | } 63 | 64 | int pivot = randomized_partition(input, start, end); 65 | 66 | quick_sort(input, start, pivot - 1); 67 | quick_sort(input, pivot + 1, end); 68 | } 69 | 70 | /** 71 | * Swap two integers. 72 | * 73 | * @param int a 74 | * @param int b 75 | * 76 | * @return void 77 | */ 78 | void swap(int *a, int *b) 79 | { 80 | int temp = *b; 81 | 82 | *b = *a; 83 | *a = temp; 84 | } 85 | 86 | int main() 87 | { 88 | int n; 89 | 90 | printf("How many numbers? "); 91 | scanf("%d", &n); 92 | 93 | int *input = (int *) malloc(n * sizeof(int)); 94 | 95 | printf("Enter %d numbers: ", n); 96 | for (int i = 0; i < n; i++) { 97 | scanf("%d", input + i); 98 | } 99 | 100 | quick_sort(input, 0, n - 1); 101 | 102 | for (int i = 0; i < n; i++) { 103 | printf("%d\t", *(input + i)); 104 | } 105 | 106 | free(input); 107 | } 108 | -------------------------------------------------------------------------------- /Eular/maximum_path_sum_1.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Maximum Path Sum I 3 | * https://projecteuler.net/problem=18 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #define MAX_LENGTH 100 10 | 11 | int sum_brute_force(int triangle[MAX_LENGTH][MAX_LENGTH], int n) 12 | { 13 | int possible_routes = (int) pow(2, n - 1); 14 | 15 | int largest = 0, sum, index; 16 | 17 | for (int i = 0; i < possible_routes; i++) { 18 | sum = triangle[0][0]; 19 | 20 | index = 0; 21 | for (int j = 0; j < n - 1; j++) { 22 | /** 23 | * Decide whether to stay at same level or go right. 24 | * 25 | * We will check if jth bit is set on index i by right shiftting i jth times 26 | * and check if first bit for the number is set or not. if we encounter 0 (odd) 27 | * we stay at same level, if we encounter 1 (even) we go right by 1. 28 | */ 29 | index += (i >> j & 1); 30 | 31 | /** 32 | * Right shift expression can be written as i >> j => i / (int) pow(2, j) and 33 | * Bitwise & can be written as i & j => i % pow(2, j) in mathematical notation. 34 | * 35 | * So the above expression is equivalent to 36 | * index += (i / (int) pow(2, j)) % 2; 37 | */ 38 | 39 | sum += triangle[j + 1][index]; 40 | } 41 | 42 | if (sum > largest) { 43 | largest = sum; 44 | } 45 | } 46 | 47 | return largest; 48 | } 49 | 50 | int main() 51 | { 52 | int test_data_1[MAX_LENGTH][MAX_LENGTH] = { 53 | {3}, 54 | {7, 4}, 55 | {2, 4, 6}, 56 | {8, 5, 9, 3} 57 | }; 58 | 59 | int test_data_2[MAX_LENGTH][MAX_LENGTH] = { 60 | {75}, 61 | {95, 64}, 62 | {17, 47, 82}, 63 | {18, 35, 87, 10}, 64 | {20, 4, 82, 47, 65}, 65 | {19, 1, 23, 75, 3, 34}, 66 | {88, 2, 77, 73, 7, 63, 67}, 67 | {99, 65, 4, 28, 6, 16, 70, 92}, 68 | {41, 41, 26, 56, 83, 40, 80, 70, 33}, 69 | {41, 48, 72, 33, 47, 32, 37, 16, 94, 29}, 70 | {53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14}, 71 | {70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57}, 72 | {91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48}, 73 | {63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31}, 74 | {4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23}, 75 | }; 76 | 77 | assert(23 == sum_brute_force(test_data_1, 4)); 78 | assert(1074 == sum_brute_force(test_data_2, 15)); 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Recursion/str_reverse.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | char *substr(char *, size_t); 7 | 8 | /** 9 | * Solution 1: By swapping elements. 10 | * Will override given string. 11 | * 12 | * @param char* str 13 | * @param int index 14 | * @param int size 15 | * 16 | * @return void 17 | */ 18 | void str_reverse_1(char *str, int index, int size) 19 | { 20 | if (index == size / 2) { 21 | return; 22 | } 23 | 24 | char temp = str[index]; 25 | str[index] = str[size - index]; 26 | str[size - index] = temp; 27 | 28 | str_reverse_1(str, index + 1, size); 29 | } 30 | 31 | /** 32 | * Solution 2: By using temporary var. 33 | * 34 | * @param char* str 35 | * 36 | * @return char* reversed string 37 | */ 38 | char *str_reverse(char *str) 39 | { 40 | size_t len = strlen(str); 41 | 42 | static char *reverse = ""; 43 | static int i = 0; 44 | 45 | if (i == 0) { 46 | reverse = (char *) malloc(len * sizeof(char)); 47 | } 48 | 49 | if (len < 1) { 50 | reverse[i] = '\0'; 51 | i = 0; 52 | 53 | return reverse; 54 | } 55 | 56 | reverse[i++] = str[len - 1]; 57 | 58 | return str_reverse(substr(str, len)); 59 | } 60 | 61 | /** 62 | * Get substring of given length. 63 | * 64 | * @param char* str 65 | * @param size_t len 66 | * 67 | * @return char* 68 | */ 69 | char *substr(char *str, size_t len) 70 | { 71 | char *temp = (char *) malloc(len * sizeof(char)); 72 | 73 | strncpy(temp, str, len - 1); 74 | temp[len - 1] = '\0'; 75 | 76 | return temp; 77 | } 78 | 79 | int main() 80 | { 81 | assert(strcmp("a", str_reverse("a")) == 0); 82 | assert(strcmp("tikna", str_reverse("ankit")) == 0); 83 | assert(strcmp("lerhkop tikna", str_reverse("ankit pokhrel")) == 0); 84 | assert(strcmp(".egaugnaL gnimmargorP C", str_reverse("C Programming Language.")) == 0); 85 | assert(strcmp("!dlrow yzarc a si sihT", str_reverse("This is a crazy world!")) == 0); 86 | assert(strcmp( 87 | ".tile gnicsipida rutetcesnoc ,tema tis rolod muspi meroL", 88 | str_reverse("Lorem ipsum dolor sit amet, consectetur adipiscing elit.") 89 | ) == 0); 90 | 91 | char s[20] = "ankit"; 92 | str_reverse_1(s, 0, (int) strlen(s) - 1); 93 | assert(strcmp("tikna", s) == 0); 94 | 95 | strcpy(s, "ankit pokhrel"); 96 | str_reverse_1(s, 0, (int) strlen(s) - 1); 97 | assert(strcmp("lerhkop tikna", s) == 0); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C Code Katas 2 | _Collection of short programs, data structures, algorithms and competitive programs implemented in C programming language._ 3 | 4 | Data Structure and Algorithms 5 | ----------------------------- 6 | 7 | - **Search** 8 | 1. [Linear Search](DSA/Search/linear_search.c) 9 | 2. [Binary Search](DSA/Search/binary_search.c) 10 | 11 | - **Sorting** 12 | 1. [Bubble Sort](DSA/Sorting/bubble_sort.c) 13 | 2. [Insertion Sort](DSA/Sorting/insertion_sort.c) 14 | 3. [Merge Sort](DSA/Sorting/merge_sort.c) 15 | 4. [Quick Sort](DSA/Sorting/quick_sort.c) 16 | 5. [Randomized Quick Sort](DSA/Sorting/randomized_quick_sort.c) 17 | 6. [Selection Sort](DSA/Sorting/selection_sort.c) 18 | 7. [Shell Sort](DSA/Sorting/shell_sort.c) 19 | 20 | - **Linked List** 21 | 1. [Singly Linked List](DSA/LinkedList/singly_linked_list.c) 22 | 2. [Doubly Linked List](DSA/LinkedList/doubly_linked_list.c) 23 | 24 | - **Tree** 25 | 1. [Binary Search Tree](DSA/Tree/binary_search_tree.c) 26 | 27 | - **Misc** 28 | 1. [Luhn Algorithm](DSA/Misc/luhn.c) 29 | 2. [Reservoir Sample](DSA/Misc/reservoir_sample.c) 30 | 31 | 32 | Recursion 33 | --------- 34 | 1. [Tower of Hanoi](Recursion/tower_of_hanoi.c) 35 | 2. [Nth Fibonacci Number](Recursion/nth_fibonacci_number.c) 36 | 3. [Factorial](Recursion/factorial.c) 37 | 4. [Sum of Digits](Recursion/sum_of_digits.c) 38 | 5. [Palindrome](Recursion/palindrome.c) 39 | 6. [String Reverse](Recursion/str_reverse.c) 40 | 7. [Character Replace](Recursion/char_replace.c) 41 | 8. [Linear Search](Recursion/linear_search.c) 42 | 9. [Binary Search](Recursion/binary_search.c) 43 | 10. [Ackermann Function](Recursion/ackermann.c) 44 | 45 | Math 46 | ---- 47 | 1. [Factors](Math/factors.c) 48 | 2. [Common Factors](Math/common_factors.c) 49 | 3. [Greatest Common Divisor](Math/gcd.c) 50 | 4. [Euclid GCD](Math/euclid_gcd.c) 51 | 5. [Prime](Math/is_prime.c) 52 | 6. [Prime Factors](Math/prime_factors.c) 53 | 54 | Project Eular 55 | ---------------------- 56 | 1. [Multiples of 3 and 5](Eular/sum_of_multiples_of_3_5.c) 57 | 2. [Even Fibonacci Numbers](Eular/fibonacci_series.c) 58 | 3. [Largest Prime Factor](Math/prime_factors.c) 59 | 4. [Largest Palindrome Product](Eular/palindrome_of_numbers.c) 60 | 5. [Smallest Multiple](Eular/smallest_multiple.c) 61 | 6. [Sum Square Difference](Eular/sum_square_difference.c) 62 | 7. [10001st Prime](Eular/sieve_of_eratosthenes.c) 63 | 8. [Largest Product in a Series](Eular/largest_product_in_series.c) 64 | 9. [Special Pythagorean Triplet](Eular/special_pythagorean_triplet.c) 65 | 10. [Summation of Primes](Eular/sieve_of_eratosthenes.c) 66 | 11. [Largest Product in a Grid](Eular/largest_product_in_grid.c) 67 | 12. [Highly Divisible Triangular Number](Eular/highly_divisible_triangular_number.c) 68 | 13. [Large Sum](Eular/large_sum.c) 69 | 14. [Longest Collatz Sequence](Eular/longest_collatz_sequence.c) 70 | 15. [Lattice Paths](Eular/lattice_paths.c) 71 | 16. [Power Digit Sum](Eular/power_digit_sum.c) 72 | 17. [Number Letter Counts](Eular/number_to_words_and_letters_count.c) 73 | 18. [Maximum Path Sum I](Eular/maximum_path_sum_1.c) 74 | 75 | -------------------------------------------------------------------------------- /Eular/largest_product_in_series.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Largest product in a series. 3 | * https://projecteuler.net/problem=8 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define NUMBER_LENGTH 1000 12 | 13 | /** 14 | * Get product of digits of numeric string. 15 | * 16 | * @param char num 17 | * 18 | * @return unsigned long long 19 | */ 20 | unsigned long long get_product(char num[]) 21 | { 22 | unsigned long long product = 1; 23 | size_t length = strlen(num); 24 | 25 | for (int i = 0; i < length; i++) { 26 | product *= (num[i] - '0'); 27 | } 28 | 29 | return product; 30 | } 31 | 32 | /** 33 | * Get substring from a given string. 34 | * 35 | * @param char[] string 36 | * @param int start 37 | * @param int end 38 | * 39 | * @return char * Substring 40 | */ 41 | char *substr(char str[], int start, int end) 42 | { 43 | char *buffer = (char *) malloc((end - start) + 1 * sizeof(char)); 44 | 45 | int k = 0; 46 | for (int j = start; j < end; j++) { 47 | buffer[k++] = str[j]; 48 | } 49 | buffer[k] = '\0'; 50 | 51 | return buffer; 52 | } 53 | 54 | /** 55 | * Calculate largest product in a series. 56 | * 57 | * @param char number 58 | * @param int product_length 59 | * 60 | * @return unsigned long long Largest product 61 | */ 62 | unsigned long long largest_product_in_series(char number[], int product_length) 63 | { 64 | unsigned long long largest = 0; 65 | for (int i = 0; i < NUMBER_LENGTH; i += 1) { 66 | char *buffer = substr(number, i, i + product_length); 67 | 68 | unsigned long long product = get_product(buffer); 69 | 70 | if (product > largest) { 71 | largest = product; 72 | } 73 | 74 | free(buffer); 75 | } 76 | 77 | return largest; 78 | } 79 | 80 | int main() 81 | { 82 | char number[] = "73167176531330624919225119674426574742355349194934" 83 | "96983520312774506326239578318016984801869478851843" 84 | "85861560789112949495459501737958331952853208805511" 85 | "12540698747158523863050715693290963295227443043557" 86 | "66896648950445244523161731856403098711121722383113" 87 | "62229893423380308135336276614282806444486645238749" 88 | "30358907296290491560440772390713810515859307960866" 89 | "70172427121883998797908792274921901699720888093776" 90 | "65727333001053367881220235421809751254540594752243" 91 | "52584907711670556013604839586446706324415722155397" 92 | "53697817977846174064955149290862569321978468622482" 93 | "83972241375657056057490261407972968652414535100474" 94 | "82166370484403199890008895243450658541227588666881" 95 | "16427171479924442928230863465674813919123162824586" 96 | "17866458359124566529476545682848912883142607690042" 97 | "24219022671055626321111109370544217506941658960408" 98 | "07198403850962455444362981230987879927244284909188" 99 | "84580156166097919133875499200524063689912560717606" 100 | "05886116467109405077541002256983155200055935729725" 101 | "71636269561882670428252483600823257530420752963450"; 102 | 103 | assert(5832 == largest_product_in_series(number, 4)); 104 | assert(2571912 == largest_product_in_series(number, 7)); 105 | assert(23514624000 == largest_product_in_series(number, 13)); 106 | assert(282293061120 == largest_product_in_series(number, 15)); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /Eular/smallest_multiple.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Smallest multiple. 3 | * https://projecteuler.net/problem=5 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define MAX_FACTORS 25 13 | 14 | typedef struct PRIME_FACTORS 15 | { 16 | int *factors; 17 | int count; 18 | } Prime_Factor; 19 | 20 | /** 21 | * Find prime factors of a given number. 22 | * 23 | * @param int n 24 | * 25 | * @return struct PRIME_FACTORS 26 | */ 27 | Prime_Factor prime_factors(int n) 28 | { 29 | int root = (int) sqrt(n); 30 | int *factors = (int *) malloc(MAX_FACTORS * sizeof(int)); 31 | 32 | int j = 0; 33 | for (int i = 2; i <= root; i++) { 34 | if (n % i == 0) { 35 | while (n % i == 0) { 36 | n = n / i; 37 | factors[j++] = i; 38 | } 39 | } 40 | } 41 | 42 | if (n != 1) { 43 | factors[j++] = n; 44 | } 45 | 46 | Prime_Factor factor = { 47 | .factors = factors, 48 | .count = j 49 | }; 50 | 51 | return factor; 52 | } 53 | 54 | /** 55 | * Find if a value is in array. 56 | * 57 | * @param int needle 58 | * @param int[] haystack 59 | * @param int length 60 | * @return int Index if found else -1 61 | */ 62 | int in_array(int needle, int *haystack, int length) 63 | { 64 | for (int i = 0; i < length; i++) { 65 | if (needle == haystack[i]) { 66 | return i; 67 | } 68 | } 69 | 70 | return -1; 71 | } 72 | 73 | /** 74 | * Count number of occurrence given number 75 | * in an array. 76 | * 77 | * @param int needle 78 | * @param int[] haystack 79 | * @param int length 80 | * 81 | * @return int 82 | */ 83 | int count_in_array(int needle, int *haystack, int length) 84 | { 85 | int count = 0; 86 | 87 | for (int i = 0; i < length; i++) { 88 | if (needle == haystack[i]) { 89 | ++count; 90 | } 91 | } 92 | 93 | return count; 94 | } 95 | 96 | /** 97 | * Calculate smallest multiple evenly divisible 98 | * up to given number. 99 | * 100 | * @param num 101 | * 102 | * @return unsigned long long 103 | */ 104 | unsigned long long smallest_multiple(int num) 105 | { 106 | Prime_Factor factor; 107 | 108 | int k = 0, l; 109 | int pf[MAX_FACTORS]; 110 | int count[MAX_FACTORS]; 111 | int *processed; 112 | 113 | for (int i = num; i > 1; i--) { 114 | factor = prime_factors(i); 115 | 116 | l = 0; 117 | processed = (int *) calloc((size_t) factor.count, sizeof(int)); 118 | for (int j = 0; j < factor.count; j++) { 119 | if (in_array(factor.factors[j], processed, l) != -1) { 120 | break; 121 | } 122 | 123 | processed[l++] = factor.factors[j]; 124 | 125 | int factor_index = in_array(factor.factors[j], pf, k); 126 | int factor_count = count_in_array(factor.factors[j], factor.factors, factor.count); 127 | 128 | if (factor_index == -1) { 129 | pf[k] = factor.factors[j]; 130 | count[k++] = factor_count; 131 | } else if (count[factor_index] < factor_count) { 132 | count[factor_index] += (factor_count - count[factor_index]); 133 | } 134 | } 135 | 136 | free(processed); 137 | } 138 | 139 | unsigned long long multiple = 1; 140 | for (int m = 0; m < k; m++) { 141 | multiple *= pow(pf[m], count[m]); 142 | } 143 | 144 | return multiple; 145 | } 146 | 147 | /** 148 | * Efficient way to calculate smallest multiple 149 | * evenly divisible up to given number. 150 | * 151 | * @param num 152 | * 153 | * @return unsigned long long 154 | */ 155 | unsigned long long smallest_multiple_efficient(int num) 156 | { 157 | unsigned long long multiple = 1; 158 | 159 | int limit = (int) sqrt(num); 160 | bool check = true; 161 | 162 | int primes[MAX_FACTORS] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}; 163 | int count[MAX_FACTORS]; 164 | 165 | int i = 0; 166 | while (primes[i] <= num) { 167 | count[i] = 1; 168 | if (check) { 169 | if (primes[i] <= limit) { 170 | count[i] = (int) floor(log(num) / log(primes[i])); 171 | } else { 172 | check = false; 173 | } 174 | } 175 | 176 | multiple *= pow(primes[i], count[i]); 177 | 178 | i++; 179 | } 180 | 181 | return multiple; 182 | } 183 | 184 | int main() 185 | { 186 | assert(60 == smallest_multiple(5)); 187 | assert(2520 == smallest_multiple(10)); 188 | assert(232792560 == smallest_multiple(20)); 189 | assert(2329089562800 == smallest_multiple(30)); 190 | 191 | assert(60 == smallest_multiple_efficient(5)); 192 | assert(2520 == smallest_multiple_efficient(10)); 193 | assert(232792560 == smallest_multiple_efficient(20)); 194 | assert(2329089562800 == smallest_multiple_efficient(30)); 195 | 196 | return 0; 197 | } 198 | -------------------------------------------------------------------------------- /Eular/largest_product_in_grid.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Largest product in a grid 3 | * https://projecteuler.net/problem=11 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #define WIDTH 20 10 | #define HEIGHT 20 11 | #define ADJACENT 4 12 | 13 | #define MAX(a, b) (a > b ? a : b) 14 | 15 | unsigned long long largestProductHorizontallyAndVertically(int grid[WIDTH][HEIGHT]) 16 | { 17 | unsigned long long productHorizontal; 18 | unsigned long long productVertical; 19 | unsigned long long largest = 1; 20 | 21 | for (int i = 0; i < WIDTH - ADJACENT; i++) { 22 | for (int j = 0; j < HEIGHT - ADJACENT; j++) { 23 | productHorizontal = productVertical = 1; 24 | for (int k = j; k < j + ADJACENT; k++) { 25 | if (k < 0 || k >= 20) continue; 26 | productHorizontal *= grid[i][k]; 27 | productVertical *= grid[k][i]; 28 | } 29 | 30 | largest = MAX(MAX(productHorizontal, largest), productVertical); 31 | } 32 | } 33 | 34 | return largest; 35 | } 36 | 37 | unsigned long long largestProductDiagonallyUpDown(int grid[WIDTH][HEIGHT]) 38 | { 39 | unsigned long long product; 40 | unsigned long long largest = 1; 41 | 42 | int x, l; 43 | 44 | for (int z = 0; z < WIDTH + HEIGHT - ADJACENT; z++) { 45 | for (int y = 0; y < HEIGHT - ADJACENT; y++) { 46 | x = WIDTH - z + y; 47 | 48 | if (x < 0 || x >= WIDTH) continue; 49 | 50 | product = 1; 51 | for (int k = y; k < (y + ADJACENT); k++) { 52 | l = WIDTH - z + k; 53 | 54 | if (l < 0 || l >= WIDTH) continue; 55 | if (k < 0 || k >= HEIGHT) continue; 56 | 57 | product *= grid[l][k]; 58 | } 59 | 60 | largest = MAX(product, largest); 61 | } 62 | } 63 | 64 | return largest; 65 | } 66 | 67 | unsigned long long largestProductDiagonallyDownUp(int grid[WIDTH][HEIGHT]) 68 | { 69 | unsigned long long product; 70 | unsigned long long largest = 1; 71 | 72 | int x, l; 73 | 74 | for (int z = -(WIDTH - 1); z < WIDTH + HEIGHT - ADJACENT; z++) { 75 | for (int y = 0; y < HEIGHT - ADJACENT; y++) { 76 | x = WIDTH - z - y; 77 | 78 | if (x < 0 || x >= WIDTH) continue; 79 | 80 | product = 1; 81 | for (int k = y; k < (y + ADJACENT); k++) { 82 | l = WIDTH - z - k; 83 | 84 | if (l < 0 || l >= WIDTH) continue; 85 | if (k < 0 || k >= HEIGHT) continue; 86 | 87 | product *= grid[l][k]; 88 | } 89 | 90 | largest = MAX(product, largest); 91 | } 92 | } 93 | 94 | return largest; 95 | } 96 | 97 | int main() 98 | { 99 | int grid[WIDTH][HEIGHT] = { 100 | {8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8}, 101 | {49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 0}, 102 | {81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65}, 103 | {52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91}, 104 | {22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80}, 105 | {24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50}, 106 | {32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70}, 107 | {67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21}, 108 | {24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72}, 109 | {21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95}, 110 | {78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92}, 111 | {16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57}, 112 | {86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58}, 113 | {19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40}, 114 | {4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66}, 115 | {88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69}, 116 | {4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36}, 117 | {20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16}, 118 | {20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54}, 119 | {1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48} 120 | }; 121 | 122 | unsigned long long largestProductHorizontalAndVertical = largestProductHorizontallyAndVertically(grid); 123 | unsigned long long largestProductDiagonalClockwise = largestProductDiagonallyUpDown(grid); 124 | unsigned long long largestProductDiagonalAntiClockwise = largestProductDiagonallyDownUp(grid); 125 | 126 | unsigned long long largest = MAX( 127 | MAX(largestProductHorizontalAndVertical, largestProductDiagonalClockwise), 128 | largestProductDiagonalAntiClockwise 129 | ); 130 | 131 | printf("Largest Product: %llu", largest); 132 | 133 | assert(70600674 == largest); 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /DSA/Tree/binary_search_tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct BINARY_SEARCH_TREE 7 | { 8 | int data; 9 | struct BINARY_SEARCH_TREE *left; 10 | struct BINARY_SEARCH_TREE *right; 11 | } Node; 12 | 13 | /** 14 | * Creates a new node. 15 | * 16 | * @internal 17 | * 18 | * @param int data Data for node 19 | * 20 | * @return Node 21 | */ 22 | Node *get_Node(int data) 23 | { 24 | Node *temp = (Node *) malloc(sizeof(Node)); 25 | 26 | temp->data = data; 27 | temp->left = NULL; 28 | temp->right = NULL; 29 | 30 | return temp; 31 | } 32 | 33 | /** 34 | * Insert new node to a tree. 35 | * 36 | * @param Node tree Search tree 37 | * @param int data Data to insert 38 | * 39 | * @return void 40 | */ 41 | void insert(Node **tree, int data) 42 | { 43 | if (!*tree) { 44 | *tree = get_Node(data); 45 | 46 | return; 47 | } 48 | 49 | if (data < (*tree)->data) { 50 | //left subtree 51 | insert(&(*tree)->left, data); 52 | } else { 53 | //right subtree 54 | insert(&(*tree)->right, data); 55 | } 56 | } 57 | 58 | /** 59 | * Prints data using inorder traversal of a tree. 60 | * 61 | * @param Node tree Search tree 62 | * 63 | * @return void 64 | */ 65 | void inorder(Node **tree) 66 | { 67 | if (!*tree) { 68 | return; 69 | } 70 | 71 | inorder(&(*tree)->left); 72 | printf("%d ", (*tree)->data); 73 | inorder(&(*tree)->right); 74 | } 75 | 76 | /** 77 | * Prints data using preorder traversal of a tree. 78 | * 79 | * @param Node tree Search tree 80 | * 81 | * @return void 82 | */ 83 | void preorder(Node **n) 84 | { 85 | if (!*n) { 86 | return; 87 | } 88 | 89 | printf("%d ", (*n)->data); 90 | preorder(&(*n)->left); 91 | preorder(&(*n)->right); 92 | } 93 | 94 | /** 95 | * Prints data using postorder traversal of a tree. 96 | * 97 | * @param Node tree Search tree 98 | * 99 | * @return void 100 | */ 101 | void postorder(Node **n) 102 | { 103 | if (!*n) { 104 | return; 105 | } 106 | 107 | postorder(&(*n)->left); 108 | postorder(&(*n)->right); 109 | printf("%d ", (*n)->data); 110 | } 111 | 112 | /** 113 | * Finds a node with given data from tree. 114 | * 115 | * @param Node tree Search tree 116 | * @param int data Data to search 117 | * 118 | * @return Node|Null 119 | */ 120 | Node *find(Node **tree, int data) 121 | { 122 | static Node *item = NULL; 123 | 124 | if (!*tree) { 125 | return NULL; 126 | } 127 | 128 | if (!item) { 129 | item = (Node *) malloc(sizeof(Node)); 130 | } 131 | 132 | if (data == (*tree)->data) { 133 | item = *tree; 134 | } else if (data < (*tree)->data) { 135 | find(&((*tree)->left), data); 136 | } else { 137 | find(&((*tree)->right), data); 138 | } 139 | 140 | return item; 141 | } 142 | 143 | /** 144 | * Find node with minimum data from given tree. 145 | * 146 | * @param Node root Root of a tree 147 | * 148 | * @return Node 149 | */ 150 | Node *find_minimum(Node *root) 151 | { 152 | Node *subtree = root; 153 | 154 | while (subtree->left) { 155 | subtree = subtree->left; 156 | } 157 | 158 | return subtree; 159 | } 160 | 161 | /** 162 | * Find node with maximum data from given tree. 163 | * 164 | * @param Node root Root of a tree 165 | * 166 | * @return Node 167 | */ 168 | Node *find_maximum(Node *root) 169 | { 170 | Node *subtree = root; 171 | 172 | while (subtree->right) { 173 | subtree = subtree->right; 174 | } 175 | 176 | return subtree; 177 | } 178 | 179 | /** 180 | * Checks if a node is a leaf node. 181 | * 182 | * @param Node n Node to check 183 | * 184 | * @return bool 185 | */ 186 | bool is_leaf_node(Node *n) 187 | { 188 | return n->left == NULL && n->right == NULL; 189 | } 190 | 191 | /** 192 | * Checks if a node is root node of a given tree. 193 | * 194 | * @param Node tree Search tree 195 | * @param Node n Node to check against root node 196 | * 197 | * @return bool 198 | */ 199 | bool is_root_node(Node **tree, Node *n) 200 | { 201 | return (*tree) == n; 202 | } 203 | 204 | /** 205 | * Deletes a node with given data from tree 206 | * and returns a new root. 207 | * 208 | * @param Node root Root of a tree 209 | * @param int data Data to be deleted 210 | * 211 | * @return Node New node of a tree 212 | */ 213 | Node *delete(Node *root, int data) 214 | { 215 | if (!root) { 216 | return root; 217 | } 218 | 219 | if (data < root->data) { 220 | //left 221 | root->left = delete(root->left, data); 222 | } else if (data > root->data) { 223 | //right 224 | root->right = delete(root->right, data); 225 | } else { 226 | //equal 227 | if (is_leaf_node(root)) { 228 | free(root); 229 | root = NULL; 230 | 231 | return NULL; 232 | } 233 | 234 | if (root->left && root->right) { 235 | //has both child 236 | Node *min = find_minimum(root->right); 237 | 238 | root->data = min->data; 239 | 240 | root->right = delete(root->right, min->data); 241 | } else if (root->left) { 242 | //left child 243 | Node *temp = root->left; 244 | 245 | free(root->left); 246 | root->left = NULL; 247 | 248 | return temp; 249 | } else if (root->right) { 250 | //right child 251 | Node *temp = root->right; 252 | 253 | free(root->right); 254 | root->right = NULL; 255 | 256 | return temp; 257 | } 258 | } 259 | 260 | return root; 261 | } 262 | 263 | int main() 264 | { 265 | Node *n = NULL; 266 | 267 | int total, input, del; 268 | 269 | printf("%s", "How many data? "); 270 | scanf("%d", &total); 271 | 272 | printf("Enter %d numbers\n", total); 273 | for (int i = 0; i < total; i++) { 274 | scanf("%d", &input); 275 | insert(&n, input); 276 | } 277 | 278 | printf("%s", "Inorder: "); 279 | inorder(&n); 280 | 281 | printf("%s", "\nPreorder: "); 282 | preorder(&n); 283 | 284 | printf("%s", "\nPostorder: "); 285 | postorder(&n); 286 | 287 | printf("%s", "\n\nDelete? "); 288 | scanf("%d", &del); 289 | 290 | Node *found = find(&n, del); 291 | assert(del == found->data); 292 | 293 | Node *new_root = delete(n, del); 294 | assert(new_root->data == n->data); 295 | 296 | printf("\n%s", "After Deletion: "); 297 | preorder(&n); 298 | 299 | free(n); 300 | 301 | return 0; 302 | } 303 | -------------------------------------------------------------------------------- /Eular/number_to_words_and_letters_count.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Program to convert number to words and Number letters count. 3 | * https://projecteuler.net/problem=17 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX_LETTERS_LENGTH 100 14 | 15 | const char LETTERS[20][10] = { 16 | "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", 17 | "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", 18 | "Eighteen", "Nineteen", "Twenty" 19 | }; 20 | 21 | /** 22 | * Maps number to respective text. 23 | * 24 | * @param int num 25 | * 26 | * @return string 27 | */ 28 | char *mapper(int num) 29 | { 30 | if (num == 0) { 31 | return "Zero"; 32 | } 33 | 34 | if (num <= 20) { 35 | return (char *) LETTERS[num - 1]; 36 | } 37 | 38 | switch (num) { 39 | case 30: 40 | return "Thirty"; 41 | 42 | case 40: 43 | return "Forty"; 44 | 45 | case 50: 46 | return "Fifty"; 47 | 48 | case 60: 49 | return "Sixty"; 50 | 51 | case 70: 52 | return "Seventy"; 53 | 54 | case 80: 55 | return "Eighty"; 56 | 57 | case 90: 58 | return "Ninety"; 59 | 60 | case 100: 61 | return "Hundred"; 62 | 63 | case 1000: 64 | return "Thousand"; 65 | 66 | default: 67 | return ""; 68 | } 69 | } 70 | 71 | /** 72 | * Determines if we should add 'and'. 73 | * 74 | * @param int* arr 75 | * @param int j 76 | * 77 | * @return bool 78 | */ 79 | bool should_add_conjunction(int *arr, int j) 80 | { 81 | bool flag = false; 82 | 83 | for (int x = j - 1; x >= 0; x--) { 84 | if (arr[x] != 0) { 85 | flag = true; 86 | break; 87 | } 88 | } 89 | 90 | return flag; 91 | } 92 | 93 | /** 94 | * Reduce number to array. 95 | * 96 | * @param int* arr 97 | * @param int num 98 | * 99 | * @return int 100 | */ 101 | int num_to_array(int *arr, int num) 102 | { 103 | int digit, i = 0; 104 | 105 | while (num > 0) { 106 | digit = num % 10; 107 | 108 | arr[i++] = digit; 109 | 110 | num /= 10; 111 | } 112 | 113 | return i; 114 | } 115 | 116 | /** 117 | * Convert number to words. 118 | * 119 | * @param int num 120 | * @param string separator 121 | * 122 | * @return string 123 | */ 124 | char *number_to_words(int num, char *separator) 125 | { 126 | if (num < 0 || num > 9999) { 127 | return "Number out of range"; 128 | } 129 | 130 | if (num <= 20) { 131 | return mapper(num); 132 | } 133 | 134 | char *word = (char *) malloc(MAX_LETTERS_LENGTH * sizeof(char)); 135 | int place, arr[5], i = num_to_array(arr, num); 136 | 137 | for (int j = i - 1; j >= 0; j--) { 138 | if (arr[j] == 0) { 139 | continue; 140 | } 141 | 142 | place = (int) pow(10, j); 143 | 144 | if (place <= 10) { 145 | if (j == 0) { 146 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s", word, mapper(arr[j])); 147 | break; 148 | } 149 | 150 | int tens = arr[j] * place; 151 | int ones = arr[j - 1]; 152 | 153 | if ((tens + ones) <= 20) { 154 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s", word, mapper(tens + ones)); 155 | } else if (ones != 0) { 156 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s%s%s", word, mapper(tens), separator, mapper(ones)); 157 | } else { 158 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s", word, mapper(tens)); 159 | } 160 | 161 | --j; 162 | } else { 163 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s%s%s", word, mapper(arr[j]), separator, mapper(place)); 164 | 165 | if (num == arr[j] * place) { 166 | return word; 167 | } 168 | 169 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s", word, separator); 170 | 171 | if (place == 100 && should_add_conjunction(arr, j)) { 172 | snprintf(word, MAX_LETTERS_LENGTH, "%s%s%s", word, "and", separator); 173 | } 174 | } 175 | } 176 | 177 | return word; 178 | } 179 | 180 | /** 181 | * Count number of letters in given range. 182 | * 183 | * @param int start 184 | * @param int end 185 | * @param string separator 186 | * 187 | * @return int 188 | */ 189 | int range_sum(int start, int end, char *separator) 190 | { 191 | int sum = 0; 192 | char *word; 193 | 194 | for (int i = start; i <= end; i++) { 195 | word = number_to_words(i, separator); 196 | sum += strlen(word); 197 | } 198 | 199 | return sum; 200 | } 201 | 202 | int main() 203 | { 204 | int test_data[20] = { 205 | 1, 10, 15, 35, 83, 100, 110, 117, 155, 223, 577, 999, 206 | 1000, 1100, 1222, 5000, 5555, 7654, 70004, 9999 207 | }; 208 | 209 | char *test_string[20] = { 210 | "One", "Ten", "Fifteen", "Thirty Five", "Eighty Three", "One Hundred", "One Hundred and Ten", 211 | "One Hundred and Seventeen", "One Hundred and Fifty Five", "Two Hundred and Twenty Three", 212 | "Five Hundred and Seventy Seven", "Nine Hundred and Ninety Nine", "One Thousand", "One Thousand One Hundred", 213 | "One Thousand Two Hundred and Twenty Two", "Five Thousand", "Five Thousand Five Hundred and Fifty Five", 214 | "Seven Thousand Six Hundred and Fifty Four", "Seven Thousand and Four", 215 | "Nine Thousand Nine Hundred and Ninety Nine" 216 | }; 217 | 218 | char *test_string_2[20] = { 219 | "One", "Ten", "Fifteen", "Thirty-Five", "Eighty-Three", "One-Hundred", "One-Hundred-and-Ten", 220 | "One-Hundred-and-Seventeen", "One-Hundred-and-Fifty-Five", "Two-Hundred-and-Twenty-Three", 221 | "Five-Hundred-and-Seventy-Seven", "Nine-Hundred-and-Ninety-Nine", "One-Thousand", "One-Thousand-One-Hundred", 222 | "One-Thousand-Two-Hundred-and-Twenty-Two", "Five-Thousand", "Five-Thousand-Five-Hundred-and-Fifty-Five", 223 | "Seven-Thousand-Six-Hundred-and-Fifty-Four", "Seven-Thousand-and-Four", 224 | "Nine-Thousand-Nine-Hundred-and-Ninety-Nine" 225 | }; 226 | 227 | for (int i = 0; i < 13; i++) { 228 | assert(strcmp(test_string[i], number_to_words(test_data[i], " ")) == 0); 229 | assert(strcmp(test_string_2[i], number_to_words(test_data[i], "-")) == 0); 230 | } 231 | 232 | assert(36 == range_sum(1, 9, "")); 233 | assert(70 == range_sum(10, 19, "")); 234 | assert(748 == range_sum(20, 99, "")); 235 | assert(20259 == range_sum(100, 999, "")); 236 | assert(21124 == range_sum(1, 1000, "")); 237 | assert(152577 == range_sum(1, 5000, "")); 238 | 239 | return 0; 240 | } 241 | -------------------------------------------------------------------------------- /DSA/LinkedList/doubly_linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef struct DOUBLY_LINKED_LIST 6 | { 7 | int data; 8 | struct DOUBLY_LINKED_LIST *next; 9 | struct DOUBLY_LINKED_LIST *previous; 10 | } List; 11 | 12 | List *front = NULL; 13 | 14 | /** 15 | * Creates a new node. 16 | * 17 | * @internal 18 | * 19 | * @param int data Data for node 20 | * 21 | * @return Node 22 | */ 23 | List *get_node(int data) 24 | { 25 | List *temp = (List *) malloc(sizeof(List)); 26 | 27 | temp->data = data; 28 | temp->next = NULL; 29 | temp->previous = NULL; 30 | 31 | return temp; 32 | } 33 | 34 | /** 35 | * Insert in front of the list. 36 | * 37 | * @param List list 38 | * @param List new_node Node to insert 39 | * 40 | * @return List 41 | */ 42 | List *insert_first(List *list, List *new_node) 43 | { 44 | new_node->next = list; 45 | list->previous = new_node; 46 | 47 | front = new_node; 48 | 49 | return new_node; 50 | } 51 | 52 | /** 53 | * Insert at the end of list. 54 | * 55 | * @param List list 56 | * @param List new_node Node to insert 57 | * 58 | * @return List 59 | */ 60 | List *insert_last(List *list, List *new_node) 61 | { 62 | if (list->next) { 63 | insert_last(list->next, new_node); 64 | } else { 65 | list->next = new_node; 66 | new_node->previous = list; 67 | } 68 | 69 | return list; 70 | } 71 | 72 | /** 73 | * Insert in between 2 nodes. 74 | * 75 | * @param List list 76 | * @param List new_node Node to insert 77 | * 78 | * @return 79 | */ 80 | List *insert_between(List *list, List *new_node) 81 | { 82 | static List *parent; 83 | 84 | if (!list) { 85 | return list; 86 | } 87 | 88 | if (list->data > new_node->data) { 89 | parent->next = new_node; 90 | new_node->previous = parent; 91 | 92 | new_node->next = list; 93 | list->previous = new_node; 94 | } else { 95 | parent = list; 96 | insert_between(list->next, new_node); 97 | } 98 | 99 | return list; 100 | } 101 | 102 | /** 103 | * Find position to insert a given node. 104 | * 105 | * @param List list 106 | * @param new_node 107 | * 108 | * @return List 109 | */ 110 | List *find_insert_position(List *list, List *new_node) 111 | { 112 | static List *parent; 113 | 114 | if (NULL == parent) { 115 | parent = list; 116 | } 117 | 118 | if (new_node->data > list->data) { 119 | parent = list; 120 | 121 | if (list->next) { 122 | find_insert_position(list->next, new_node); 123 | } 124 | } 125 | 126 | return parent; 127 | } 128 | 129 | /** 130 | * Find node in a list. 131 | * 132 | * @param List list 133 | * @param Int data Data to search 134 | * 135 | * @return List 136 | */ 137 | List *find(List *list, int data) 138 | { 139 | if (!list) { 140 | return NULL; 141 | } 142 | 143 | if (data == list->data) { 144 | return list; 145 | } 146 | 147 | return find(list->next, data); 148 | } 149 | 150 | /** 151 | * Insert new node to a sorted list. 152 | * 153 | * @param List 154 | * @param int data Data to insert 155 | * 156 | * @return void 157 | */ 158 | void insert_sorted(List **list, int data) 159 | { 160 | List *new_node = get_node(data); 161 | 162 | if (!*list) { 163 | *list = new_node; 164 | 165 | front = *list; 166 | 167 | return; 168 | } 169 | 170 | List *parent = find_insert_position(*list, new_node); 171 | 172 | if (!parent->next && new_node->data < parent->data) { 173 | *list = insert_first(*list, new_node); 174 | } else if (!parent->next && new_node->data > parent->data) { 175 | insert_last(*list, new_node); 176 | } else { 177 | *list = insert_between(*list, new_node); 178 | } 179 | } 180 | 181 | /** 182 | * Insert new node to a list. 183 | * 184 | * @param List 185 | * @param int data Data to insert 186 | * @param int poistion Start, end or inbetween 187 | * 188 | * @return void 189 | */ 190 | void insert(List **list, int data, int position) 191 | { 192 | List *new_node = get_node(data); 193 | 194 | if (!*list) { 195 | *list = new_node; 196 | 197 | front = *list; 198 | 199 | return; 200 | } 201 | 202 | switch (position) { 203 | case 0: 204 | *list = insert_first(*list, new_node); 205 | break; 206 | 207 | case 1: 208 | *list = insert_between(*list, new_node); 209 | break; 210 | 211 | case 2: 212 | *list = insert_last(*list, new_node); 213 | break; 214 | } 215 | } 216 | 217 | /** 218 | * Delete given node from a list. 219 | * 220 | * @param List list 221 | * @param Int data Data to delete 222 | * 223 | * @return List|NULL 224 | */ 225 | List *delete(List **list, int data) 226 | { 227 | if (!*list) { 228 | return NULL; 229 | } 230 | 231 | if (front->data == data) { 232 | List *deleted_node = front; 233 | 234 | front = front->next; 235 | *list = front; 236 | (*list)->previous = NULL; 237 | 238 | return deleted_node; 239 | } 240 | 241 | List *node = find(*list, data); 242 | 243 | if (!node->previous) { 244 | return NULL; 245 | } 246 | 247 | List *delete_node = node; 248 | 249 | node->previous->next = delete_node->next; 250 | 251 | if (delete_node->next) { 252 | delete_node->next->previous = delete_node->previous; 253 | } 254 | 255 | return delete_node; 256 | } 257 | 258 | /** 259 | * Print a given list. 260 | * 261 | * @param List 262 | * 263 | * @return void 264 | */ 265 | void print_list(List *list) 266 | { 267 | if (!list) { 268 | return; 269 | } 270 | 271 | printf("%d -> ", list->data); 272 | print_list(list->next); 273 | } 274 | 275 | /** 276 | * Print a given list in inverted order. 277 | * 278 | * @param List 279 | * 280 | * @return void 281 | */ 282 | void print_inverted(List *list) 283 | { 284 | if (!list) { 285 | return; 286 | } 287 | 288 | print_inverted(list->next); 289 | printf("%d -> ", list->data); 290 | } 291 | 292 | int main() 293 | { 294 | int data_array[] = {3, 2, 8, 6, 4, 4, 12}; 295 | 296 | List *l1 = NULL; 297 | List *l2 = NULL; 298 | 299 | insert(&l1, 3, 0); //root node 300 | insert(&l1, 2, 0); //insert at start 301 | insert(&l1, 8, 2); //insert at end 302 | insert(&l1, 6, 1); //insert between 2 and 8 303 | 304 | assert(front == l1); 305 | 306 | print_list(l1); 307 | 308 | free(l1); 309 | for (int i = 0; i < 7; i++) { 310 | insert_sorted(&l2, data_array[i]); 311 | } 312 | 313 | assert(front == l2); 314 | 315 | printf("\n\n"); 316 | print_list(l2); 317 | printf("\n"); 318 | print_inverted(l2); 319 | 320 | List *find_node = find(l2, 8); 321 | assert(8 == find_node->data); 322 | 323 | find_node = find(l2, 99); 324 | assert(NULL == find_node); 325 | 326 | List *deleted_node = delete(&l2, 2); 327 | assert(2 == deleted_node->data); 328 | assert(front == deleted_node->next); 329 | 330 | printf("\n\n"); 331 | print_list(l2); 332 | 333 | deleted_node = delete(&l2, 4); 334 | assert(4 == deleted_node->data); 335 | 336 | printf("\n"); 337 | print_list(l2); 338 | 339 | deleted_node = delete(&l2, 12); 340 | assert(12 == deleted_node->data); 341 | 342 | free(l2); 343 | 344 | return 0; 345 | } 346 | -------------------------------------------------------------------------------- /DSA/LinkedList/singly_linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef struct SINGLY_LINKED_LIST 6 | { 7 | int data; 8 | struct SINGLY_LINKED_LIST *next; 9 | } List; 10 | 11 | List *front = NULL; 12 | 13 | /** 14 | * Creates a new node. 15 | * 16 | * @internal 17 | * 18 | * @param int data Data for node 19 | * 20 | * @return Node 21 | */ 22 | List *get_node(int data) 23 | { 24 | List *temp = (List *) malloc(sizeof(List)); 25 | 26 | temp->data = data; 27 | temp->next = NULL; 28 | 29 | return temp; 30 | } 31 | 32 | /** 33 | * Insert in front of the list. 34 | * 35 | * @param List list 36 | * @param List new_node Node to insert 37 | * 38 | * @return List 39 | */ 40 | List *insert_first(List *list, List *new_node) 41 | { 42 | new_node->next = list; 43 | 44 | front = new_node; 45 | 46 | return new_node; 47 | } 48 | 49 | /** 50 | * Insert at the end of list. 51 | * 52 | * @param List list 53 | * @param List new_node Node to insert 54 | * 55 | * @return List 56 | */ 57 | List *insert_last(List *list, List *new_node) 58 | { 59 | if (list->next) { 60 | insert_last(list->next, new_node); 61 | } else { 62 | list->next = new_node; 63 | } 64 | 65 | return list; 66 | } 67 | 68 | /** 69 | * Insert in between 2 nodes. 70 | * 71 | * @param List list 72 | * @param List new_node Node to insert 73 | * 74 | * @return 75 | */ 76 | List *insert_between(List *list, List *new_node) 77 | { 78 | static List *parent; 79 | 80 | if (!list) { 81 | return list; 82 | } 83 | 84 | if (list->data > new_node->data) { 85 | parent->next = new_node; 86 | new_node->next = list; 87 | } else { 88 | parent = list; 89 | insert_between(list->next, new_node); 90 | } 91 | 92 | return list; 93 | } 94 | 95 | /** 96 | * Find position to insert a given node. 97 | * 98 | * @param List list 99 | * @param new_node 100 | * 101 | * @return List 102 | */ 103 | List *find_insert_position(List *list, List *new_node) 104 | { 105 | static List *parent; 106 | 107 | if (NULL == parent) { 108 | parent = list; 109 | } 110 | 111 | if (new_node->data > list->data) { 112 | parent = list; 113 | 114 | if (list->next) { 115 | find_insert_position(list->next, new_node); 116 | } 117 | } 118 | 119 | return parent; 120 | } 121 | 122 | /** 123 | * Find parent of a given node. 124 | * 125 | * @param List list 126 | * @param new_node 127 | * 128 | * @return List 129 | */ 130 | List *find_parent(List *list, int data) 131 | { 132 | if (!list) { 133 | return NULL; 134 | } 135 | 136 | if (list->next && list->next->data == data) { 137 | return list; 138 | } 139 | 140 | return find_parent(list->next, data); 141 | } 142 | 143 | /** 144 | * Find node in a list. 145 | * 146 | * @param List list 147 | * @param Int data Data to search 148 | * 149 | * @return List 150 | */ 151 | List *find(List *list, int data) 152 | { 153 | if (!list) { 154 | return NULL; 155 | } 156 | 157 | if (data == list->data) { 158 | return list; 159 | } 160 | 161 | return find(list->next, data); 162 | } 163 | 164 | /** 165 | * Insert new node to a sorted list. 166 | * 167 | * @param List 168 | * @param int data Data to insert 169 | * 170 | * @return void 171 | */ 172 | void insert_sorted(List **list, int data) 173 | { 174 | List *new_node = get_node(data); 175 | 176 | if (!*list) { 177 | *list = new_node; 178 | 179 | front = *list; 180 | 181 | return; 182 | } 183 | 184 | List *parent = find_insert_position(*list, new_node); 185 | 186 | if (!parent->next && new_node->data < parent->data) { 187 | *list = insert_first(*list, new_node); 188 | } else if (!parent->next && new_node->data > parent->data) { 189 | insert_last(*list, new_node); 190 | } else { 191 | *list = insert_between(*list, new_node); 192 | } 193 | } 194 | 195 | /** 196 | * Insert new node to a list. 197 | * 198 | * @param List 199 | * @param int data Data to insert 200 | * @param int poistion Start, end or inbetween 201 | * 202 | * @return void 203 | */ 204 | void insert(List **list, int data, int position) 205 | { 206 | List *new_node = get_node(data); 207 | 208 | if (!*list) { 209 | *list = new_node; 210 | 211 | front = *list; 212 | 213 | return; 214 | } 215 | 216 | switch (position) { 217 | case 0: 218 | *list = insert_first(*list, new_node); 219 | break; 220 | 221 | case 1: 222 | *list = insert_between(*list, new_node); 223 | break; 224 | 225 | case 2: 226 | *list = insert_last(*list, new_node); 227 | break; 228 | } 229 | } 230 | 231 | /** 232 | * Delete given node from a list. 233 | * 234 | * @param List list 235 | * @param Int data Data to delete 236 | * 237 | * @return List|NULL 238 | */ 239 | List *delete(List **list, int data) 240 | { 241 | if (!*list) { 242 | return NULL; 243 | } 244 | 245 | if (front->data == data) { 246 | List *deleted_node = front; 247 | 248 | front = front->next; 249 | (*list) = front; 250 | 251 | return deleted_node; 252 | } 253 | 254 | List *parent = find_parent(*list, data); 255 | 256 | if (!parent) { 257 | return NULL; 258 | } 259 | 260 | List *delete_node = parent->next; 261 | 262 | parent->next = delete_node->next; 263 | 264 | return delete_node; 265 | } 266 | 267 | /** 268 | * Print a given list. 269 | * 270 | * @param List 271 | * 272 | * @return void 273 | */ 274 | void print_list(List *list) 275 | { 276 | if (!list) { 277 | return; 278 | } 279 | 280 | printf("%d -> ", list->data); 281 | print_list(list->next); 282 | } 283 | 284 | /** 285 | * Print a given list in inverted order. 286 | * 287 | * @param List 288 | * 289 | * @return void 290 | */ 291 | void print_inverted(List *list) 292 | { 293 | if (!list) { 294 | return; 295 | } 296 | 297 | print_inverted(list->next); 298 | printf("%d -> ", list->data); 299 | } 300 | 301 | int main() 302 | { 303 | int data_array[] = {3, 2, 8, 6, 4, 4, 12}; 304 | 305 | List *l1 = NULL; 306 | List *l2 = NULL; 307 | 308 | insert(&l1, 3, 0); //root node 309 | insert(&l1, 2, 0); //insert at start 310 | insert(&l1, 8, 2); //insert at end 311 | insert(&l1, 6, 1); //insert between 2 and 8 312 | 313 | assert(front == l1); 314 | 315 | print_list(l1); 316 | 317 | free(l1); 318 | 319 | for (int i = 0; i < 7; i++) { 320 | insert_sorted(&l2, data_array[i]); 321 | } 322 | 323 | assert(front == l2); 324 | 325 | printf("\n\n"); 326 | print_list(l2); 327 | printf("\n"); 328 | print_inverted(l2); 329 | 330 | List *find_node = find(l2, 8); 331 | assert(8 == find_node->data); 332 | 333 | find_node = find(l2, 99); 334 | assert(NULL == find_node); 335 | 336 | List *deleted_node = delete(&l2, 2); 337 | assert(2 == deleted_node->data); 338 | assert(front == deleted_node->next); 339 | 340 | printf("\n\n"); 341 | print_list(l2); 342 | 343 | deleted_node = delete(&l2, 4); 344 | assert(4 == deleted_node->data); 345 | 346 | printf("\n"); 347 | print_list(l2); 348 | 349 | deleted_node = delete(&l2, 12); 350 | assert(12 == deleted_node->data); 351 | 352 | free(l2); 353 | 354 | return 0; 355 | } 356 | -------------------------------------------------------------------------------- /Eular/large_sum.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Large sum. 3 | * https://projecteuler.net/problem=13 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #define NUM_LENGTH 100 10 | #define DIGITS_LENGTH 50 11 | #define SPLIT_LENGTH 10 12 | #define SECTION_LENGTH (DIGITS_LENGTH / SPLIT_LENGTH) 13 | 14 | int main() 15 | { 16 | unsigned long long large_numbers[NUM_LENGTH][SECTION_LENGTH] = { 17 | {3710728753, 3902102798, 7979982208, 3759024651, 135740250}, 18 | {4637693767, 7490009712, 6481248969, 7007805041, 7018260538}, 19 | {7432498619, 9524741059, 4742333095, 1305812372, 6617309629}, 20 | {9194221336, 3574161572, 5224305633, 181107240, 6154908250}, 21 | {2306758820, 7539346171, 1719803104, 2104751377, 8063246676}, 22 | {8926167069, 6623633820, 1363784183, 8368417873, 4361726757}, 23 | {2811287981, 2849979408, 654819315, 9262169127, 5889832738}, 24 | {4427422891, 7432520321, 9235894228, 7679648767, 272189318}, 25 | {4745144573, 6001306439, 911672168, 5684458871, 1603153276}, 26 | {7038648610, 5843025439, 9396198289, 1759366568, 6757934951}, 27 | {6217645714, 1856560629, 5021572231, 9658675507, 9324193331}, 28 | {6490635246, 2741904929, 1014324458, 1382266334, 7944758178}, 29 | {9257586771, 8337217661, 9637515905, 7923972824, 5598838407}, 30 | {5820356532, 5359399008, 4026335689, 4883018945, 8628227828}, 31 | {8018119938, 4826282014, 2781941399, 4056758715, 1170094390}, 32 | {3539866437, 2827112653, 8299872407, 8447305319, 104293586}, 33 | {8651550600, 6295864861, 5320752733, 7195919142, 517255829}, 34 | {7169388870, 7715466499, 1155934876, 353292171, 4970056938}, 35 | {5437007057, 6826684624, 6214956500, 7647178729, 4438377604}, 36 | {5328265410, 8756828443, 1911906346, 9403785521, 7779295145}, 37 | {3612327252, 5000296071, 750825638, 1565671088, 5258350721}, 38 | {4587657617, 2410976447, 3391106072, 1826523687, 7223636045}, 39 | {1742370690, 5851860660, 4482076212, 981328786, 733969412}, 40 | {8114266041, 8086830619, 3284608111, 9106155694, 512689692}, 41 | {5193432545, 1728388641, 9180470492, 9321505864, 2563049483}, 42 | {6246722164, 8435076201, 7279180399, 4469300473, 2956340691}, 43 | {1573244438, 6908125794, 5140890577, 622942919, 7107928209}, 44 | {5503768752, 5678773091, 8625407449, 6984450833, 393682126}, 45 | {1833638482, 5330154686, 1961243487, 6768129753, 4375946515}, 46 | {8038628759, 2878490201, 5216855548, 2871720121, 9257766954}, 47 | {7818283375, 7993103614, 7403568564, 4909552709, 7864797581}, 48 | {1672632010, 436897842, 5535399209, 3183744149, 7806860984}, 49 | {4840309812, 9077791799, 882187953, 2736447567, 5590848030}, 50 | {8708698755, 1392711854, 5170785441, 6185242432, 693150332}, 51 | {5995940689, 5756536782, 1070749269, 6653767632, 6235447210}, 52 | {6979395067, 9652694742, 5977097391, 6669376304, 2633987085}, 53 | {4105268470, 8299085211, 3994273657, 3411618276, 315001271}, 54 | {6537860736, 1501080857, 91499395, 1255702819, 8746004375}, 55 | {3582903531, 7434717326, 9321235781, 5498262974, 2552737307}, 56 | {9495375976, 5105305946, 9660676831, 5657437716, 7401875275}, 57 | {8890280257, 1733229619, 1766687138, 1993181104, 8770190271}, 58 | {2526768027, 6078003013, 6786809925, 2546340106, 1632866526}, 59 | {3627021854, 497705585, 6299465806, 3623799314, 746255962}, 60 | {2407448690, 8231174977, 7923654662, 5724692332, 2810917141}, 61 | {9143028819, 7103288597, 8066697608, 9293863828, 5025333403}, 62 | {3441306557, 8016127815, 9218150055, 6186883646, 8420090470}, 63 | {2305308117, 2816430487, 6237919698, 4248725503, 6638784583}, 64 | {1148769693, 2154902810, 4240201383, 3512446218, 1441773470}, 65 | {6378329949, 636259666, 4985876182, 2122522551, 2486764533}, 66 | {6772018697, 1698544312, 4195724099, 1395900895, 2310058822}, 67 | {9554825530, 263520781, 5322967962, 4948164195, 3868218774}, 68 | {7608532713, 2285723110, 4248034561, 2486769706, 4507995236}, 69 | {3777424253, 5411291684, 2768655389, 2620502491, 326572967}, 70 | {2370191327, 5725675285, 6532482582, 6546309220, 7058596522}, 71 | {2979886027, 2258331913, 1263751473, 4199488953, 4765745501}, 72 | {1849570145, 4879288984, 8568277260, 7771372140, 3798879715}, 73 | {3829820378, 3031473527, 7215803481, 4451349137, 3226651381}, 74 | {3482954382, 9199918180, 2789165224, 3102739225, 1122869539}, 75 | {4095795306, 6405232632, 5380441000, 5965493915, 9879593635}, 76 | {2974615218, 5502371307, 6422551211, 8369380358, 388584903}, 77 | {4169811622, 2072977186, 1582366784, 2468915799, 3532961922}, 78 | {6246795719, 4401269043, 8771072750, 4810239089, 5523597457}, 79 | {2318970677, 2547915061, 5055049539, 2297953090, 1129967519}, 80 | {8618808822, 5875314529, 5840992512, 382900940, 7770775672}, 81 | {1130673970, 8304724483, 8165338735, 234084564, 7058077308}, 82 | {8295917476, 7140363198, 81871290, 1187549131, 547126581}, 83 | {9762333104, 4818386269, 5154563349, 2636657289, 7563400500}, 84 | {4284628018, 3517070527, 8318394258, 8214552122, 7251250327}, 85 | {5512160354, 6981200581, 7621652128, 2765275169, 1296897789}, 86 | {3223819573, 4329339946, 4375019078, 3694576588, 3352399886}, 87 | {7550616496, 5184775180, 7381688378, 6109152735, 7929701337}, 88 | {6217784275, 2192623401, 9423996391, 6804498399, 3173312731}, 89 | {3292418570, 7147349566, 9166746876, 3466091503, 5914677504}, 90 | {9951867143, 235219628, 8948901024, 2332511691, 3619626622}, 91 | {7326746080, 591547471, 8307983928, 6853520694, 6944540724}, 92 | {7684182252, 4674417161, 5140364279, 8227334805, 5556214818}, 93 | {9714261791, 342598647, 2045168939, 8942217982, 6088076852}, 94 | {8778364618, 2799346313, 7677543078, 936333301, 8982642090}, 95 | {1084880252, 1674670883, 2151201858, 8354322381, 2876952786}, 96 | {7132961247, 4782464538, 6369930090, 4931036361, 9763878039}, 97 | {6218407357, 2399794223, 4062353938, 833965132, 7408011116}, 98 | {6662789198, 1488087797, 9418768761, 4423003098, 4490851411}, 99 | {6066182629, 3682836764, 7447792391, 8033511098, 9069790714}, 100 | {8578694408, 9552990653, 6404474255, 7608365997, 6645795096}, 101 | {6602439640, 9905389607, 1201982199, 7604759949, 197230297}, 102 | {6491398268, 32973156, 371200413, 7790378556, 6085089252}, 103 | {1673093931, 9872750275, 4689069037, 753941304, 2652315011}, 104 | {9480937724, 5048795150, 9541009216, 4586375471, 598436791}, 105 | {7863916702, 1187492431, 9957006419, 1796977759, 9028300699}, 106 | {1536871371, 1936614952, 8113058763, 8027841075, 4449733078}, 107 | {4078992311, 5535562561, 1423224232, 5503368544, 2488917353}, 108 | {4488991150, 1440648020, 3690680639, 6067232219, 3204149535}, 109 | {4150312888, 339536053, 2993403680, 697771065, 566631954}, 110 | {8123488067, 3210146739, 585685579, 3458140362, 7822703280}, 111 | {8261657077, 3948327592, 2328459417, 652509451, 2325230608}, 112 | {2291880205, 8777319719, 8394501808, 8807242966, 1980811197}, 113 | {7715854250, 2016545090, 4132458097, 8688277894, 8721859617}, 114 | {7210783843, 5069186155, 4356628840, 6225747369, 2284509516}, 115 | {2084960398, 134001723, 9306716668, 2355524525, 2804609722}, 116 | {5350353422, 6472524250, 8740540755, 9178978126, 4330331690} 117 | }; 118 | 119 | int remainder = 0, num_digits; 120 | unsigned long long sum[SPLIT_LENGTH] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 121 | unsigned long long tenth_power = (unsigned long long) pow(10, SPLIT_LENGTH); 122 | 123 | for (int j = SECTION_LENGTH - 1; j >= 0; j--) { 124 | for (int i = 0; i < NUM_LENGTH; i++) { 125 | sum[j] += large_numbers[i][j]; 126 | } 127 | 128 | sum[j] += remainder; 129 | 130 | num_digits = (int) floor(log10(sum[j])) + 1; 131 | 132 | if (j > 0 && num_digits > SPLIT_LENGTH) { 133 | remainder = (int) (sum[j] / tenth_power); 134 | 135 | sum[j] -= remainder * tenth_power; 136 | } 137 | } 138 | 139 | for (int i = 0; i < 5; i++) { 140 | printf("%010llu ", sum[i]); 141 | } 142 | 143 | // Output: 553737623039 0876637302 0487468329 8597177365 9831892672 144 | 145 | return 0; 146 | } 147 | --------------------------------------------------------------------------------