Advertisement
Standev

Pandigital division

Oct 28th, 2018
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.78 KB | None | 0 0
  1. /* file: pandigital_division.c                                    */
  2. /* author: Stan van der Bend (email: stanvdbend@gmail.com)        */
  3. /* date: 25-10-2018                                               */
  4. /* version: 1.0                                                   */
  5. /* Description: prints all combinations of numbers ABCDE/FGHIJ
  6.  *              that yield n. The letters represents the digits.
  7.  *              All digits 0..9 must be used.                     */
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <stdlib.h>
  12.  
  13. // template for a dynamic array
  14. typedef struct { int *array; size_t used; size_t size; } DynamicArray;
  15.  
  16. // initialise a DynamicArray, allocate resources.
  17. void initDA(DynamicArray *a, size_t initialSize) {
  18.     a->array = (int *)malloc(initialSize * sizeof(int));
  19.     a->used = 0;
  20.     a->size = initialSize;
  21. }
  22.  
  23. // insert an integer element into the argued DA
  24. void insertInDynamicArray(DynamicArray *a, int element) {
  25.     if (a->used == a->size) {
  26.         a->size *= 2;
  27.         a->array = (int *)realloc(a->array, a->size * sizeof(int));
  28.     }
  29.     a->array[a->used++] = element;
  30. }
  31.  
  32. DynamicArray combine(DynamicArray a, DynamicArray b){
  33.     DynamicArray combined;
  34.     initDA(&combined, a.used + b.used);
  35.     for (int i = 0; i < a.used; ++i) {
  36.         insertInDynamicArray(&combined, a.array[i]);
  37.     }
  38.     for (int i = 0; i < b.used; ++i) {
  39.         insertInDynamicArray(&combined, b.array[i]);
  40.     }
  41.     return combined;
  42. }
  43.  
  44. /**
  45.  * @param a an array of length > 8, possibly containing duplicates.
  46.  * @return {@code true}(1) if the array contains a duplicate integer value, {@code false}(0) if not.
  47.  */
  48. int containsDuplicate(DynamicArray a){
  49.  
  50.     for (int i = 0; i < a.used; ++i) {
  51.         for (int j = i + 1; j < a.used; ++j) {
  52.             if(a.array[i] == a.array[j]){
  53.                 return 1;
  54.             }
  55.         }
  56.     }
  57.     return 0;
  58. }
  59.  
  60. /**
  61.  * Checks if a given two dynamic arrays contain the digits 0..9
  62.  *count = 246
  63.  * @param a array one
  64.  * @param b array two
  65.  * @return {@code true}(1) if the digits 0..9 are present in arrays a and b, {@code false}(0) if not.
  66.  */
  67. int containsPangramNumber(DynamicArray a, DynamicArray b){
  68.     int panProduct = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9; // 362.880
  69.     int panSum = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9;     // 45
  70.  
  71.     /*
  72.      * Determine both the sum and the product of the digits in the two given arrays.
  73.      */
  74.     int product = 1;
  75.     int sum = 0;
  76.  
  77.     for (int i = 0; i < a.used; ++i) {
  78.         if(a.array[i] == 0) // leave out zero
  79.             continue;
  80.         product *= a.array[i];
  81.         sum += a.array[i];
  82.     }
  83.     for (int j = 0; j < b.used; ++j) {
  84.         if(b.array[j] == 0) // leave out zero
  85.             continue;
  86.         product *= b.array[j];
  87.         sum += b.array[j];
  88.     }
  89.  
  90.  
  91.     return panSum == sum && panProduct == product;
  92. }
  93.  
  94. /**
  95.  * @param n an integer n of length 4/5
  96.  * @return convert the given integer n into an array of digits
  97.  */
  98. DynamicArray getDigits(int n){
  99.  
  100.     DynamicArray digits;
  101.     initDA(&digits, 5);
  102.  
  103.     while (n > 0){
  104.         int remainder = n%10;
  105.         insertInDynamicArray(&digits, remainder);
  106.         n /= 10;
  107.     }
  108.  
  109.     return digits;
  110. }
  111.  
  112. int countPanDiv2(int n){
  113.     // we declare this variable to count the results, if none we should print "NONE"
  114.     int count = 0;
  115.  
  116.     // iterate the number from 98765..01234 (in ascending order)
  117.     for(int i = 98765; i >= 01234; i--){
  118.         // find the remainder of the product of the given input and the iteration number
  119.         int remainder = i % n;
  120.         // check if the division product is going to be a whole number, remainder is 0
  121.         if(remainder == 0){
  122.             // get the product of the division by our iteration value and the input number
  123.             int product = i / n;
  124.             // check whether both the input number and the product contain a leading zero
  125.             int bothHaveLeadingZero = i < 10000 && product < 10000;
  126.             // if both have, that means we know it does not contain the digits 0..9
  127.             if(!bothHaveLeadingZero){
  128.  
  129.                 /*
  130.                  * store the digits of both the input number and the product in an array
  131.                  */
  132.                 DynamicArray a = getDigits(i);
  133.                 DynamicArray b = getDigits(product);
  134.                 DynamicArray combined = combine(a, b);
  135.  
  136.                 // if the combined length of both of our arrays is smaller than 9,
  137.                 // we know the combined digits of these arrays cannot contain the digits 0..9
  138.                 if(combined.used < 9)
  139.                     continue;
  140.  
  141.                 // check if the digits of the combined array contains any duplicates
  142.                 if(containsDuplicate(combined))
  143.                     continue;
  144.  
  145.                 // check if the combined digits of both arrays are the digits 0..9
  146.                 if(containsPangramNumber(a, b)){
  147.  
  148.                     /*
  149.                      * check which array (if any) uses up 4 out of 5 slots,
  150.                      * if any such array exists, add a 0 in front of the number that this array represents.
  151.                      */
  152.                     if(a.used == 4)
  153.                         printf("0%d/%d", i, product);
  154.                     else if(b.used == 4)
  155.                         printf("%d/0%d", i, product);
  156.                     else
  157.                         printf("%d/%d", i, product);
  158.  
  159.                     printf("\n");
  160. //                    printf(" - length = %d %d \n", (int) a.used, (int) b.used);
  161.                     count++;
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     return count;
  167. }
  168.  
  169.  
  170. int main() {
  171.  
  172.     int n; //n integers
  173.  
  174.     scanf("%d", &n);
  175.  
  176.     int count = countPanDiv2(n);
  177.  
  178.     if(count == 0)
  179.         printf("NONE");
  180.  
  181.     return 0;
  182. }
  183. //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement