Làm thế nào để tìm phần tử của chuỗi Digit Sum một cách hiệu quả?


20

Chỉ cần quan tâm, tôi đã cố gắng giải quyết vấn đề từ danh mục "Gần đây" của Project Euler ( chuỗi Digit Sum ). Nhưng tôi không thể nghĩ ra cách giải quyết vấn đề hiệu quả. Vấn đề như sau (trong chuỗi câu hỏi ban đầu có hai câu hỏi bắt đầu, nhưng nó không thay đổi trình tự):

Chuỗi Digit Sum là 1,2,4,8,16,23,28,38,49 .... trong đó số hạng của chuỗi là tổng các chữ số đứng trước nó trong chuỗi. Tìm số hạng của chuỗi. 10 15 t hnth1015th

Giải pháp ngây thơ không thể được thực hiện bởi vì nó tốn rất nhiều thời gian. Tôi đã cố gắng giảm vấn đề thành một trường hợp lũy thừa ma trận (sẽ mất thời gian ) nhưng không thể đưa ra một sự lặp lại như vậy phù hợp với tiêu chí tuyến tính vì sự tái phát cho chuỗi này là khá kỳ dị. Có thể thấy rằng trình tự bị chi phối bởi sự tái diễn:O(log(1015))

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

trong đó là hạn của dãy và là một hàm mà khi được cho một số tự nhiên là đầu vào trả về tổng các chữ số của số đó (ví dụ: ). Cách tiếp cận thứ hai của tôi là cố gắng tìm một số mẫu trong chuỗi. Có thể thấy rằng một vài thuật ngữ đầu tiên của chuỗi có thể được viết làannthdd(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 ) ) ) )

Từ mẫu ở trên, có thể tạo ra thuật ngữ của chuỗi theo phương pháp sau:nth

  1. Viết 'với ký hiệu cộng giữa chúng.2n1 1
  2. Rời khỏi đầu tiên , sau đó áp dụng hàm cho các điều khoản tiếp theo sau đó cho các điều khoản theo, sau đó vào các điều khoản theo, v.v.1d202122
  3. Sau đó áp dụng phương pháp trên một cách đệ quy trên các đối số của từng hàm được áp dụng.d

ví dụ: nếu n = 3 chúng ta thực hiện các thao tác sau:

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

Bằng lập trình động, tôi có thể tạo ra thuật ngữ bằng cách sử dụng phương thức trên trong thời gian , một lần nữa không tốt hơn giải pháp ngây thơ. O ( l o g ( 2 10 15 ) )nthO(log(21015))

EDIT 1
Một điều khác có thể được quan sát là . Ví dụ . Nhưng tôi không thể sử dụng điểm này. Tôi một lần nữa cố gắng tìm một mối quan hệ tái phát tuyến tính (đối với lũy thừa ma trận), nhưng tôi không thể tìm thấy nó.d ( a 6 ) = d ( 23 ) = d ( 32 ) = 5d(an)=d(2n1)d(a6)=d(23)=d(32)=5

CHỈNH SỬA 2

Dưới đây là biểu đồ khi chuỗi được vẽ cho phạm vi nhỏ hơn ( điều khoản đầu tiên của chuỗi được vẽ). 106nhập mô tả hình ảnh ở đây

PS: Tôi biết không nên hỏi các giải pháp từ Project Euler. Nhưng tôi chỉ muốn một hướng đi mới hoặc một gợi ý, vì tôi đã di chuyển trong vòng tròn trong vài ngày qua. Nếu điều đó cũng không được chấp nhận, tôi có thể xóa câu hỏi nếu được đề xuất.


1
Tôi cảm thấy như You are given a106 = 31054319.trong vấn đề Euler ban đầu là một gợi ý.
Filip Haglund

@FilipHaglund đó không phải là một gợi ý. Chỉ bằng sức mạnh vũ phu, tôi có thể tính toán giá trị đó một cách dễ dàng. Nó chỉ là để kiểm tra cách tiếp cận của bạn.
sashas

3
Ngoài ra trên OEIS: oeis.org/A004207 .
Yuval Filmus

@EvilJS có thể tôi đã vẽ đồ thị để mở rộng nó tăng dần theo kiểu zig zag. Bạn có thể giải thích điểm cuối cùng của bạn "" các mẫu bộ nhớ đệm .. ".
sashas

Cho rằng các mẫu thú vị xuất hiện mod 9, có điều gì thú vị xảy ra nếu chúng ta nhìn vào trình tự mod 11 hoặc mod 99 không? Giá trị mod 11 có thể được lấy từ tổng các chữ số có chỉ số lẻ và tổng của các chữ số được lập chỉ mục chẵn. Giá trị mod 99 có thể được lấy từ tổng các cặp chữ số liền kề.
DW

Câu trả lời:


4

Trình tự của bạn được mô tả trong oeis.org/A004207 dưới dạng tổng các chữ số. Có một số điểm tốt như trình tự mod 9 có mẫu lặp lại , nó chia sẻ các gốc kỹ thuật số với oeis.org/A065075oeis.org/A001370 . Nếu các tính chất này hữu ích là bài toán mở (vì không có phương trình dạng đóng cho số ). n - t h(1,2,4,8,7,5)nth

