Search code examples
pythonfunctional-programmingprocedural-programming

What is the funtional-style replacement of this loop?


I have the following loop:

import random
distribution = []
sum = 0
while True:
  item = random.randint(1, 8)
  if sum + item == 812:
    distribution.append(item)
    break
  elif sum + item > 812:
    distribution.append(812 - sum)
    break
  else:
    distribution.append(item)
    sum = sum + item

The idea here is to create a list with items where each item is a random number between 1 and 8 and the sum of items in the list has to be exactly 812. The challenge is, that the last item can randomly overshoot, so a simple stop condition won't do.

I'm racking my brain on how to express this functionally, but came up blank so far. Any ideas?


Solution

  • I am answering the title of this question:

    What is the functional-style replacement of this loop?

    def random_list(sum_rest):
        item = random.randint(1, min(8, sum_rest))
        return ([] if sum_rest - item == 0 else random_list(sum_rest - item)) + [item]
    

    This solution is based on the improvement proposed by @DollarAkshay, once you get that, it is very straightforward: I am recursively calling random_list, but decreasing the sum_rest parameter by the item randomly chosen.

    You get the list by calling

    random_list(812)