Trường hợp chạy trong chuỗi vô hạn này? (Đã tìm thấy CCCCCC!)


25

Bắt đầu với chuỗi ABC, hãy xem xét kết quả của việc liên tục nối nửa cuối của chính nó với chính nó (sử dụng nửa lớn hơn nếu độ dài là số lẻ).

Chúng tôi có được sự tiến bộ:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Hãy Sbiểu diễn chuỗi vô hạn (hoặc chuỗi) kết quả mà thủ tục này được lặp lại mãi mãi.

Mục tiêu

Mục tiêu trong thách thức mã này là để tìm thấy những chỉ số về sự xuất hiện đầu tiên của chạy của C's trong S.

Lúc đầu thật dễ dàng: Clần đầu tiên xảy ra tại chỉ mục 2, CCtại 4, CCCtại 7, CCCCtại 26, nhưng CCCCClà tất cả các cách tại chỉ mục 27308! Sau đó, trí nhớ của tôi hết.

Người chiến thắng sẽ là người gửi chính xác tạo ra nhiều chỉ số chạy nhất (theo thứ tự, bắt đầu từ C). Bạn có thể sử dụng bất kỳ loại thuật toán nào nhưng hãy chắc chắn giải thích nó nếu bạn không sử dụng vũ lực cơ bản. Đầu vào và đầu ra có thể ở bất kỳ định dạng dễ hiểu.

Lưu ý quan trọng: Tôi không chính thức biết liệu Sthực sự có chứa tất cả các lần chạy hay không C. Câu hỏi này được bắt nguồn từ câu hỏi này trên Sàn giao dịch toán học , trong đó tác giả chưa tìm thấy CCCCCC. Tôi tò mò nếu có ai ở đây có thể. (Câu hỏi đó lần lượt dựa trên câu hỏi ban đầu của tôi về chủ đề này .)

Nếu bạn có thể chứng minh rằng không phải tất cả các lần chạy Cxảy ra Sthì bạn sẽ thắng tự động vì câu hỏi này sẽ không còn hiệu lực. Nếu không ai có thể chứng minh rằng cũng không tìm thấy CCCCCCthì người chiến thắng sẽ là người có thể bị ràng buộc thấp nhất cao nhất về chỉ số CCCCCC(hoặc bất cứ điều gì lớn nhất chưa được giải quyết nếu CCCCCCđược tìm thấy).

Cập nhật: thanh danh Humongous để isaacgres người đã tìm thấy CCCCCCở các chỉ số thiên văn của 2,124 * 10 ^ 519. Với tốc độ này, tôi không thể tưởng tượng được việc tìm kiếm CCCCCCCbằng bất kỳ phương pháp nào dựa vào lực lượng vũ phu. Làm tốt lắm các bạn!


Tôi không hiểu điều đó - Bạn đang nói rằng bạn đã tìm thấy CCCCCở chỉ số 27308, nhưng sau đó có vẻ như bạn không biết nó xảy ra ở đâu. Ý bạn là CCCCCCsao
isaacg

@isaacg Rất tiếc. 6 C là một thứ khó tìm. Tôi sẽ sửa nó.
Sở thích của Calvin

Nếu phỏng đoán sai, có một N mà c ^ N là lần chạy dài nhất. Tôi khá chắc chắn rằng có thể xây dựng một chuỗi dài hơn, dẫn đến mâu thuẫn và chứng minh sự phỏng đoán. Tôi cũng không nghĩ nó quá khó, nhưng mặt khác, các vấn đề có thể dễ dàng bị đánh giá thấp ...
Ingo Bürk

Tôi chắc chắn sẽ trở lại đây vào lúc nửa đêm với loạt phiếu bầu mới của mình - cho cả câu hỏi và câu trả lời!
trichoplax

Đối với những người đang tìm kiếm, điều này có thể làm cho nó dễ dàng hơn một chút: Nếu bạn loại bỏ "A" đầu tiên thì bạn chỉ phải chơi với "AB" và bạn thêm một nửa + 1 cho lần lặp tiếp theo.
Faquarl

