이 무한 문자열에서 런은 어디에 있습니까? (CCCCCC 발견!)


25

string으로 시작하여 ABC자신의 마지막 절반을 반복해서 자신에 추가 한 결과를 고려하십시오 (길이가 홀수 인 경우 더 큰 절반 사용).

우리는 진보를 얻습니다 :

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

하자 S절차와 같은 결과가 영원히 반복되는 결과 무한 문자열 (또는 열)를 나타낸다.

이 코드 챌린지의 목표는의 런의 첫 번째 발생 색인을 찾는 것 C입니다 S.

: 그것은 처음에는 쉽게 C첫 번째 인덱스에서 발생 2, CC4, CCC7, CCCC26, 그러나 CCCCC인덱스에 모든 방법입니다 27308! 그 후 내 기억이 부족합니다.

우승자는 가장 많은 지수를 올바르게 생성하는 제출물이됩니다 (순서대로 시작 C). 모든 종류의 알고리즘을 사용할 수 있지만 기본적인 무차별 대입을 사용하지 않는 경우 반드시 설명하십시오. 입력 및 출력은 이해하기 쉬운 형식 일 수 있습니다.

중요 사항 : 나는 S실제로 모든 실행을 포함 하는지 여부를 공식적으로 알지 못합니다 C. 이 질문은 저자가 찾지 못한 Mathematics Stack Exchange의 질문에서 비롯된 CCCCCC것입니다. 나는 여기 누군가가 할 수 있는지 궁금하다. (이 질문은 주제에 대한 나의 원래 질문을 바탕 으로합니다 .)

당신의 모든 실행 증명할 수있는 경우 C에 발생을 S이 질문은 더 이상 유효하지 때문에 당신은 자동으로 이길 것이다. 아무도 그 증명되지도 찾을 수 있다면 CCCCCC그 승자가 얻을 수있는 사람이 될 것입니다 가장 높은 지수에 하한 CCCCCC(또는 어떤 경우에 가장 큰 미해결 실행이 CCCCCC발견된다).

업데이트 : 엄청난로 명성 isaacg고해상도 발견 CCCCCC2.124 * 10 ^ (519)의 천문학적 인덱스. 이 속도에서 나는 CCCCCCC무차별 대입에 의존하는 방법으로 찾는 것을 상상할 수 없습니다 . 잘 했어!


나는 그것을 얻지 못합니다-당신은 CCCCC색인 27308에서 발견했다고 말하지만 나중에 처음 어디에서 발생하는지 알지 못하는 것처럼 들립니다. 당신은 의미 했습니까 CCCCCC?
isaacg

@isaacg 죄송합니다. 6 C는 찾기 어려운 곳입니다. 내가 고칠 게
Calvin 's Hobbies

추측이 틀리면 c ^ N이 가장 긴 N이 있습니다. 더 긴 시퀀스를 구성하여 모순을 일으키고 추측을 증명하는 것이 가능할 것이라고 확신합니다. 나도 그렇게 어렵다고 생각하지 않지만, 반면에 문제는 쉽게 과소 평가 될 수 있습니다 ...
Ingo Bürk

나는 질문과 답변 모두를 위해 자정에 새로운 투표를 통해 여기에 다시오고 있습니다!
trichoplax

검색하는 사람들의 경우 조금 더 쉬울 수 있습니다. 첫 번째 "A"를 제거하면 "AB"만 재생하면되고 다음 반복을 위해 half + 1 만 추가하면됩니다.
Faquarl

답변:


23

CCCCCC는 2.124 * 10 ^ 519에 있습니다.

정확한 지수는 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215입니다

3.5 시간의 검색 후 아래의 (이전 버전) 코드를 사용하여 res가 발견했습니다.

해당 색인 주위에서 문자열은 다음과 같습니다. ...BCCBCBCCCBCCCCCCBCCB...

