Digit Sum dizisinin elemanını verimli bir şekilde nasıl bulabilirim?


20

Sadece ilgi dışında Project Euler ( Digit Sum dizisi ) "Recent" kategorisinden bir sorunu çözmeye çalıştım . Ancak sorunu etkili bir şekilde çözmenin bir yolunu düşünemiyorum. Sorun aşağıdaki gibidir (orijinal soru dizisinde başlangıçta iki sorun vardır, ancak diziyi değiştirmez):

Burada Rakam Miktar sekansı .... 1,2,4,8,16,23,28,38,49 olan nth dizisinin terimi toplamı basamak dizisi içinde önceki. Dizinin 1015th terimini bulun .

Saf çözüm uygulanamaz çünkü çok zaman alır. Sorunu bir matris üssü vakasına indirmeye çalıştım (bu O(log(1015)) zaman alır), ancak bu sekans için rekürrens oldukça uygun olduğu için doğrusal kriterlere uyan böyle bir tekrarlama bulamadım tuhaf. Sekansın nüksetme tarafından yönetildiği görülebilir:

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

burada olup , n t h dizisinin süreli ve d (örneğin sayının rakamlarının giriş döner toplamı olarak doğal bir numara verilir bir fonksiyonudur.annthd ). İkinci yaklaşımım dizide bir örüntü bulmaya çalışmaktı. Dizinin ilk birkaç teriminin şu şekilde yazılabileceği görülebilir:d(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 ) ) ) )

Yukarıdaki modelden , dizinin terimi aşağıdaki yöntemle üretilebilecektir:nth

  1. Aralarına ek sembol ile 1 yazın .2n1 1
  2. İlk çıktıktan sonra d işlevini sonraki 2 0 terimine, ardından sonraki 2 1 terimine, ardından sonraki 2 2 terimine uygulayın.1d202122
  3. Ardından, uygulanan her işlevinin bağımsız değişkenlerine yukarıdaki yöntemi yinelemeli olarak uygulayın.d

örneğin n = 3 ise aşağıdaki manipülasyonları gerçekleştiririz:

    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 ) ) )

Dinamik programlama ile , tekrar saf çözeltiden daha iyi olmayan O ( l o g ( 2 10 15 ) ) zamanında yukarıdaki yöntemi kullanarak terimini üretebilirim.nthO(log(21015))

DÜZENLEME 1
Gözlemlenebilecek başka bir şey de . Örneğin d ( a 6 ) = d ( 23 ) = d ( 32 ) = 5 . Ama bu noktadan yararlanamıyorum. Yine (matris üssü için) doğrusal bir yineleme ilişkisi bulmaya çalıştım, ama bulamıyorum.d(an)=d(2n1)d(a6)=d(23)=d(32)=5

DÜZENLEME 2

Sekansı, daha küçük bir aralığı için çizilmiştir grafiktir aşağıda (ilk dizisinin koşulları çizilmiştir). 106resim açıklamasını buraya girin

Not: Project Euler'den çözüm istemenin tavsiye edilmediğini biliyorum. Ama son birkaç gündür daireler çizdiğim için sadece yeni bir yön veya ipucu istiyorum. Bu da kabul edilemez durumdaysa, soruyu kaldırabilirim.


1
You are given a106 = 31054319.Orijinal Euler probleminde bir ipucu olduğunu hissediyorum .
Filip Haglund

@FilipHaglund bu bir ipucu değil. Sadece kaba kuvvet tarafından olduğu gibi bu değeri kolayca hesaplayabilirim. Sadece yaklaşımınızı kontrol etmek içindir.
sashas


@EvilJS evet ben grafik yavaş yavaş zig zag tarzında artar uzatmak için çizdi. Son noktanızı "" önbellek kalıpları .. "olarak detaylandırabilir misiniz.
sashas

İlginç modellerin mod 9'da göründüğü göz önüne alındığında, mod 11 veya mod 99 dizisine bakarsak ilginç bir şey olur mu? Mod 11 değeri, tek indeksli rakamların toplamından ve çift indeksli rakamların toplamından türetilebilir. Mod 99 değeri, bitişik basamak çiftlerinin toplamından türetilebilir.
DW

Yanıtlar:


4

Sıralamanız oeis.org/A004207'de rakam toplamı olarak açıklanmıştır . Dizi mod 9'un yinelenen paterni gibi bazı iyi noktalar vardır , oeis.org/A065075 ve oeis.org/A001370 ile dijital kökleri paylaşır . Bu özellikler yararlıysa açık problemdir ( n - t h sayısı için kapalı form denklemi olmadığından ).(1,2,4,8,7,5)nth

