Странный вывод при поиске суммы факториала цифр в наименьшем числе == заданное число

#python #algorithm

#питон #алгоритм #python

Вопрос:

 #Function factorial
def fact(d):
  f=1
  for i in range(d,0,-1):
    f=f*i
  print(f"factorial {f}")
  return f

#Function for summation of factorial of digits
def f(n):
  s=0
  d=n%10
  s=fact(d) s
  n=int(n/10)
  print(f"summing {s}")
  return s

l=[]
q=int(input("enter number of queries"))
print(q) 
n=int(input("enter the number to which you want to calculate"))
m=int(input("enter range"))
for i in range(1,n 1):
   l.append(i) #adding elements from 1 to n in list
   print(l[i-1])
   for j in range(1,m 1): 
    p=f(j) 
    if(l[i-1]==p):#element in list is equal to function (i.e sum of factorial of digits)
      l[i-1]=p #then assign p to list
      print(f"list {l[i-1]}")
      break  #then break the second loop
  
  

Например, для:
Для запроса 1
n = 3 и m = 100

До 1 до n
ищите в m числа, сумма факториалов цифр которых равна числу в n

Например : 5 = 25 (как 2! 5! = 2 120 = 122 1 2 2=5)

Затем сделайте перерыв для следующей итерации i, но я не знаю, где я совершаю ошибку.

Комментарии:

1. Пожалуйста, добавьте комментарии в свой код.

2. например: для запроса 1 n = 3 и m = 100 в первом цикле i = 1, затем 2-й цикл выполняется до m = 100 1 = 1 (1!) разрыв второго цикла i = 2, затем 2-й цикл выполняется до m=100 2=1 (1!) 2=2(2!) затем прервите второй цикл i = 3, затем цикл выполняется до m=100 3=1 3=2 3=3 … 3=12 ( как ( 1! 2!)=3) затем прервите второй цикл

3. Нет, минимум нет. как 12= 1! 2!=3 , 25=2! 5!=2 120=122=1 2 2= 5 итак, 12 = 3 и 25 = 5 — это то, чего я хочу

4. Проверьте мой комментарий, например, на минимальное число, сумма факториала цифр которого

5. Да, это диапазон

Ответ №1:

Цель: найти наименьшее x такое, чтобы сумма цифр факториалов цифр x была n равна.

Пример поведения:

 Find the smallest x such that:
    the sum of digits of the factorials of the digits of x is n
Please provide n: 12
Please provide the maximal x to check: 10000
Trying 1:
    Sum of the digits of factorials of the digits of 1 is:
        digit_sum(1!)
        = digit_sum(1)
        = 1
...
Trying 4:
    Sum of the digits of factorials of the digits of 4 is:
        digit_sum(4!)
        = digit_sum(24)
        = 6
...
Trying 16:
    Sum of the digits of factorials of the digits of 16 is:
        digit_sum(1!)   digit_sum(6!)
        = digit_sum(1)   digit_sum(720)
        = 10
...
Trying 33:
    Sum of the digits of factorials of the digits of 33 is:
        digit_sum(3!)   digit_sum(3!)
        = digit_sum(6)   digit_sum(6)
        = 12
x is 33.
  

Исходный код:

 import math


def print_sum_eq(x):
    print(f"    Sum of digits of the factorials of the digits of {x} is:")
    msg1 = [f"digit_sum({d}!)" for d in str(x)]
    print("        "   "   ".join(msg1))
    msg2 = [f"digit_sum({math.factorial(int(d))})" for d in str(x)]
    fact_values_str = "   ".join(msg2)
    print(f"        = {fact_values_str}")


def digit_sum(x):
    return sum(int(d) for d in str(x))


def sum_fact_digit(x):
    """Calculate sum of factorials of the digits of x

    For example, when x = 25, the digits are 2 and 5. The sum of the
    factorials of the digits is 2!   5! = 2   120 = 122.

    Parameters
    ----------
    x : int

    Returns
    -------
    digit_sum : int
        Sum of the factorials of the digits of x
    """
    s = 0
    print_sum_eq(x)

    # Loop over the digits of x
    for d in str(x):
        digit = int(d)
        digit_fact = math.factorial(digit)
        s  = digit_sum(digit_fact)

    print(f"        = {s}")
    return s


def search(n, max_x=None):
    """Try to find x such that sum of factorials of the digits of x is n

    Parameters
    ----------
    n : int
    max_x : int, optional
        The function will search over x = 1, 2, ..., max_x

    Returns
    -------
    result : int or None
        If we find x, the result is x.
        If we can't find x, the result is None.
    """
    if max_x is None:
        max_x = int(10 ** n)
    for x in range(1, max_x   1):
        print(f"Trying {x}:")
        sum = sum_fact_digit(x)
        if sum == n:
            return x
    return None


def main():
    print("Find the smallest x such that:")
    print("    the sum of digits of the factorials of the digits of x is n")
    n = int(input("Please provide n: "))
    max_x = int(input("Please provide the maximal x to check: "))
    x = search(n, max_x=max_x)
    if x is None:
        print("Cannot find such a x.")
    else:
        print(f"x is {x}.")


main()

  

Комментарии:

1. Это можно сделать намного, намного быстрее. Удачи в вашем подходе, обнаружив, что ответ на 319 равен 1336999999999999.

2. @btilly: попытка угадать, чего на самом деле хочет op, заняла слишком много времени 🙂 Как бы вы сделали это быстрее? Решение задач целочисленного программирования обычно требует использования hueristic, что не гарантирует нахождения оптимального ответа. Мне было бы очень интересно узнать ваш подход.

3. Вы можете использовать динамическое программирование. Мы знаем, что маленькие цифры будут предшествовать большим, и мы хотим использовать как можно меньше цифр. Это означает, что мы можем использовать поиск в ширину, чтобы создать dict last_digit_in_sum последнего члена в кратчайшей сумме (суммы цифр факториалов), которая соответствует любому конкретному числу. А затем просто пройдите назад по этой структуре данных из вашего целевого номера, чтобы получить цифры.

4. Как обрезать дерево поиска? Каждый узел имеет одну ветвь для каждой из 10 цифр. Это динамическое программирование на 10-мерной сетке.

5. Это простой поиск по ширине, и вы добавляете число в todo список только тогда, когда ничто другое не достигло его первым. Это автоматически запускает его.