확인하려면 아래 코드에서 표시된 줄을 5 대신에 2946에서 시작하도록 변경하십시오. 확인하는 데 20 초가 걸립니다.

업데이트 : 프로그램 개선. 기존 프로그램은 필요한 것보다 ~ 10 배 더 많은 위치를 검색했습니다.

새 버전은 CCCCCC33 분만에 찾을 수 있습니다.

코드 작동 방식 : 기본적으로 증분 문자열의 끝 부분에 해당하는 영역 만보고 원래 문자열을 재귀 적으로보고 문자를 계산합니다. 메모 테이블을 사용하므로 메모리가 가득 찰 수 있습니다. 필요한 경우 메모 테이블의 길이에 뚜껑을 닫으십시오.

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

검색된 현재 최대 값 : 4000 회

CCCCCC 반복에서 발견 : 2946


이게 파이썬이야?
캘빈의 취미

예, 추가하겠습니다.
isaacg

(+1) sys.setrecursionlimit(4000)and을 (를) 사용하는 프로그램이 ULIMIT=4000내 시스템에서 약 3.5 시간 내에 인덱스 = 2.124 * 10 ^ 519에서 CCCCCC가 처음 발견되었습니다. 정확한 색인은 다음 코멘트에 있습니다 ...
res

3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215는
입술

대박! 나는 그것이 성공에 너무 가까웠다 고 의심하지 않았다.
isaacg

12

CCCCCC는 2.124 * 10 ^ 519에 있습니다.

다음 루비 코드가 검색에 사용되었습니다 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]}*""

색인은 @isaacg 의 답변 과 동일 합니다.

위의 코드 6의 런타임은 내 컴퓨터에서 10 초 정도입니다. 그럼에도 불구하고 여전히 답을 찾고 있습니다 CCCCCCC(직접 시도하려고하면 상수 SEARCH로 설정하십시오 7).

색인 주위의 문자열이 인쇄되는 마지막 행에서 수행되는 것처럼 getc특정 위치에서 문자를 찾는 데 사용할 수 있습니다 i.


작업 속도 향상-내 솔루션은 매우 거칠고 닦지 않았습니다.
isaacg

이상한 점 : 중단을 제거하고 테스트를 약간 변경 한 후 위의 코드를 반복 # 34000까지 실행했으며 6 번만 실행합니다.이 코드에 문제가 있습니까? 시퀀스의 이상한 속성입니까?
isaacg

@isaacg 각 시퀀스의 구분 만 확인하므로 모든 복사 순서 C ^ 6이 누락되었습니다. 쉬는 시간에 그것들은 매우 드문 것 같습니다. 따라서 우리는 C ^ 7을 곧 보지 못할 것이라고 생각합니다.
Howard

나는 알고 있지만, 2946 반복 후에 시퀀스 중단에서 발견되었으므로 지금은 40000 반복으로 두 번째 반복을 볼 것으로 예상됩니다.
isaacg

@isaacg 당신은 여기에 (훨씬 더 빠른) 코드를 사용할 수 있습니다 : ideone.com/HoEKOB를 . 그럼에도 불구하고 나는 시퀀스 포인트에서 다른 C ^ 6을 찾을 수 없었습니다 (심지어 C ^ 7이 적음).
Howard

5

(답은 아니지만 의견이 너무 깁니다.)

다음은 @Howard의 Ruby 프로그램을 파이썬으로 번역 한 것 getc입니다 (검색 루프에 하나만 있으면 3에 가까워집니다 ). 내 시스템에서 이것은 3 초 안에 첫 번째 C ^ 6을 찾습니다. 93 시간 동안 231,000 번의 반복에서 C ^ 7을 찾지 못하므로 첫 번째 C ^ 7 (있는 경우)은 무한 문자열에서 가장 왼쪽의 10 ^ 40677 위치 이후에 발생해야합니다.

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

PyPy를 사용하면 내 컴퓨터에서 1 초 이내에 C ^ 6을 찾습니다.
Dennis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.