Câu trả lời:


23

CCCCCC được tìm thấy tại 2.124 * 10 ^ 519.

chỉ số chính xác là 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Được tìm thấy bởi độ phân giải, sử dụng mã (phiên bản cũ) bên dưới, sau 3,5 giờ tìm kiếm.

Xung quanh chỉ mục đó, chuỗi là: ...BCCBCBCCCBCCCCCCBCCB...

Để xác minh, thay đổi dòng được chỉ định trong mã bên dưới để bắt đầu ở 2946, thay vì 5. Việc xác minh mất 20 giây.

Cập nhật: Chương trình cải tiến. Chương trình cũ đã tìm kiếm ~ gấp 10 lần địa điểm hơn mức cần thiết.

Phiên bản mới tìm thấy CCCCCCchỉ trong 33 phút.

Cách thức hoạt động của mã: Về cơ bản, tôi chỉ nhìn vào các vùng tương ứng với các đầu của chuỗi tăng dần và tính toán các chữ cái bằng cách nhìn đệ quy trở lại chuỗi gốc. Lưu ý rằng nó sử dụng bảng ghi nhớ, có thể lấp đầy bộ nhớ của bạn. Đặt một nắp trên chiều dài của bảng ghi nhớ nếu cần thiết.

import time
import sys
sys.setrecursionlimit(4000)
ULIMIT=4000
end_positions=[]
current_end=2
while len(end_positions)<ULIMIT+3:
    end_positions.append(current_end)
    next_end=((current_end+1)*3+1)//2-1
    current_end=next_end
memo={}
def find_letter(pos):
    if pos in memo:
        return memo[pos]
    if pos<3:
        return 'ABC'[pos]
    for end_num in range(len(end_positions)-1):
        if pos>end_positions[end_num] and pos<=end_positions[end_num+1]:
            delta=end_positions[end_num+1]-end_positions[end_num]
            if len(memo)>5*10**6:
                return find_letter(pos-delta)
            memo[pos]=find_letter(pos-delta)
            return memo[pos]
time.clock()
for end_num in range(5,ULIMIT+1): # This line.
    diff = 1 # Because end_num is guaranteed to be a C
    while True:
        last_letter=find_letter(end_positions[end_num]+diff)
        if not last_letter=='C':
            break
        diff+=1
    if end_num%100==0:
        pos_str=str(end_positions[end_num])
        print(end_num,'%s.%s*10^%i'%(pos_str[0],pos_str[1:5],len(pos_str)-1),
        len(memo),diff,time.clock())
    if diff>=6:
        print(end_num,end_positions[end_num],diff,time.clock())

Tối đa hiện tại được tìm kiếm tới: 4000 lần lặp

CCCCCC tìm thấy ở lần lặp (s): 2946


Đây là Python phải không?
Sở thích của Calvin

Vâng, tôi sẽ thêm nó.
isaacg

(+1) Chương trình của bạn, với sys.setrecursionlimit(4000)ULIMIT=4000, được tìm thấy (trong khoảng 3,5 giờ trên hệ thống của tôi) sự xuất hiện đầu tiên của CCCCCC tại index = 2.124 * 10 ^ 519. Chỉ số chính xác là trong các bình luận tiếp theo ...
res

3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res

Tuyệt vời! Tôi không bao giờ nghi ngờ rằng nó rất gần với thành công.
isaacg

12

CCCCCC được tìm thấy tại 2.124 * 10 ^ 519.

Mã ruby ​​sau đây được sử dụng để tìm kiếm CCCCCC.

SEARCH = 6

k = [5,3]

getc=->i{
  j=i
  k.unshift(k[0]+(k[0]+1)/2)while(k[0]<=j)
  k.each_cons(2){|f,g|j-=f-g if j>=g}
  "ABC"[j]
}

while true
  x=k[0]
  x-=1 while getc[x]=="C"
  x+=1 
  l=1
  l+=1 while getc[x+l]=="C"

  break if l>=SEARCH
