/* CS107 Pointers + Heap Example
 * Code by Nick Troccoli
 * 
 * This program compresses numbers in an array as an example of
 * how to use dynamic memory allocation on the heap with malloc
 * and free.
 *
 * If there are no additional command-line arguments, the program
 * runs hardcoded tests of compressing an array of ints.
 * The user can also specify a list of numbers as command line
 * arguments to use to test the function.
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#define COMPRESSION_THRESHOLD 6


/* Function: compress_in_batches
 * --------------------------
 * This function returns a heap-allocated, compressed version of the 
 * given int array.  If the array's length is <= COMPRESSION_THRESHOLD, it's 
 * compressed with a batch size of 2, summing each sequential pair of elements.  
 * Otherwise, it's compressed more aggressively with a batch size of 3,
 * summing each sequential trio of elements.  It is the caller's responsibility 
 * to free the returned heap array.  The length of the compressed array
 * is stored in the location pointed to by out_n.
 *
 * If the provided int array length is not a multiple of the batch size (2 or 3),
 * or if the array is empty, this function returns NULL and no length is stored
 * at the location pointed to by out_n.
 */
int *compress_in_batches(const int *values, int n, int *out_n) {
    if (n <= 0) return NULL;

    int batch_size = 2;
    if (n > COMPRESSION_THRESHOLD) {
        batch_size = 3;
    }

    if (n % batch_size != 0) return NULL;

    // TODO: implement the rest of this function
    return NULL;
}


/************************************ main ************************************/

/* Function: print_int_array
 * --------------------------
 * This function prints the given int array in {1, 2, 3} format.
 */
void print_int_array(const int arr[], int n) {
    printf("{");
    for (int i = 0; i < n; i++) {
        if (i > 0) {
            printf(", ");
        }
        printf("%d", arr[i]);
    }
    printf("}\n");
}

/* Function: test_compress_in_batches
 * --------------------------
 * This function runs test cases on compress_in_batches for the specified 
 * int array, and prints out the result.
 */
void test_compress_in_batches(const int *vals, int num_vals) {
    int compressed_length;
    int *compressed_vals = compress_in_batches(vals, num_vals, &compressed_length);
    if (compressed_vals != NULL) {
        print_int_array(compressed_vals, compressed_length);
        free(compressed_vals);
    }
}

int main(int argc, char *argv[]) {
    if (argc == 1) {
        // Large test case
        int testing1[] = { 1, 5, 15, -2, 45, 2, 6, 12, 0 };
        int n_elems = sizeof(testing1) / sizeof(int);
        test_compress_in_batches(testing1, n_elems);

        // Smaller test case
        int testing2[] = { 4, 6, 7, 1 };
        n_elems = sizeof(testing2) / sizeof(int);
        test_compress_in_batches(testing2, n_elems);
    } else {
        // Test compressing the command line arguments
        int testing[argc - 1];
        for (int i = 1; i < argc; i++) {
            testing[i - 1] = atoi(argv[i]);
        }
        test_compress_in_batches(testing, argc - 1);
    }

    return 0;
}
