Emeeus
Emeeus

Reputation: 5250

Divide a number into unequal parts in order to balance vector in r

I have a vector made of 10 random integers like this:

a <- c(400,1,1,1,1,1,1,1,1,13)

and I have a random integer:

n <- 100

My goal is to divide n so that the components of a have the smallest differences between them. The desired output in this case is c(400,14,14,14,14,13,13,13,13,13) (13+13+13+13+12+12+12+12 = 100)

My approach was to use a recursive function:

    dis <- function(n,a){

      a[which.min(a)] <- a[which.min(a)] + 1 

      n <- n -1

      if(!n){
        return(a)
      }

      dis(n,a)

   }

   dis(100, c(400,1,1,1,1,1,1,1,1,13))

But I found problems when n is larger, e.g. when n is 1000 I get this message

Error: C stack usage 7969684 is too close to the m

I'm not sure if there is something to avoid recursion, maybe an arithmetic solution, or another approach.

Upvotes: 0

Views: 248

Answers (2)

ThomasIsCoding
ThomasIsCoding

Reputation: 101568

You need some minor modification over your recursive function, e.g.,

dis <- function(n, a) {
  if (!n) {
    return(a)
  } else {
    a[which.min(a)] <- a[which.min(a)] + 1
    dis(n-1, a)
  }
}

Example

> dis(100,a)
 [1] 400  14  14  14  14  13  13  13  13  13

> dis(1000,a)
 [1] 400 114 114 114 114 113 113 113 113 113

Upvotes: 0

Allan Cameron
Allan Cameron

Reputation: 173858

Why not do it as a while loop rather than using deeply nested recursion?

dis <- function(n,a) {

  while(n > 0)
  {
    a[which.min(a)] <- a[which.min(a)] + 1 
    n <- n - 1
  }
  a
}

dis(100, c(400,1,1,1,1,1,1,1,1,13))
#> [1] 400  14  14  14  14  13  13  13  13  13

dis(10000, c(400,1,1,1,1,1,1,1,1,13))
#> [1] 1043 1042 1042 1042 1042 1042 1042 1042 1042 1042

Upvotes: 1

Related Questions