Có một số thuộc tính của chuỗi này đáng được đề cập:
Khi bạn tính số , bạn chỉ cần lưu trữ bộ đếm (để biết đó là số nào) và chính số đó. Để khởi động lại, không có gì cần thiết hơn, vì số tiếp theo là số hiện tại + tổng các chữ số của nó.nth

Thực hiện một số bước để đảm bảo tốc độ lúc đầu, tốt nhất là đặt số vào mảng, tránh các phép tính mod và div ngây thơ, rất tốn kém. Điều này cho phép tăng tốc liên tục, nhưng nhìn vào những thời điểm nó có vấn đề.

Từ điểm bắt đầu, bạn có thể tính toán tiếp theo và tiếp theo, và nó hoạt động đến một số điểm, chính điểm này là số chữ số thay đổi.
Điều quan trọng hơn, các mô hình đang thay đổi với sự gia tăng số lượng.
Tổng các chữ số là nhỏ so với chính số, vì vậy chỉ một phần của số sẽ thay đổi trên hầu hết các hoạt động.
Vì vậy, những gì thực sự chúng ta có thể bộ nhớ cache?

Chúng ta biết rằng với hai số có cùng một chữ số, phép cộng để có được số tiếp theo sẽ giống nhau. Còn cái tiếp theo thì sao?

Sasha

Spoiler alert, bên dưới là mẫu bộ nhớ cache khá rõ ràng

Nó phụ thuộc vào các điều kiện bổ sung, như các số không thay đổi trong quá trình chạy , tôi sẽ gọi nó là thay đổi , số tiền bắt đầubắt đầu .

10009100nth

100
1001

10



1,2,4,8

11012183054065176077198059041003

Chúng tôi có thể tiếp tục cho đến khi thay đổi cao hơn so với tính toán.
Đi xa hơn, chúng ta có thể xây dựng nhiều lần chạy hơn , tính toán trước các lần chạy lớn hơn hoặc quan sát các mẫu khác (như chúng ta có thể sử dụng một phần các bảng tái sử dụng đã được tính toán).
Hãy nhìn vào khác nhau thay đổi như tất cả họ đều đưa ra cùng chạy là môi trường tương tự cho tiền con số, do đó chúng ta có thể sử dụng các bảng rất tương tự. Làm cho các bảng lớn hơn phần tử tăng tốc quá trình hơn nữa, thực hiện các bước nhảy lớn hơn cùng một lúc.100,1000,10000,100000,1000000...
100


4

Vì bạn đã hỏi "một hướng đi mới hoặc một gợi ý" và tôi không biết câu trả lời, tôi sẽ để nó ở đây, tôi hy vọng nó hữu ích. một vài ý tưởng:

Nó có ý nghĩa sẽ có một mô hình mod 9, kể từ khi

k>1,kZ10k1mod9

Mà bạn có thể chứng minh bằng cảm ứng.

Điều này có nghĩa là tất cả các số đều đồng dạng với tổng các chữ số mod 9 của chúng.

Hơn nữa, an=d(an)mod9

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

Nếu chúng ta tiếp tục mở rộng sự tái phát này, chúng ta sẽ nhận được

an=2nmod9

Điều này giải thích mô hình mod 9.

Nó cũng được chúng tôi . Mỗi lần lặp chúng ta có một khoảng cách chia hết cho 9. Những khoảng trống đó rộng bao nhiêu?an=9k+2n

Đây là một số ít hơn mã chung:

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

Cốt truyện (cho 100 người đầu tiên) có vẻ theo cấp số nhân, nhưng tôi không nghĩ nó hoàn hảo.

âm mưu cho những khoảng trống

Đây là đầu ra của

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

cốt truyện logarit của các khoảng trống

Điều cuối cùng tôi có là dường như nếu bạn tính tổng các chữ số của một số, sau đó tổng các chữ số của số kết quả và lặp lại điều này, cuối cùng bạn sẽ có được số đó mod 9.

Làm cho ý nghĩa đưa ra thực tế trên về sức mạnh của 10 mod 9.

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

Nó đưa ra một chuỗi số thú vị mặc dù.

Chỉnh sửa: Rõ ràng đây được gọi là "gốc kỹ thuật số".


1
Nó đã được bình luận ít nhất ba lần. Ngoài ra khi bạn thực hiện cốt truyện có vẻ theo cấp số nhân, có lẽ bạn nên sử dụng logarit, thông báo về nó trên trục tỷ lệ? Nếu bạn vẽ 10 ^ 16 điều khoản có thể đọc được, tôi sẽ thực sự ấn tượng.
Ác

Điều gì đã được bình luận 3 lần? Mọi người đang nói rằng có một "mẫu mod 9" nhưng tôi cảm thấy như nó không rõ đó là gì. Tôi vừa thực hiện một số khám phá và nhận xét những gì tôi có, vì tôi không nghĩ rằng tôi sẽ có thể tiếp tục làm việc này. Một lần nữa, tôi không có giải pháp, nhưng câu hỏi không yêu cầu.
quietContest

Đã thêm một biểu đồ nhật ký cho mỗi đề xuất của EvilJS, không thể vẽ bất kỳ biểu đồ nào lớn hơn bởi vì giờ nghỉ giải lao và tôi thực sự không có thời gian để tiếp tục theo đuổi vấn đề này
quietContest
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.