Bu dizinin bahsetmeye değer bazı özellikleri vardır: n - t h sayısını
hesaplarken , sadece sayacı (hangi numaranın olduğunu bilmek için) ve numaranın kendisini saklamanız gerekir. Yeniden başlatmak için daha fazla bir şey gerekmez, çünkü bir sonraki sayı geçerli sayı + rakamlarının toplamıdır.nth

İlk başta hızı sağlamak için bazı adımlar atmak, sayıları diziye koymak, pahalı olan naif mod ve div hesaplamalarından kaçınmak iyidir. Bu sürekli hızlanma sağlar, ancak bazen bakmak önemlidir.

Başlangıç ​​noktasından bir sonrakini ve bir sonrakini hesaplayabilirsiniz ve bir noktaya kadar çalışır, bu nokta basamak değişimidir.
Daha da önemlisi, sayılar arttıkça desenler değişiyor.
Rakam toplamları sayıların kendisiyle karşılaştırıldığında küçüktür, bu nedenle çoğu işlemde sayının sadece bir kısmı değişecektir.
Peki gerçekten ne önbellekleyebiliriz?

Aynı rakamlara sahip iki sayıyla bir sonraki sayıyı elde etmenin eklenmesinin aynı olacağını biliyoruz. Sırada ne var?

sasha

Spoiler uyarısı, aşağıda oldukça açık bir önbellek kalıbı

Bu değişmez numaraları gibi, ek şartlara bağlıdır vadede , bunu arayacak vardiya olarak miktarını başlayarak baştan .

Bazı keyfi alarak çalıştırmak gibi ve çekici bir başlangıç gelen 0'a kadar 9'a biz kadar başlangıç noktası her desen önbelleğe alabilir 100 , bazı vermek için gerekli olan sayaç, nasıl başa bilmek elemanların sayısını (saymak n - t h numara) ve ezberleyin. 10009100nth

Tamam. Şimdiye kadar herhangi bir başlangıç kapsam dahilinde ne değişiyor ? Eğer gelen çalışırsanız Maalesef bu desenler, durmasına 100 vermede başlatmak eşit 1 , sonraki numaralı sonları mükemmel hesaplanmış, ancak ikinci edilir. 100
1001

10



1,2,4,8

11012183054065176077198059041003



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


4

"Yeni bir yön ya da bir ipucu" istediğinden ve cevabı bilmediğimden, bunu burada bırakacağım, umarım faydalı olur. bazı fikirler:

Bir model mod 9 olması mantıklı, çünkü

k>1,kZ10k1mod9

Hangi indüksiyon ile kanıtlayabilirsiniz.

Bu, tüm sayıların, mod 9 rakamlarının toplamına uygun olduğu anlamına gelir.

an=d(an)mod9

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

Bu nüksü genişletmeye devam edersek,

an=2nmod9

Hangi desen modunu açıklar 9.

an=9k+2n

İşte genel koddan daha az:

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()

Arsa (ilk 100 için) üstel görünüyor, ama mükemmel olduğunu sanmıyorum.

boşluklar çizmek

İşte çıktı

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

boşlukların logaritmik grafiği

Sahip olduğum son şey, bir sayının rakamlarını toplarsanız ve sonra ortaya çıkan sayının rakamlarını toplarsanız ve bunu tekrarlarsanız, nihayetinde bu sayı mod 9'u alırsınız.

10 mod 9'un güçleri hakkında yukarıdaki gerçek göz önüne alındığında mantıklıdır.

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

Yine de ilginç bir sayı dizisi verir.

Düzenleme: Görünüşe göre bu "dijital kök" denir.


1
En az üç kez yorumlandı. Ayrıca size üstel görünen bir arsa yaptığınızda, belki logaritma kullanmalı, ölçek ekseni hakkında bilgi vermelisiniz? Okunabilir 10 ^ 16 terimler çizseydiniz gerçekten çok etkilendim.
Kötülük

3 kez ne yorum yapıldı? İnsanlar bir "model mod 9" olduğunu söylüyorlardı ama bunun ne olduğunu net değil gibi hissettim. Biraz araştırdım ve ne yaptığımı yorumladım, çünkü bunun üzerinde çalışmaya devam edebileceğimi sanmıyorum. Yine, bir çözümüm yok, ama soru bir tane sormadı.
quietContest

EvilJS önerisi başına bir günlük arsa eklendi, daha büyük arsa olamaz çünkü numpy molaları ve gerçekten bu sorunu takip etmeye devam etmek için zamanım yok
quietContest
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.