Soy un principiante en programación y estoy buscando una buena idea sobre cómo generar tres números enteros que satisfagan una condición.
Ejemplo:
Nos dan n = 30 y nos piden que generemos tres enteros a, b y c, de modo que 7*a + 5*b + 3*c = n . Traté de usar bucles for , pero lleva demasiado tiempo y tengo un tiempo de prueba máximo de 1000 ms.
Estoy usando Python 3.
Mi intento:
x = int(input()) c = [] k = [] w = [] for i in range(x): for j in range(x): for h in range(x): if 7*i + 5*j + 3*h = x: c.append(i) k.append(j) w.append(h) if len(c) == len(k) == len(w) print(-1) else: print(str(k[0]) + ' ' + str(c[0]) + ' ' + str(w[0]))import numpy as np def generate_answer(n: int, low_limit:int, high_limit: int): while True: a = np.random.randint(low_limit, high_limit + 1, 1)[0] b = np.random.randint(low_limit, high_limit + 1, 1)[0] c = (n - 7 * a - 5 * b) / 3.0 if int(c) == c and low_limit <= c <= high_limit: break return a, b, int(c) if __name__ == "__main__": n = 30 ans = generate_answer(low_limit=-5, high_limit=50, n=n) assert ans[0] * 7 + ans[1] * 5 + ans[2] * 3 == n print(ans) Si selecciona dos de los números a, b, c, conoce el tercero. En este caso, aleatorizo enteros para a, b, y encuentro c por c = (n - 7 * a - 5 * b) / 3.0 .
Asegúrese de que c sea un número entero y esté dentro de los límites permitidos, y listo.
Si no es así, vuelve a aleatorizar.
Si quieres generar todas las posibilidades,
def generate_all_answers(n: int, low_limit:int, high_limit: int): results = [] for a in range(low_limit, high_limit + 1): for b in range(low_limit, high_limit + 1): c = (n - 7 * a - 5 * b) / 3.0 if int(c) == c and low_limit <= c <= high_limit: results.append((a, b, int(c))) return resultsSi se permiten bibliotecas de terceros, puede usar el solucionador de ecuaciones lineales de diofantina diophantine.diop_linear de SymPy:
from sympy.solvers.diophantine.diophantine import diop_linear from sympy import symbols from numpy.random import randint n = 30 N = 8 # Number of solutions needed # Unknowns a, b, c = symbols('a, b, c', integer=True) # Coefficients x, y, z = 7, 5, 3 # Parameters of parametric equation of solution t_0, t_1 = symbols('t_0, t_1', integer=True) solution = diop_linear(x * a + y * b + z * c - n) if not (None in solution): for s in range(N): # -10000 and 10000 (max and min for t_0 and t_1) t_sub = [(t_0, randint(-10000, 10000)), (t_1, randint(-10000, 10000))] a_val, b_val, c_val = map(lambda t : t.subs(t_sub), solution) print('Solution #%d' % (s + 1)) print('a =', a_val, ', b =', b_val, ', c =', c_val) else: print('no solutions')Salida (aleatoria):
Solution #1 a = -141 , b = -29187 , c = 48984 Solution #2 a = -8532 , b = -68757 , c = 134513 Solution #3 a = 5034 , b = 30729 , c = -62951 Solution #4 a = 7107 , b = 76638 , c = -144303 Solution #5 a = 4587 , b = 23721 , c = -50228 Solution #6 a = -9294 , b = -106269 , c = 198811 Solution #7 a = -1572 , b = -43224 , c = 75718 Solution #8 a = 4956 , b = 68097 , c = -125049Por qué su solución no puede hacer frente a grandes valores de n
Puede comprender que todo en un bucle for con un rango de i , se ejecutará i veces. Entonces multiplicará el tiempo que toma por i .
Por ejemplo, supongamos (para simplificar las cosas) que esto se ejecuta en 4 milisegundos:
if 7*a + 5*b + 3*c = n: c.append(a) k.append(b) w.append(c)entonces esto se ejecutará en 4 × n milisegundos:
for c in range(n): if 7*a + 5*b + 3*c = n: c.append(a) k.append(b) w.append(c)Aproximadamente:
Si coloca eso dentro de un bucle for en un rango de n , todo se repetirá n veces. Es decir
for b in range(n): for c in range(n): if 7*a + 5*b + 3*c = n: c.append(a) k.append(b) w.append(c)tomará 4n² milisegundos.
Ponerlo en un tercer ciclo for tomará 4n³ milisegundos.
Ahora, ¿qué pasa si reduce a la mitad el original if a 2 milisegundos? n podría aumentar en 15000 en el primer caso... y 23 en el último caso. La lección aquí es que un menor número de bucles for suele ser mucho más importante que acelerar lo que hay dentro de ellos. Como puede ver en la respuesta de Gulzar, parte 2, solo hay dos bucles for, lo que marca una gran diferencia. (Esto solo se aplica si los bucles están uno dentro del otro; si están uno tras otro, no tienes el problema de la multiplicación).
desde mi perspectiva, el último número de los tres nunca es un número aleatorio. digamos que primero genera a y b , luego c nunca es aleatorio porque debe calcularse a partir de la ecuación
n = 7*a + 5*b + 3*c c = (7*a + 5*b - n) / -3 esto significa que necesitamos generar dos valores aleatorios (a,b) que 7*a + 5*b - n es divisible por 3
import random n = 30; max = 1000000; min = -1000000; while True: a = random.randint(min , max); b = random.randint(min , max); t = (7*a) + (5*b) - n; if (t % 3 == 0) : break; c = (t/-3); print("A = " + str(a)); print("B = " + str(b)); print("C = " + str(c)); print("7A + 5B + 3C =>") print("(7 * " + str(a) + ") + (5 * " + str(b) + ") + (3 * " + str(c) + ") = ") print((7*a) + (5*b) + (3*c));