Problem of the Day
A new programming or logic puzzle every Mon-Fri

Random Sum

Hope everyone enjoyed their weekend! Today's problem comes from @quentinms. Thanks for the submission.

How to randomly pick k numbers between 0 and n such that their sum is n?

Permalink: http://problemotd.com/problem/random-sum/

Comments:

  • Anonymous - 9 years, 8 months ago

    cool

    reply permalink

  • Driphter - 9 years, 8 months ago

    Clojure!

    I wasn't sure if the "between" in the requirements was supposed to be inclusive or exclusive, so I did both.

    (defn- rand-sum-inclusive*
      [k n]
      (if (= 1 k)
        [n]
        (let [r (cond
                 (pos? n) (rand-int (inc n))
                 (neg? n) (rand-int (dec n))
                 :else 0)]
          (concat [r] (rand-sum-inclusive* (dec k) (- n r))))))
    
    (defn rand-sum-inclusive
      [k n]
      {:pre [(number? k) (number? n)
             (pos? k)]
       :post [(= n (apply + %))]}
      (rand-sum-inclusive* k n))
    
    (defn- rand-sum-exclusive*
      [k n]
      (if (= 1 k)
        [n]
        (let [r (if (pos? n)
                  (inc (rand-int (- n (dec k))))
                  (dec (rand-int (+ n (inc k)))))]
          (concat [r] (rand-sum-exclusive* (dec k) (- n r))))))
    
    (defn rand-sum-exclusive
      [k n]
      {:pre [(number? k) (number? n)
             (pos? k)
             (or (and (pos? n) (not (neg? (- n k))))
                 (and (neg? n) (not (pos? (+ n k)))))]
       :post [(= n (apply + %))]}
      (rand-sum-exclusive* k n))
    

    reply permalink

  • Anonymous - 9 years, 8 months ago

    Using HTML + JS (with jquery) https://jsfiddle.net/k0f8k3va/1/

    reply permalink

  • David - 9 years, 4 months ago

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    //modify the passed array parameter to contain the k integers from 0 to n, inclusive, that add up to n
    //this function must be should k be allowed to be larger than n.
    //I have made the design decision to allow earlier selected values to remain as unbound as possible
    //therefore, I will keep a checksum
    void randSum(int* arr, unsigned int k, unsigned int n) {
        int maxRemaining = n;
        int count = 0;
        srand(time(NULL));
        //This use of array length without checking length is susceptible to a buffer overflow from a malicious user of the function
        while(count < k) {
            arr[count] = rand() % (maxRemaining + 1);
            maxRemaining -= arr[count];
            count++;
        }
    
    // Below is for output visibility sake
        printf("n = %i: ", n);
        //I am printing because I feel a touch lazy.
        //A better version still would have a return type that enumerates possible errors.
        for(count = 0; count < k; count++) {
            printf("%i", arr[count]);
            if(count < k-1) printf(", ");
        }
        printf("\n");
    }
    
    
    int main(int argc, char const *argv[])
    {
        int* array = (int*) malloc(5 * sizeof(int));
    
        randSum(array, 5, 10);
        randSum(array, 5, 3);
        randSum(array, 5, 5);
        free(array);
        return 0;
    }
    

    reply permalink

Content curated by @MaxBurstein