0
$\begingroup$

Alice is preparing decorations to decorate the classroom for Children's Day. She is using beads in the colors red (r), green (g), blue (b), and yellow (y) to create strings of beads. During the class meeting, it was established that two beads of the same color cannot be placed next to each other.

Help Alice design the strings of beads and write a function called "beads(lk)" where the result is a sorted list of words representing the strings that can be constructed using all available beads. The parameter "lk" is a four-element list of numbers that specify the number of red, green, blue, and yellow beads, respectively. The maximum total number of beads is n=10.

Here is my solution using permutation, but the complexity is high.

from itertools import permutations

def beads(lk):
    colors = ['r', 'g', 'b', 'y']
    all = []
    for i in range(len(lk)):
        for j in range(lk[i]):
            all.append(colors[i])
    all_possible_combinations = []
    
    for perm in permutations(all):
        valid = True
        for i in range(len(perm) - 1):
            if perm[i] == perm[i + 1]:
                    valid = False
                    break
        if valid:
            all_possible_combinations.append("".join(perm))
    unique_combinations = sorted(set(all_possible_combinations))

    return unique_combinations

I am looking for a better complexity algorithm, now is O(n!). Can you provide me with some ideas?

Edit

Thanks @Yves for your suggestion:

def beads(lk):
    def recursive_beads(prev_color, remaining, current_string):
        valid_strings = []
        if sum(remaining) == 0:
            return [current_string]
        for color, count in enumerate(remaining):
            if count > 0 and color != prev_color:
                new_remaining = list(remaining)
                new_remaining[color] -= 1
                valid_strings.extend(recursive_beads(color, new_remaining, current_string + colors[color]))

        return valid_strings

    colors = ['r', 'g', 'b', 'y']
    result = []
    valid_strings = recursive_beads(4, lk, "")

    return valid_strings
$\endgroup$
8
  • 1
    $\begingroup$ Any attribution to the source of the problem? $\endgroup$ Commented Sep 8, 2023 at 12:41
  • $\begingroup$ You can do an $O(n^4)$ dynamic program by storing how many red, green, yellow, and blue colors you have left to insert in the first 4 states, and a number $b\in \{0,1,2,3\}$ indicating the last color added in the fifth state. $\endgroup$ Commented Sep 8, 2023 at 12:51
  • $\begingroup$ Do you mean to use the 5d array? @AspiringMat $\endgroup$ Commented Sep 8, 2023 at 13:53
  • $\begingroup$ @PålGD the original source in Polish, is the kid's competitions, I wanted to build a better solution than me. $\endgroup$ Commented Sep 8, 2023 at 13:57
  • $\begingroup$ @AspiringMat: are you sure that the number of possible strings does not exceed $O(n^4)$ ? $\endgroup$
    – user16034
    Commented Sep 8, 2023 at 14:26

1 Answer 1

1
$\begingroup$

Use a recursive function that takes as input

  • the string assembled so far,

  • the remaining amounts of beads of every color.

In this function, you will try and add a bead of every color (if available, and different from the previous), and recurse until no bead remains.


I believe that this is close to optimal, but the complexity is pretty difficult to evaluate.

$\endgroup$
3
  • $\begingroup$ Thanks for your suggestion, I implemented this approach. What do you think about complexity? It is not linear? $\endgroup$ Commented Sep 8, 2023 at 14:56
  • $\begingroup$ @MartinInf1n1ty: it is probably close to linear in the number of solutions, times $n$. But I can't tell more. $\endgroup$
    – user16034
    Commented Sep 8, 2023 at 15:01
  • $\begingroup$ If the counts are $[202,100,100,0]$ then I think this algorithm will take $>2^{100}$ steps to figure out that there are no solutions. It may be fixable by adding a bailout condition that max(lk) <= ceil(sum(lk)/2), but I don't know if I'm overlooking another pathological case. $\endgroup$
    – benrg
    Commented Sep 8, 2023 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.