Advertisement
Nickel59

Untitled

Dec 6th, 2024
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.84 KB | None | 0 0
  1. #include <inttypes.h>
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <vcruntime.h>
  8.  
  9. #define lengthof(x) (sizeof(x) / sizeof(*(x)))
  10.  
  11. void *safemalloc(size_t size) {
  12.   void *block = malloc(size);
  13.   if (!block) {
  14.     (void)fputs("Memory allocation has failed.", stderr);
  15.     abort();
  16.   }
  17.   return block;
  18. }
  19.  
  20. void *saferealloc(void *block, size_t size) {
  21.   char *newBlock = realloc(block, size);
  22.   if (!newBlock) {
  23.     (void)fputs("Memory reallocation has failed.", stderr);
  24.     abort();
  25.   }
  26.   return newBlock;
  27. }
  28.  
  29. char *input(uint16_t maxLength) {
  30.   if (!maxLength) {
  31.     return NULL;
  32.   }
  33.   int32_t inputStringSize = maxLength + 2;
  34.   char *inputString = safemalloc(inputStringSize);
  35.   if (!fgets(inputString, inputStringSize, stdin)) {
  36.     free(inputString);
  37.     while (getchar() != '\n') {
  38.     }
  39.     return NULL;
  40.   }
  41.   if (inputString[0] == '\n') {
  42.     free(inputString);
  43.     return NULL;
  44.   }
  45.   size_t inputStringLength = strlen(inputString);
  46.   char *lastStringCharacterPtr = &(inputString[inputStringLength - 1]);
  47.   if (*lastStringCharacterPtr != '\n') {
  48.     free(inputString);
  49.     while (getchar() != '\n') {
  50.     }
  51.     return NULL;
  52.   }
  53.   *lastStringCharacterPtr = '\0';
  54.   return saferealloc(inputString, inputStringLength);
  55. }
  56.  
  57. uint64_t abs64(int64_t integer) { return integer < 0 ? -(uint64_t)integer : integer; }
  58.  
  59. typedef struct {
  60.   int64_t integer;
  61.   const char *error;
  62. } StringToIntResult;
  63. StringToIntResult *stringToInt(const char *string) {
  64.   StringToIntResult *result = safemalloc(sizeof(StringToIntResult));
  65.   if (!string) {
  66.     *result = (StringToIntResult){0, "Passed NULL."};
  67.     return result;
  68.   }
  69.   if (string[0] == '\0') {
  70.     *result = (StringToIntResult){0, "Invalid string."};
  71.     return result;
  72.   }
  73.   bool startsWithNegativeSign = (string[0] == '-');
  74.   if (startsWithNegativeSign) {
  75.     string = string + 1;
  76.   }
  77.   uint64_t maxInt = abs64(startsWithNegativeSign ? INT64_MIN : INT64_MAX);
  78.   uint8_t maxDigitNumber = snprintf( // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  79.       NULL, 0, "%" PRIu64, maxInt);
  80.   size_t stringLength = strlen(string);
  81.   if (stringLength == 0 || string[0] == '0' || stringLength > maxDigitNumber) {
  82.     *result = (StringToIntResult){0, "Invalid string."};
  83.     return result;
  84.   }
  85.   for (uint32_t i = 0; i < stringLength; ++i) {
  86.     if (string[i] < '0' || string[i] > '9') {
  87.       *result = (StringToIntResult){0, "The string contains non numerical characters."};
  88.       return result;
  89.     }
  90.   }
  91.   if (stringLength == maxDigitNumber) {
  92.     char *maxString = safemalloc(maxDigitNumber + 1);
  93.     (void)snprintf(maxString, // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  94.                    maxDigitNumber + 1, "%" PRIu64, maxInt);
  95.     for (uint32_t i = 0; i < stringLength; ++i) {
  96.       if (string[i] > maxString[i]) {
  97.         free(maxString);
  98.         *result = (StringToIntResult){0, "The resulting integer is too large."};
  99.         return result;
  100.       }
  101.     }
  102.     free(maxString);
  103.   }
  104.   int64_t integer = strtoll(string, NULL, 10);
  105.   if (startsWithNegativeSign) {
  106.     integer = -integer;
  107.   }
  108.   *result = (StringToIntResult){integer, NULL};
  109.   return result;
  110. }
  111.  
  112. typedef struct {
  113.   size_t smallerIndex;
  114.   size_t biggerIndex;
  115. } ClosestNumberIndeces;
  116. ClosestNumberIndeces *calculate(int32_t *array, size_t size) {
  117.   if (size < 2) {
  118.     puts("The array has to have at least 2 elements.");
  119.     abort();
  120.   }
  121.   ClosestNumberIndeces *closestNumberIndeces = safemalloc(sizeof(ClosestNumberIndeces));
  122.   *closestNumberIndeces = (ClosestNumberIndeces){0, 1};
  123.   if (size == 2 || !abs64((int64_t)(array[closestNumberIndeces->smallerIndex]) -
  124.                           (int64_t)(array[closestNumberIndeces->biggerIndex]))) {
  125.     return closestNumberIndeces;
  126.   }
  127.   uint64_t iterationAbsoluteDifference = 0;
  128.   for (size_t i = 0; i < size; ++i) {
  129.     for (size_t j = i + 1; j < size; ++j) {
  130.       iterationAbsoluteDifference = abs64((int64_t)(array[i]) - (int64_t)(array[j]));
  131.       if (iterationAbsoluteDifference == 0) {
  132.         *closestNumberIndeces = (ClosestNumberIndeces){i, j};
  133.         return closestNumberIndeces;
  134.       }
  135.       if (iterationAbsoluteDifference < abs64((int64_t)(array[closestNumberIndeces->smallerIndex]) -
  136.                                               (int64_t)(array[closestNumberIndeces->biggerIndex]))) {
  137.         *closestNumberIndeces = (ClosestNumberIndeces){i, j};
  138.       }
  139.     }
  140.   }
  141.   return closestNumberIndeces;
  142. }
  143.  
  144. int main() {
  145.   printf("Enter array size >>> ");
  146.   char *arraySizeString = input(9);
  147.   if (!arraySizeString) {
  148.     puts("Invalid input.");
  149.     return 1;
  150.   }
  151.   StringToIntResult *arraySizeResult = stringToInt(arraySizeString);
  152.   free(arraySizeString);
  153.   if (arraySizeResult->error) {
  154.     puts(arraySizeResult->error);
  155.     free(arraySizeResult);
  156.     return 1;
  157.   }
  158.   int32_t *array = safemalloc(sizeof(int32_t) * arraySizeResult->integer);
  159.   for (size_t i = 0; i < arraySizeResult->integer; ++i) {
  160.     printf("Enter array element >>> ");
  161.     char *elementString = input(9);
  162.     if (!elementString) {
  163.       free(arraySizeResult);
  164.       free(array);
  165.       puts("Invalid input.");
  166.       return 1;
  167.     }
  168.     StringToIntResult *elementResult = stringToInt(elementString);
  169.     free(elementString);
  170.     if (elementResult->error) {
  171.       free(arraySizeResult);
  172.       free(array);
  173.       puts(elementResult->error);
  174.       free(elementResult);
  175.       return 1;
  176.     }
  177.     array[i] = (int32_t)elementResult->integer;
  178.     free(elementResult);
  179.   }
  180.   ClosestNumberIndeces *closestNumberIndeces = calculate(array, arraySizeResult->integer);
  181.   free(arraySizeResult);
  182.   free(array);
  183.   printf("%" PRIu64 " %" PRIu64, closestNumberIndeces->smallerIndex, closestNumberIndeces->biggerIndex);
  184.   free(closestNumberIndeces);
  185.   return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement