Як ефективно знайти елемент послідовності цифр?


20

Тільки з інтересу я спробував вирішити проблему з категорії «Останні» проекту Euler ( послідовність цифр суми ). Але я не в змозі придумати спосіб ефективного вирішення проблеми. Проблема полягає в наступному (у початковій послідовності питань на початку є два, але послідовність не змінюється):

Послідовність суми цифр дорівнює 1,2,4,8,16,23,28,38,49 .... де додаток послідовності є сумою цифр, що передують їй у послідовності. Знайдіть член послідовності.nth1015th

Наївне рішення неможливо реалізувати, оскільки це займає багато часу. Я намагався звести цю проблему до випадку експозиції матриці (це зайняло б кількість часу ), але не міг придумати такого рецидиву, що відповідає лінійним критеріям, як повторення для цієї послідовності досить своєрідний. Видно, що послідовність регулюється рецидивом:O(log(1015))

an=an1+d(an1).....(1)

де - n ^ {th} додаток послідовності, а d - функція, яка при введенні натурального числа як введення повертає суму цифр числа (наприклад, \; d (786) = 21 ). Мій другий підхід полягав у тому, щоб спробувати знайти деякий зразок у послідовності. Видно, що перші кілька членів послідовності можна записати якn t h dannthdd(786)=21

   a_1 = 1  
   a_2 = 1 + d( 1 )
   a_3 = 1 + d( 1 ) + d( 1 + d( 1 ) )
   a_4 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) )
   a_5 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) + d( 1 +  d(  
   1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) )

З наведеної вище схеми стає зрозуміло, що нтгод член послідовності може бути сформований наступним методом:

  1. Запишіть 12н-1 1 'з символом додавання між ними.
  2. Залишивши перший 1 , потім застосуйте функцію г на наступних 20 умовах, потім на наступних 21 умовах, потім на наступних 22 доданках тощо.
  3. Потім застосовуйте описаний вище метод рекурсивно на аргументах кожної застосованої функції г .

наприклад, якщо n = 3, ми виконуємо такі маніпуляції:

    1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
    1 + d( 1 ) + d( 1 + 1 ) + d( 1 + 1 + 1 + 1 )
    1 + d( 1 ) + d( 1 + d(1) ) + d( 1 + d( 1 ) + d( 1 +d( 1 ) ) )

За допомогою динамічного програмування я можу генерувати термін, використовуючи вищезазначений метод за часом , що знову ж таки не є кращим за наївне рішення.нтгодО(лог(21015))

EDIT 1
Ще одне, що можна спостерігати, це те, що . Наприклад, . Але я не в змозі скористатися цим пунктом. Я знову спробував знайти лінійне відношення рецидиву (для матричної експоненції), але не можу його знайти.d(an)=d(2n1)d(a6)=d(23)=d(32)=5

EDIT 2

Далі наводиться графік, коли послідовність побудована для меншого діапазону (спочатку наводяться членів послідовності). 106введіть тут опис зображення

PS: Я знаю, що недоцільно запитувати рішення у Project Euler. Але я просто хочу нового напрямку чи підказки, оскільки я рухаюся по колах останні кілька днів. Якщо це теж неприйнятно, я можу зняти питання, якщо це буде запропоновано.


1
Я відчуваю, що You are given a106 = 31054319.в оригінальній проблемі Ейлера є натяк.
Філіп Хаглунд

@FilipHaglund - це не натяк. Оскільки по грубій силі я можу легко обчислити це значення. Це лише для перевірки вашого підходу.
саша

3
Також на OEIS: oeis.org/A004207 .
Yuval Filmus

@EvilJS міг, так, я побудував графік в розширенні, він поступово збільшується в режимі зигзагу. Не могли б ви розробити свій останній пункт "" шаблонів кешування .. "
sashas

З огляду на те, що цікаві зразки з'являються мод 9, чи трапляється щось цікаве, якщо ми подивимось на послідовність моди 11 чи моди 99? Значення mod 11 може бути отримане з суми непарних індексованих цифр і суми парних індексованих цифр. Значення mod 99 може бути отримане з суми суміжних пар чисел.
DW

Відповіді:


4

Ваша послідовність описана в oeis.org/A004207 як сума цифр. Є кілька хороших моментів, як послідовність моди 9 має повторюваний малюнок , вона ділиться цифровими коренями з oeis.org/A065075 та oeis.org/A001370 . Якщо ці властивості корисні - це відкрита проблема (оскільки для n - t h чисел немає рівняння закритої форми ).(1,2,4,8,7,5)nth

Є кілька властивостей цієї послідовності, які варто згадати:
Коли ви обчислюєте число, вам потрібно зберігати лише лічильник (щоб знати, яке це число) та саме число. Для перезапуску більше нічого не потрібно, оскільки наступне число - це поточне число + сума його цифр.nth

Роблячи кілька кроків для забезпечення швидкості спочатку, добре класти числа в масив, уникаючи наївних розрахунків моди та діва, які дорого коштують. Це дає швидкість постійною, але дивлячись на час це має значення.

З початкової точки ви можете обчислити наступну та наступну, і вона працює до деякого моменту, саме ця точка є числом змін цифр.
Що важливіше, закономірності змінюються зі збільшенням чисельності.
Суми цифр невеликі порівняно з самими числами, тому на більшості операцій зміниться лише частина числа.
То що насправді ми можемо кешувати?

Ми знаємо, що з двома числами з однаковою сумою цифр додавання для отримання наступного числа буде однаковим. Що з наступним?

саша

Попередження спойлера, внизу, є досить явною схемою кешу

Це залежить від додаткових умов, як числа , які не змінюються в перспективі , я буду називати його зміщення , починаючи з суми в якості початку .

10009100nth

100
1001

10



1,2,4,8

11012183054065176077198059041003



100,1000,10000,100000,1000000...
100


4

Оскільки ви попросили "новий напрямок чи підказку", і я не знаю відповіді, я залишу це тут, сподіваюся, це корисно. кілька ідей:

Має сенс, що існувала б модель 9, оскільки

k>1,kZ10k1mod9

Що ви можете довести індукцією.

Це означає, що всі числа узгоджуються з сумою їхніх цифр mod 9.

an=d(an)mod9

an=an1+d(an1)=2d(an1)mod9

Якщо ми продовжуватимемо розширювати цей рецидив, який ми отримуємо

an=2nmod9

Що пояснює шаблон мод 9.

an=9k+2n

Ось дещо менше загального коду:

import matplotlib.pyplot as plt
import numpy as np

#sum digits of n
def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

#get the sequence to n digits
def calculate(n):
    retval = [1]
    for i in range(n):
        retval.append(retval[-1] + sum_digits(retval[-1]))
    return retval;

#empirically confirm that a_n = 2^n mod 9
def confirmPow2(a):
    count = 0
    for i in a[:10000]:
        if((i%9) != (2**count % 9)):
            print "false"
        count = count + 1

#find gaps divisible by 9 in a subset of a
def find9Gaps(a):
    count = 0
    S = []
    for i in a[:10000]:
         S.append(((2**count ) - i)/9)
         count = count + 1
    return S

#repeatedly sum the digits until they're less than 9...
#gives some interesting patterns
def repeatedDigitSum():
    for i in range(1000, 1100):
         print "=========for ",i
         while i > 9:
                 i = sum_digits(i)
                 print i 


a = calculate(10**6)
b = find9Gaps(a)
plt.plot(range(len(b[:100])), b[:100])
plt.show()

Сюжет (для перших 100) виглядає експоненційно, але я не думаю, що це ідеально.

сюжет для прогалин

Ось результат

>>> plt.plot(range(len(b[5:60])), np.log2(np.array(b[5:60])))
>>> plt.show()

логарифмічний сюжет прогалин

Останнє, що в мене є, - це здається, якщо ви підсумуєте цифри числа, а потім підсумовуєте цифри отриманого числа і повторюєте це, ви з часом отримаєте це число mod 9.

Має сенс враховувати вищезазначений факт про потужність 10 мод 9.

nd(n)d(d(n))mod9

Це дає цікаву послідовність чисел.

Редагувати: Мабуть, це називається "цифровий корінь".


1
Це якось коментували щонайменше три рази. Крім того, коли ви робите сюжет, який виглядає для вас експоненціальним, можливо, вам слід скористатися логарифмом, повідомити про це на осі шкали? Якби ви побудували читати 10 ^ 16 термінів, я був би дуже вражений.
Зло

Що коментували 3 рази? Люди казали, що існує "модель мод 9", але я відчував, що не зрозуміло, що це. Я просто проаналізував і прокоментував те, що мав, оскільки не думаю, що мені вдасться продовжувати роботу над цим. Знову ж таки, у мене немає рішення, але питання не було на нього.
тихийконкурс

Додано сюжет журналу за пропозицією EvilJS, не можна створити більше, тому що нуд розривається, і я дійсно не
встигаю
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.