end

puts x
puts (x-14..x+l+13).map{|i|getc[i]}*""

Chỉ số này giống như trong câu trả lời của @isaacg .

Thời gian chạy của mã trên cho 6 theo thứ tự mười giây trên máy tính của tôi. Tuy nhiên, nó vẫn tìm kiếm một câu trả lời cho CCCCCCC(nếu bạn muốn thử nó cho mình bộ liên tục SEARCHtới 7).

Bạn có thể sử dụng getcđể tìm ký tự ở một vị trí cụ thể ivì nó được thực hiện ở dòng cuối cùng nơi chuỗi xung quanh chỉ mục được in.


Tốt công việc tăng tốc nó - giải pháp của tôi là rất thô và chưa được đánh bóng.
isaacg

Một cái gì đó kỳ lạ: Tôi đã chạy mã ở trên cho đến lần lặp # 34000 sau khi loại bỏ ngắt và thay đổi các thử nghiệm xung quanh một chút và nó chỉ tìm thấy một lần chạy 6. Đây có phải là vấn đề với mã (tôi nghi ngờ về nó) hoặc nó chỉ là một thuộc tính kỳ lạ của chuỗi?
isaacg

@isaacg Lưu ý rằng chúng tôi chỉ kiểm tra thời gian nghỉ của từng chuỗi và do đó bỏ lỡ tất cả các chuỗi sao chép C ^ 6. Vào giờ nghỉ, những điều đó dường như rất hiếm - vì vậy tôi nghĩ rằng chúng ta sẽ không gặp C ^ 7 sớm.
Howard

Tôi biết, nhưng vì một lần được tìm thấy trong một lần ngắt chuỗi chỉ sau 2946 lần lặp, tôi mong đợi sẽ thấy lần thứ hai sau 40000 lần lặp, đó là nơi tôi đang ở.
isaacg

@isaacg Bạn có thể sử dụng mã (nhanh hơn nhiều) tại đây: ideone.com/HoEKOB . Ngay cả với điều đó, tôi không thể tìm thấy C ^ 6 khác tại một điểm liên tiếp (thậm chí ít hơn C ^ 7).
Howard

5

(Không phải là một câu trả lời, nhưng quá dài cho một nhận xét.)

Sau đây là bản dịch Python của chương trình Ruby của @ Howard (được tăng tốc bởi một nhân tố gần 3 bằng cách chỉ có một getctrong vòng tìm kiếm). Trên hệ thống của tôi, điều này tìm thấy C ^ 6 đầu tiên trong 3 giây. Trong 93 giờ, nó không tìm thấy C ^ 7 trong 231.000 lần lặp, do đó, C ^ 7 đầu tiên (nếu nó tồn tại) phải xuất hiện sau 10 ^ 40677 vị trí ngoài cùng bên trái trong chuỗi vô hạn.

import time

L = [5, 3]      #list grows "backwards" (by insertion on the left)

def getc(i):    #return the letter at index i
    while L[0] <= i: L.insert(0,L[0] + (L[0] + 1)//2)
    for k in range(len(L)-1): 
        if i >= L[k+1]: i -= L[k] - L[k+1]
    return 'abc'[i]

def search(k):  #find the first occurrence of c^k
    start = time.time()
    iter = 0
    while True:
        iter += 1
        if iter % 1000 == 0: print iter, time.time()-start
        p = L[0] - 1
        l = 1
        while getc(p+l)=='c': l += 1
        if l == k: break 
    return p, iter, time.time()-start

k = 6

(indx, iter, extime) = search(k)
print 'run length:', k
print 'index:', indx, '    (',len(str(indx)),'digits )'
print 'iteration count:', iter
print 'neighborhood:', ''.join([getc(i) for i in range(indx-1,indx+k+10)])
print 'execution time:', extime

Với PyPy, nó tìm thấy C ^ 6 trong chưa đầy một giây trên máy của tôi.
Dennis
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.