Home > Software engineering >  Find various ways of allocating fruit to people
Find various ways of allocating fruit to people

Time:10-28

# Example 1
People = ["Terry", "Merry"]
Fruit = ["Apple","Grape","Peach"]

# Possible solutions:
[
  {"Terry"=>"Apple","Merry"=>"Grape"},
  {"Terry"=>"Apple","Merry"=>"Peach"},

  {"Terry"=>"Grape","Merry"=>"Apple"},
  {"Terry"=>"Grape","Merry"=>"Peach"},

  {"Terry"=>"Peach","Merry"=>"Apple"},
  {"Terry"=>"Peach","Merry"=>"Grape"},
]

# Example 2
People = ["Terry", "Merry", "Perry"]
Fruit = ["Apple","Grape"]

# Possible solutions:
[
  {"Terry"=>"Apple","Merry"=>"Grape","Perry"=>nil},
  {"Terry"=>"Apple","Merry"=>nil,"Perry"=>"Grape"},

  {"Terry"=>"Grape","Merry"=>"Apple","Perry"=>nil},
  {"Terry"=>"Grape","Merry"=>nil,"Perry"=>"Apple"},

  {"Terry"=>nil,"Merry"=>"Apple","Perry"=>"Grape"},
  {"Terry"=>nil,"Merry"=>"Grape","Perry"=>"Apple"},
]

Stuck trying to solve this recursively (necessary for this exercise, though let me know if you don't think recursion is possible).

I feel like basically I start by assigning a random person a fruit, and then add that to all possible solutions that arise from the smaller subset of assigning remaining people remaining fruit.

E.g., for Example 1, I assign Terry an Apple, and then aggregate that with the remaining possible options of what Merry can get (either Grape or Peach).

Then just repeat changing up the fruit assigned to the first random person (e.g., with Terry getting Grape then Peach, in Example 1).

I feel like this sounds so straightforward but I cannot write it!

CodePudding user response:

If len(people) <= len(fruit), then you can use

for pieces in itertools.permutations(fruit, len(people)):
    assign the pieces of fruit to the people in order

If len(people) > len(fruit), then use

for eaters in itertools.permutations(people, len(fruit))
    assign the eaters to the fruit in order, and the others get nothing

I don't know how to combine the two separate cases into a single case


I now see that this was supposed to be solve recursively. Misread the original.

Let's look the possibilities for

assignment(people, fruit):

  • If len(people) == 0, then you're done, with the empty solution. (Not to be confused with no solution.)

  • If len(fruit) == 0, then no one gets any fruit. Again, this is an actual solution.

  • If len(people) <= len(fruit), then the first person gets some piece of fruit, appended onto all possible results of the remainder of the people getting the remainder of the fruit.

  • If len(people) > len(fruit), then either the first person does or doesn't get a piece of fruit, and recursively the rest of the people get whatever's left.

It's left as an exercise to you how to code this.

CodePudding user response:

I don't if this can be done by recursion. It can be done as follows.

def hmmm(people, fruit)
  (fruit   [nil]*[people.size - fruit.size, 0].max).
    permutation(people.size).
    map { |a| people.zip(a).to_h }
end
hmmm(["Terry", "Merry"], ["Apple","Grape","Peach"])
  #=> [{"Terry"=>"Apple", "Merry"=>"Grape"},
  #    {"Terry"=>"Apple", "Merry"=>"Peach"},
  #    {"Terry"=>"Grape", "Merry"=>"Apple"},
  #    {"Terry"=>"Grape", "Merry"=>"Peach"},
  #    {"Terry"=>"Peach", "Merry"=>"Apple"},
  #    {"Terry"=>"Peach", "Merry"=>"Grape"}]
hmmm(["Terry", "Merry", "Perry"], ["Apple","Grape"])
  #=> [{"Terry"=>"Apple", "Merry"=>"Grape", "Perry"=>nil},
  #    {"Terry"=>"Apple", "Merry"=>nil,     "Perry"=>"Grape"},
  #    {"Terry"=>"Grape", "Merry"=>"Apple", "Perry"=>nil},
  #    {"Terry"=>"Grape", "Merry"=>nil,     "Perry"=>"Apple"},
  #    {"Terry"=>nil,     "Merry"=>"Apple", "Perry"=>"Grape"},
  #    {"Terry"=>nil,     "Merry"=>"Grape", "Perry"=>"Apple"}]

See Array#permutation and Enumerable#zip.

  • Related