Где пробеги в этой бесконечной последовательности? (Нашел!)


25

Начиная со строки ABC, рассмотрим результат многократного добавления последней половины к себе (используя большую половину, если длина нечетна).

Получаем прогрессию:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Позвольте Sпредставить результирующую бесконечную строку (или последовательность), которая получается, как эта процедура повторяется навсегда.

Цель

Цель этой задачи кода - найти индекс первого вхождения прогонов Cв S.

Сначала это легко: Cсначала происходит в index 2, CCat 4, CCCat 7, CCCCat 26, но CCCCCполностью в index 27308! После этого у меня кончается память.

Победителем будет представление, которое правильно генерирует наиболее запущенные индексы (по порядку, начиная с C). Вы можете использовать любой алгоритм, но обязательно объясните его, если вы не используете базовую грубую силу. Вход и выход могут быть в любом удобном для понимания формате.

Важное примечание: я официально не знаю, Sсодержит ли на самом деле все серии C. Этот вопрос выводится из этого на Математическом обмене стека , в котором автор также не нашел CCCCCC. Мне любопытно, если кто-нибудь здесь может. (Этот вопрос, в свою очередь, основан на моем первоначальном вопросе по теме .)

Если вы можете доказать, что не все заезды Cпроисходят, Sвы автоматически выиграете, так как этот вопрос больше не будет действительным. Если никто не может ни доказать это, ни найти, CCCCCCто победителем будет тот, кто сможет получить наивысшую нижнюю границу индекса CCCCCC(или какова будет самая большая нерешенная пробежка, если CCCCCCнайден).

Обновление: Humongous престижность isaacg и разрешения , которые нашли CCCCCCна астрономической индекс 2.124 * 10 ^ 519. При таких темпах я не могу себе представить поиск CCCCCCCс помощью любого метода, основанного на грубой силе. Хорошая работа, ребята!


Я не понимаю - ты говоришь, что нашел CCCCC по индексу 27308, но позже кажется, что вы не знаете, где это происходит впервые. Вы имели в виду CCCCCC?
Исаак

@isaacg Упс. 6 C это тот, который трудно найти. Я исправлю это.
Увлечения Кэлвина

Если гипотеза неверна, существует N, для которого c ^ N - самый длинный пробег. Я почти уверен, что должна быть возможность построить более длинную последовательность, приводящую к противоречию и подтверждающую гипотезу. Я также не думаю, что это слишком сложно, но, с другой стороны, проблемы могут быть легко недооценены ...
Ingo Bürk

Я определенно вернусь сюда в полночь с моей новой партией голосов - и за вопрос, и за ответы!
Трихоплакс

Для тех, кто ищет, это может немного облегчить задачу: если вы удалите первую букву «А», вам нужно будет поиграть только с буквой «А», и вы добавите половину + 1 для следующей итерации.
Faquarl

Ответы:


23

Нашли в 2.124 * 10 ^ 519.

Точный показатель 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Найден res, используя код (старая версия) ниже, после 3,5 часов поиска.

Вокруг этого индекса строка выглядит так: ...BCCBCBCCCBCCCCCCBCCB...

Чтобы проверить, измените указанную строку в коде ниже, чтобы начать с 2946 вместо 5. Проверка занимает 20 секунд.

Обновление: улучшена программа. Старая программа искала в ~ 10 раз больше локаций, чем необходимо.

Новая версия находит CCCCCCвсего за 33 минуты.

Как работает код: в основном я смотрю только на регионы, которые соответствуют концам инкрементальных строк, и вычисляю буквы, рекурсивно возвращаясь к исходной строке. Обратите внимание, что он использует таблицу заметок, которая может заполнить вашу память. При необходимости наденьте колпачок на длину таблицы заметок.

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


Это Питон, верно?
Увлечения Кэлвина

Да, я добавлю это.
Исаак

(+1) Ваша программа с помощью sys.setrecursionlimit(4000)и ULIMIT=4000нашла (примерно через 3,5 часа в моей системе) первое вхождение индекса со значением индекса = 2,124 * 10 ^ 519. Точный индекс в следующем комментарии ...
Res

3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
рес

Потрясающе! Я никогда не подозревал, что это так близко к успеху.
Исаак

12

Нашли в 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 порядка десяти секунд на моем компьютере. Тем не менее, он все еще ищет ответ CCCCCCC(если вы хотите попробовать его самостоятельно, установите константу SEARCHв 7).

Вы можете использовать, getcчтобы найти символ в определенной позиции, iкак это делается в последней строке, где печатается строка вокруг индекса.


Хорошая работа, ускоряющая это - мое решение было очень грубым и неполированным.
Исаак

Что-то странное: я выполнил вышеупомянутый код до итерации # 34000 после удаления разрыва и изменения тестов примерно на один, и он находит только один прогон из 6. Это проблема с кодом (я сомневаюсь в этом) или это просто нечетное свойство последовательности?
Исаак

@isaacg Обратите внимание, что мы проверяем только разрывы каждой последовательности и, таким образом, пропускаем все последовательности копирования C ^ 6. На перерывах они кажутся очень редкими - поэтому я думаю, что мы скоро не увидим C ^ 7.
Говард

Я знаю, но так как один был найден на разрыве последовательности после всего лишь 2946 итераций, я бы ожидал увидеть второй с 40000 итерациями, где я сейчас нахожусь.
Исаак

@isaacg Вы можете использовать (намного быстрее) код здесь: ideone.com/HoEKOB . Даже с этим я не мог найти другой C ^ 6 в точке последовательности (даже меньше C ^ 7).
Говард

5

(Не ответ, но слишком долго для комментария.)

Ниже приведен перевод на Python программы @ Howard's Ruby (увеличенный в 3 раза благодаря наличию только одного getcв цикле поиска). В моей системе это находит первый C ^ 6 через 3 секунды. За 93 часа он не находит C ^ 7 в 231 000 итераций, поэтому первый 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 он находит C ^ 6 менее чем за секунду на моей машине.
Деннис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.