Absolute Element Sums

  • + 0 comments

    I finally beated the hack. The key here is to note that, according to restrictions, there can be only 4001 different values for input, so we can characterize them by their value, and the number of occurrences for each. Then, it's pretty straightforward.

    typedef uint64_t result_t;
    
    /* This structure stores info about each element in dara `arr`.
     * There exist, as much, 4001 different values as
     *   -2000 <= arr[i] <= 2000
     */
    struct point
    {
    	int value;
    	int freq;
    };
    typedef struct point point_t;
    
    /* Calculates the result of query `q` applied over arr */
    result_t calculateQueryResult(size_t sample_len, point_t* restrict sample, const int q)
    {
        result_t abs_sum = 0;
        
        for (size_t i = 0; i < sample_len; i++) {
    	    abs_sum += sample[i].freq * abs(sample[i].value += q);
        }
        return abs_sum;
    }
    
    /** This maps a value into an index of the array of samples */
    #define map(value) (2000 + (value))
    
    /* This builds the sample from array `arr`: values and number 
     * of occurrences for each
     */  
    void characterizeSample(size_t arr_count, int* restrict arr, size_t sample_len, point_t *sample) {
    	size_t i, j;
    	for (j = 0; j < sample_len; j++) {
    		sample[j].freq = 0;
    	}
    	for (i = 0; i < arr_count; i++) {
    		j = map(arr[i]);
    		sample[j].value = arr[i];
    		++sample[j].freq;
    	}
    }
    
    /*
     * Complete the 'playingWithNumbers' function below.
     *
     * The function is expected to return an INTEGER_ARRAY.
     * The function accepts following parameters:
     *  1. INTEGER_ARRAY arr
     *  2. INTEGER_ARRAY queries
     */
    
    result_t* playingWithNumbers(size_t arr_count, int* restrict arr, size_t queries_count, int* restrict queries, size_t* result_count) {
    	*result_count = queries_count;
    
    	// dynamically allocate space for vector `result`
    	if (arr_count <= 0 || queries_count <= 0) { return NULL; }
    	result_t *result = (result_t *)calloc(queries_count, sizeof(result_t));
    	assert(result);
    	
        // initial sum of the array
        result_t r = 0;
    	size_t j;
    	
    	// characterize sample: compute frequency of each value
    	int sample_len = 4001;
    	point_t sample[4001];
    	characterizeSample(arr_count, arr, sample_len, sample);
    	
        for (j = 0; j < queries_count; j++) {
            result[j] = calculateQueryResult(sample_len, sample, queries[j]);
        }
        
        return result;
    }