La génération combinée des débutants Python (lycéens) était en diagonale au-dessus (génération combinée par traitement récursif)

Puzzle mathématique

M. K étudie Python [puzzle mathématique](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3% 83% 9E% E8% 84% B3% E3% 82% 92% E9% 8D% 9B% E3% 81% 88% E3% 82% 8B% E6% 95% B0% E5% AD% A6% E3% 83% 91% E3% 82% BA% E3% 83% AB-% E3% 82% B7% E3% 83% B3% E3% 83% 97% E3% 83% AB% E3% 81% A7% E9% AB% 98 % E9% 80% 9F% E3% 81% AA% E3% 82% B3% E3% 83% BC% E3% 83% 89% E3% 81% 8C% E6% 9B% B8% E3% 81% 91% E3 % 82% 8B% E3% 82% 88% E3% 81% 86% E3% 81% AB% E3% 81% AA% E3% 82% 8B70% E5% 95% 8F-% E5% A2% 97% E4% BA% 95-% E6% 95% 8F% E5% 85% 8B / dp / 479814245X / ref = asc_df_479814245X /? Tag = jpo-22 & linkCode = df0 & hvadid = 295723231663 & hvpos = 1o1 & hvnetw = g & hvrando = 6299120 & hvlocint = & hvlocphy = 100009242 & hvtargid = pla-526233948639 & psc = 1 & th = 1 & psc = 1) La deuxième fois.

Le problème de trouver une condition dans laquelle le résultat du calcul correspond à l'ordre inverse du nombre d'origine en insérant quatre règles de fonctionnement entre les nombres à quatre chiffres. Saisissez au moins une des quatre règles. Si vous écrivez la réponse, 5931 5931 = 1395 Voilà la réponse. Regardez autour de vous et trouvez celui qui correspond aux conditions.

En gros, c'est un programme comme celui-ci.

op_table = ["","+","-","*","/"]
for number in range(1000,10000):
    for op1 in op_table:
        for op2 in op_table:
            for op3 in op_table:
                if check(number,op1, op2, op3):
                    print(number,op1, op2, op3)

Travail de débutant en Python

def Quinary(n):
    if (int(n/5)):
        return Quinary(int(n/5)) + str(n%5)
    return str(n%5)

def eval_change(a):
    b = list_change(a)
    try:
        return int(eval(b))
    except ZeroDivisionError:
        return -1
    except SyntaxError:
        return -1
   
def list_change(a):
    b = ""
    for l in a:
        b += l
    return b

table = ["","+","-","*","/"]
for i in range(1000,10000):
    for j in range(1,125):
        a = (Quinary(j).zfill(3))
        b = list(str(i))
        for k in range(3):
            b.insert(k*2+1,table[int(a[k])])
        if str(eval_change(b)) == str(i)[::-1]:
            print(i,list_change(b),"=",int(str(i)[::-1]))

Hey hey. M. K a choisi de résoudre avec une double boucle. J'ai l'impression d'avoir choisi une route assez raide, mais je l'ai bien résolue. Quinary semble avoir cherché sur le net. Puisqu'il existe cinq types d'opérateurs, l'idée est d'utiliser des quintuplés. Je n'avais pas cette idée.

Le cœur de ce programme est qu'il utilise récursif pour générer des combinaisons. Vous ne pouvez pas prendre la peine d'évoquer un quintette, mais vous pouvez générer un tournoi à la ronde sans utiliser plusieurs boucles, non? En outre, cette méthode a le potentiel d'être réalisée en modifiant les paramètres.

Alors, résolvons ce problème par une méthode autre que la boucle quadruple médiocre.

Empêcher SyntaxError

Réparez la pièce qui vous tient à cœur avant de faire un remodelage majeur

En python, s'il y a un 0 avant le nombre 0 tel que 01 001, une SyntaxError se produira. Par conséquent, eval ("1 + 001") entraînera une SyntaxError. M. K a adopté une stratégie qui ne calcule pas dans un tel cas. La bonne réponse n'était pas ce modèle, alors j'ai demandé une réponse. Pour être précis, ce n'est pas un round-robin, j'ai donc essayé de ne pas faire d'erreur (n'ajoutez pas de 0 inutiles lors de la création de la formule). Après avoir créé la formule, il semble y avoir un moyen de supprimer 0 avec une expression régulière.

Commencez à cuisiner

Opérateurs de combinaison Créez un générateur qui est généré de manière récursive.

gen_sequence



a0=[["a","b"],["A","B","C"]]

def gen_sequence(a):
    for i in a[0]:
        if(len(a)>1):
            for j in gen_sequence(a[1:]):
                yield([i]+j)
        else:
            yield([i])

for x in gen_sequence(a0):
    print(x)

Résultat d'exécution


['a', 'A']
['a', 'B']
['a', 'C']
['b', 'A']
['b', 'B']
['b', 'C']

Générez une combinaison d'opérateurs avec gen_sequence et vérifiez si la condition est remplie par round-robin. Le processus de génération de la chaîne de caractères de la formule de M. K était assez délicat, je l'ai donc réécrit en un processus utilisant zip et en ai fait une fonction.

from itertools import zip_longest

op_list=[["","+","-","*","/"]]*3

def gen_sequence(a):
    for i in a[0]:
        if(len(a)>1):
            for j in gen_sequence(a[1:]):
                yield([i]+j)
        else:
            yield([i])

def build_formula(number_str, ops):
    formula = ""
    for num, op in zip_longest(number_str , ops, fillvalue=""):
        if len(formula)>1 and not formula[-2].isdigit() and formula[-1]=="0":
            #Supprimer le 0 immédiatement après l'opérateur
            formula = formula[:-1]
        formula += num + op
    return formula

def eval_string(string):
    try:
        return eval(string)
    except ZeroDivisionError:
        return -1
           
for i in range(1000,10000):
    number_str = str(i)
    number_str_rev = number_str[::-1]
    for op in gen_sequence(op_list):
        if op ==[""]*3:
            continue
        formula = build_formula(number_str, op)
        if str(eval_string(formula)) == number_str_rev:
            print(i , formula , "=" , number_str_rev)

J'ai essayé de générer une combinaison à tour de rôle sans utiliser de boucle. 2020/01/01 Changé en zip_longest ()

J'ai créé une fonction gen_sequence, mais itertools.product (* op_list) était équivalent à cela. Puisque le but est de créer cette fonction, je l'ai créée cette fois, mais si vous avez besoin de cette fonction, vous pouvez utiliser itertools.product.

Recommended Posts

La génération combinée des débutants Python (lycéens) était en diagonale au-dessus (génération combinée par traitement récursif)
J'ai essayé de refactoriser le code de Python débutant (lycéen)
Programmation débutant (lycéen) Optimiser l'algorithme créé
J'ai essayé de remodeler le code de Python débutant (lycéen) en crunchy orienté objet