diff --git a/solutions/c/palindrome-products/1/palindrome_products.c b/solutions/c/palindrome-products/1/palindrome_products.c new file mode 100644 index 0000000..a5cd2fd --- /dev/null +++ b/solutions/c/palindrome-products/1/palindrome_products.c @@ -0,0 +1,90 @@ +#include "palindrome_products.h" +#include +#include +#include +#include + +static inline bool is_palindrome(int n) { + if (n < 0 || (n != 0 && n % 10 == 0)) return false; + int reversed = 0, original = n; + while (n > 0) { + reversed = reversed * 10 + (n % 10); + n /= 10; + } + return original == reversed; +} + +static inline void add_factor(factor_t **head, int a, int b) { + factor_t *new_node = malloc(sizeof(factor_t)); + new_node->factor_a = a; + new_node->factor_b = b; + new_node->next = *head; + *head = new_node; +} + +static inline void free_factors(factor_t *f) { + while (f) { + factor_t *temp = f; + f = f->next; + free(temp); + } +} + +product_t *get_palindrome_product(int from, int to){ + product_t *result = calloc(1, sizeof(product_t)); + + if (from > to) { + snprintf(result->error, MAXERR, "invalid input: min is %d and max is %d", from, to); + return result; + } + + result->smallest = -1; + result->largest = -1; + + + for (int i = from; i <= to; i++) { + for (int j = i; j <= to; j++) { + int product = i * j; + + if ((result->smallest != -1 && product > result->smallest) && + (result->largest != -1 && product < result->largest)) { + continue; + } + + if (is_palindrome(product)) { + + if (result->smallest == -1 || product < result->smallest) { + free_factors(result->factors_sm); + result->factors_sm = NULL; + result->smallest = product; + add_factor(&result->factors_sm, i, j); + } else if (product == result->smallest) { + add_factor(&result->factors_sm, i, j); + } + + if (result->largest == -1 || product > result->largest) { + free_factors(result->factors_lg); + result->factors_lg = NULL; + result->largest = product; + add_factor(&result->factors_lg, i, j); + } else if (product == result->largest) { + add_factor(&result->factors_lg, i, j); + } + } + } + } + + if (result->smallest == -1) { + snprintf(result->error, MAXERR, "no palindrome with factors in the range %d to %d", from, to); + } + + return result; +} + +void free_product(product_t *p){ + if (p) { + free_factors(p->factors_sm); + free_factors(p->factors_lg); + free(p); + } +} diff --git a/solutions/c/palindrome-products/1/palindrome_products.h b/solutions/c/palindrome-products/1/palindrome_products.h new file mode 100644 index 0000000..320d892 --- /dev/null +++ b/solutions/c/palindrome-products/1/palindrome_products.h @@ -0,0 +1,25 @@ +#ifndef PALINDROME_PRODUCTS_H +#define PALINDROME_PRODUCTS_H + +#define MAXERR 100 + +typedef struct factors { + int factor_a; + int factor_b; + struct factors *next; +} factor_t; + +struct product { + int smallest; + int largest; + factor_t *factors_sm; + factor_t *factors_lg; + char error[MAXERR]; +}; + +typedef struct product product_t; + +product_t *get_palindrome_product(int from, int to); +void free_product(product_t *p); + +#endif