2 votes

Supprimer les triplets de nombres adjacents de la liste

Voici le problème. L'entrée est une liste d'entiers. Si trois nombres adjacents apparaissent les uns à côté des autres, ils doivent être supprimés et l'opération se poursuit. Application iPhone avec des balles de mêmes couleurs. Le résultat devrait être le nombre de balles qui seront détruites.

Exemple :

input = [3,3,4,4,4,3,4]

1ère itération

output: [3,3,3,4]

Résultat final :

6   

4,4,4 lors de la première itération, donc trois balles. et 3,3,3 à la deuxième. Au total six.

Mon code est ci-dessous. Il va supprimer les 4,4,4 mais échouera ensuite, car l'index de la liste dépassera rapidement la plage.

    def balls(a):

        curr_index = 0
        removed_count = 0
        while len(a) > 2:

            if (a[curr_index] == a[curr_index+1]) and (a[curr_index] == a[curr_index+2]):

                a.remove(a[curr_index])
                a.remove(a[curr_index+1])
                a.remove(a[curr_index+2])

            curr_index += 1
            removed_count += 3

        return removed_count

a = [3, 3, 4, 4, 4, 3, 4]

print(balls(a)) # devrait afficher 6

Des idées ?

1voto

IoaTzimas Points 8393

Voici une manière de le faire :

your_list=[3, 3, 4, 4, 4, 3, 4]

def remove_one(l):
    if len(l)>2:
        for i in range(len(l)-2):
            if l[i]==l[i+1]==l[i+2]:
                res.extend(l[i:i+3])
                l=l[:i]+l[i+3:]
                return l
    return []

res=[]
while len(your_list)>2:
    your_list=remove_one(your_list)

print(len(res))

Output:

6

1voto

Dieter Points 141
input_values = [3,3,4,4,4,3,4]

values = input_values
while len(values) >= 3:
    for x in range(0,len(values)-2):    

        # if we find 3 values in ar row
        if values[x] == values[x+1] and values[x] == values[x+2]:

            # update values by cutting out the series
            values = values[:x] + values[x+3:]

            # break this for loop
            break
    else:
        # for loops can have an else statement
        # this means that we came at the end of the for loop
        # this if we didn't break the loop (and didn't found a valid triple)
        # then we brea
        break

#résultat - montant de billes supprimées     
values, len(input_values) - len(values)

1voto

Dieter Points 141

Une approche plus générique où vous pouvez définir N

(il trouvera exactement N valeurs)

input_values = [3,3,4,4,4,4,3,3,4]

# nombre de voisins
N = 4

valeurs = input_values

# continuer la boucle tant que nous avons N valeurs
while len(valeurs) >= N:

    # nous avons besoin de ceci si nous cassons la boucle interne
    stop = False

    # parcourir les valeurs de gauche à droite
    # 3 -> 3 -> 4 -> 4 -> ... jusqu'à -N + 1
    # car c'est le dernier endroit où nous avons N valeurs restantes
    for x in range(0, len(valeurs) - N + 1):

        # chercher les prochains nombres (x+1 x+2 x+3 ....)
        # cela va de, x+1 jusqu'à la fin de la série
        # commencez également à compter à partir de 2 - car
        # si nous avons une seule correspondance, 2 nombres sont égaux
        for e, y in enumerate(range(x+1, len(valeurs)), start=2):

            # si x et y sont différents, arrêtez cette recherche
            # rappelez-vous y = x+1 x+2 x+3 ....
            if valeurs[x] != valeurs[y]:
                break

            # si nous sommes arrivés à ce stade, nous savons que
            # x et x+1 x+2 ... sont égaux
            # mais aussi vérifier si nous avons assez de correspondances
            if e == N:
                # mettre à jour les valeurs en découpant la série
                valeurs = valeurs[:x] + valeurs[y+1:]
                stop = True
                break

        if stop:
            break

    else:
        # les boucles for peuvent avoir une instruction else
        # cela signifie que nous sommes arrivés à la fin de la boucle for
        # cela signifie que si nous n'avons pas interrompu la boucle (et n'avons pas trouvé de triplet valide)
        # alors nous quittons
        break

valeurs, len(input_values) - len(valeurs)

1voto

Dieter Points 141

Une approche avec un seuil minimal

input_values = [3,3,4,4,4,4,4,3,3,4]

# seuil
N = 3

values = input_values
while len(values) >= N:

    # nous avons besoin de cela si nous cassons la boucle interne
    stop = False

    # boucle sur les valeurs
    for x in range(0, len(values) - N + 1):    

        # repérer les prochains nombres (x+1 x+2 x+3 ....)
        for e, y in enumerate(range(x+1, len(values)), start=2):

            # vérifier si les valeurs de x et x+1  (x+2 x+3 ...) sont différentes
            if values[x] != values[y]:

                # si c'est le cas, vérifiez si nous avons atteint notre seuil de N
                if e >= N:

                    # si tel est le cas, mettez à jour les valeurs en supprimant la série
                    values = values[:x] + values[y:]
                    stop = True
                    break

                # si x+n != x alors nous arrêtons cette boucle de repérage
                break

        # stop est True, cela signifie que nous avons trouvé N nombres adjacents
        # ainsi nous pouvons casser cette boucle, et recommencer avec une nouvelle valeur*
        if stop:
            break

    else:
        # les boucles for peuvent avoir une instruction else
        # cela signifie que nous sommes arrivés à la fin de la boucle for
        # donc si nous n'avons pas cassé la boucle (et pas trouvé un triplet valide)
        # alors nous cassons
        break

valeurs, len(input_values) - len(values)

0voto

aviso Points 1321

Il y a quelques problèmes avec votre code.

La première chose est que vous essayez d'itérer sur la liste une seule fois, mais cela ne fonctionnera pas pour votre exemple.

La deuxième chose est que vous supposez que la liste se réduira toujours à moins de 3 éléments, ce qui ne sera pas le cas si vous avez plus de chiffres.

Il y a aussi des endroits où vous pouvez simplifier la syntaxe, par exemple:

if (a[curr_index] == a[curr_index+1]) et (a[curr_index] == a[curr_index+2]):

est équivalent à:

if a[curr_index] == a[curr_index + 1] == a[curr_index + 2]:

Et

a.remove(a[curr_index])
a.remove(a[curr_index+1])
a.remove(a[curr_index+2])

est équivalent à:

del a[curr_index: curr_index + 3]

Voici donc une façon d'accomplir ceci, bien qu'il existe des moyens plus efficaces.

def balls(a):

    removed = 0
    complete = False

    # Continue jusqu'à ce que complete soit défini ou que la liste soit trop courte pour une correspondance
    while not complete and len(a) >= 3:

        for idx, val in enumerate(a):
            if val == a[idx + 1] == a[idx + 2]:
                del a[idx: idx + 3]
                removed += 3
                break  # Redémarre à chaque fois qu'une correspondance est trouvée

            # S'il s'agit de la dernière correspondance possible, définir complete
            if idx == len(a) - 3:
                complete = True
                break

    return removed

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X