Шаткая последовательность Голомба


21

OEIS имеет вариант (A111439) последовательности Голомба . Как и в последовательности Голомба, A(n)описывает, как часто nпоявляется в последовательности. Но кроме того, никакие два последовательных числа не могут быть идентичными. При построении последовательности A(n)всегда выбирается как наименьшее положительное целое число, которое не нарушает эти два свойства. Из-за запрещенных последовательных идентичных чисел ряд слегка колеблется вверх и вниз по мере роста. Вот первые 100 терминов:

1, 2, 3, 2, 3, 4, 3, 4, 5, 6, 5, 6, 5, 6, 7, 6, 7, 8, 7, 8, 9, 8, 9, 8, 9, 
10, 9, 10, 9, 10, 11, 10, 11, 10, 11, 10, 11, 12, 11, 12, 13, 12, 13, 12, 
13, 12, 13, 12, 13, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 16, 15, 
16, 17, 16, 17, 16, 17, 16, 17, 16, 17, 18, 17, 18, 17, 18, 19, 18, 19, 18, 
19, 18, 19, 18, 19, 18, 19, 20, 19, 20, 21, 20, 21, 20, 21, 20, 21, 20

Полный список первых 10000 номеров можно найти в OEIS .

Задача состоит в том, чтобы написать программу или функцию, которая вычисляет A(n), учитывая n. nна 1основе того, что свойство с самоописанием работает.

правила

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

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

Это , поэтому самый короткий действительный ответ - измеренный в байтах - выигрывает.

Тестовые случаи

n     A(n)
1     1
4     2
10    6
26    10
100   20
1000  86
1257  100
10000 358


3
Мне было любопытно, поэтому я это понял . Neato.
Тост инженера

4
@EngineerToast График также находится в OEIS. Я смотрел на то, как долго «пробегает» вы видите на графике, и это становится действительно странным . (Этот график показывает, как часто Nпосле последнего вхождения появляется число, N-1которое измеряет количество колебаний до N.)
Мартин Эндер,

Ответы:


5

Haskell , 67 байт

f k|k<4=k|p<-k-1=[n|n<-[1..],n/=f p,sum[1|a<-[1..p],f a==n]<f n]!!0

Определяет функцию f. Попробуйте онлайн! Это очень медленно, f 15время ожидания вычислений на TIO.

объяснение

Просто перейдем к определению: на каждом этапе выберите минимальное положительное число, nкоторое удовлетворяет ограничениям (не равным предыдущей записи и еще не произошло f n).

f k             -- Define f k:
 |k<4=k         -- If k < 4, it's k.
 |p<-k-1=       -- Otherwise, bind k-1 to p,
  [n|           -- compute the list of numbers n where
   n<-[1..],    -- n is drawn from [1,2,3,...],
   n/=f p,      -- n is not equal to f p, and
   sum[1|       -- the number of
    a<-[1..p],  -- those elements of [1,2,3,...,p]
    f a==n]     -- whose f-image equals n
   <f n]        -- is less than f n,
  !!0           -- and take the first element of that list.

5

Mathematica, 69 68 байт

Спасибо Мартину Эндеру за то, что он нашел для меня дополнительный -1 байт!

Last@Nest[{##&@@#,1//.x_/;x==Last@#||#~Count~x==#[[x]]->x+1}&,{},#]&

Безымянная функция, принимающая положительное целое число в nкачестве входных данных и возвращающая положительное целое число. Построим весь список первых nэлементов этой последовательности, затем возьмем Lastэлемент. Список {}создается, начиная с пустого списка и оперируя с ним функцией nраз в строке (через Nest).

Рассматриваемая функция {##&@@#,1//.x_/;x==Last@#||#~Count~x==#[[x]]->x+1}&принимает частичный список значений последовательности (по существу ##&@@#) и добавляет к нему следующее значение. Следующее значение вычисляется путем запуска с x=1последующим многократным замещением xдо x+1тех пор, пока выполняется условие x==Last@#||#~Count~x==#[[x]]- иными словами, если либо xявляется предыдущим элементом, либо xуже находится в списке правильное число раз. Эта функция выдает некоторые ошибки, так как (например) мы не должны вызывать xth-й элемент исходного списка {}; Однако все значения верны.


4

Python 2, 99 86 байт

Спасибо @Dennis за несколько улучшений общим объемом 13 байт!

s=0,1,2,3
exec't=1\nwhile t==s[-1]or s.count(t)/s[t]:t+=1\ns+=t,;'*input()
print s[-4]

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

Теперь мы начнем с того, 1,2,3что будем подавать результаты 1,2,3. Это сделано для того, чтобы избежать каких-либо проблем, поскольку список уже вычисленных значений слишком короткий: я предполагаю, что если nпо крайней мере, 4то a(n)строго меньше, чем n. (В этой программе s[n]он равен a(n). Наш список фактически инициализирован [0,1,2,3]так, потому что списки 0индексируются в Python. Так, например a(1)=s[1]=1, и a(2)=s[2]=2.)

Итак, допустим, мы пытаемся определить s[m], что означает, что наш список уже включает s[0], s[1], ..., s[m-1]. Мы начнем с t=1и попытаемся установить s[m]=1. Когда это не работает, мы идем t=2и пытаемся установить s[m]=2. Каждый раз, когда мы увеличиваем t, мы проверяем, s.count(t)==s[t]... но правая часть не будет выдавать ошибку, пока нам никогда не придется идти так высоко, как t=m. Гипотеза говорит, что мы никогда не должны, так как первое значение, которое мы вычисляем, на самом деле s[4].

Эта реализация вычисляет на 3 значения последовательности больше, чем нужно. Например, если nесть 8, он вычислит до s[11]того, как вернет значение s[8].

Я был бы счастлив увидеть подтверждение гипотезы. Я полагаю, что это может быть доказано (сильной?) Индукцией.

Изменить: Вот доказательство гипотезы . На самом деле мы доказываем немного более сильную форму утверждения, поскольку оно не требует дополнительной работы.

Теорема: для всех nбольше или равно 4, термин a(n)меньше или равен (n-2).

Доказательство (по индукции Strong): (Base n=4): Это утверждение верно для n=4, так как a(4) = 2 = 4-2.

Теперь предположим, a(k)что меньше или равно k-2для всех kот 4сквозного n, включительно (и предположим n, по крайней мере 4). В частности, это означает, что все предыдущие члены последовательности были не более (n-2). Нам нужно показать, что a(n+1)будет максимум (n-1). Теперь, по определению, a(n)это наименьшее положительное целое число, которое не нарушает ни одно из условий, поэтому нам просто нужно показать, что значение (n-1)не будет нарушать ни одно из условий.

Значение (n-1)не будет нарушать условие «нет последовательных повторов», потому что по предположению индукции предыдущая запись была не более (n-2). И это не будет нарушать условие a(m)«количество раз mпоявляется», если оно (n-1)не было достигнуто a(n-1). Но по предположению сильной индукции, (n-1)ранее были достигнуты 0времена, и a(n-1)не равен, 0поскольку a(m)является положительным для всех m.

Следовательно a(n+1), меньше или равно n-1 = (n+1)-2, как желательно. QED.


3

Желе , 17 байт

Ṭ€S<;1Tḟ®Ḣ©ṭ
⁸Ç¡Ṫ

Последние три контрольных примера - это слишком много для TIO. Я проверил 1000 и 1257 локально.

Попробуйте онлайн! или проверьте первые 100 терминов .

Как это устроено

⁸Ç¡Ṫ          Main link. No arguments.

⁸             Yield [].
 Ç¡           Execute the helper link n times (where n is an integer read from
              STDIN), initially with argument [], then with the previous return
              value as argument. Yield the last return value.
              Tail; yield the last element of the result.


Ṭ€S<;1Tḟ®Ḣ©ṭ  Helper link. Argument: A (array)

Ṭ€            Untruth each convert each k into an array of k-1 zeroes and one 1.
  S           Sum; column-wise reduce by +, counting the occurrences of all
              between 1 and max(A).
   <          Compare the count of k with A[k] (1-indexed), yielding 1 for all
              integers that still have to appear once or more times.
    ;1        Append a 1 (needed in case the previous result is all zeroes).
      T       Truth; find all indices of ones.
       ḟ®     Filter-false register; remove the value of the register (initially 0)
              from the previous result.
         Ḣ©   Head copy; yield the first (smallest) value of the result and save
              it in the register.
           ṭ  Tack; append the result to A.

3

Python 2 , 77 74 байта

f=lambda n,k=1:n*(n<4)or map(f,range(n)+k*[n-1]).count(k)<f(k)or-~f(n,k+1)

Это рекурсивная реализация алгоритма @ mathmandan .

Реализация O (безумная) : ввод 9 занимает 2 секунды локально, ввод 10 52 секунд и ввод 11 17 минут и 28 секунд. Однако если декларация объявлена ​​как обычная функция, а не как лямбда, для проверки контрольных примеров можно использовать памятку.

Попробуйте онлайн!

Обратите внимание, что даже при наличии заметки TIO не может вычислить f (1257) или f (10000) (оба проверены локально).


2

05AB1E , 32 31 байт

XˆXˆG[N¯2(è<›¯¤NÊsN¢¯Nè‹&&#]N.ˆ

Попробуйте онлайн!

объяснение

XˆXˆ                             # initialize global list as [1,1]
    G                            # input-1 times do:
     [                    #]     # loop until expression is true     
      N¯2(è<›                    # n > list[-2]-1
             ¯¤NÊ                # list[-1] != N
                 sN¢¯Nè‹         # count(list, N) < list[N]
                        &&       # logical AND of the 3 expressions
                            N.ˆ  # add N to global list 
                                   and output last value in list and end of program

Мы технически в цикле , Gкогда мы добавляем N в глобальный список, но все петли в 05AB1E использовать ту же переменную N как индекс, так что внутренний контур [...]имеет переписывается N из Gозначает , что мы можем добавить его вне цикла.

Проблемы с вложенными циклами и условиями не позволяют нам делать это внутри цикла.


2

Befunge, 141 136 байт

<v9\0:p8\2:*2:-1<9
v>p1+:3\8p0\9p:#^_&
>1-:#v_1.@>$8g.@
*+2%\>1-:!|>$!:::9g!\!9g!*\:8g\!8g`
9\+1g9::< \|`g9\g8+2::p
g2+\8p2+^:<>:0\9p::8

Попробуйте онлайн!

Из-за ограничений памяти Befunge практически нецелесообразно отслеживать все предыдущие записи в последовательности, поэтому в этом решении используется алгоритм с меньшим объемом памяти, который вычисляет значения более непосредственно.

Тем не менее, мы все еще ограничены размером ячейки, который в эталонном интерпретаторе Befunge-93 представляет собой 8-битное значение со знаком, поэтому наибольшее поддерживаемое четное число в последовательности равно A(1876) = 126, а наибольшее поддерживаемое нечетное число равно A(1915) = 127.

Если вы хотите проверить большие значения, вам нужно использовать интерпретатор с большим размером ячейки. Это должно включать большинство реализаций Befunge-98 ( попробуйте онлайн! ).


0

Python 2, 117 байт

Мех. Не так коротко. Простое итеративное решение.

L=[1,2,3]
n=input()
while len(L)<n:
 for i in range(2,n):
    if L.count(i)<L[i-1]and L[-1]!=i:L+=[i];break
print L[n-1]

Попробуйте онлайн

Вот действительно неудачная попытка рекурсивного решения (129 байт):

def f(n,L=[1,2,3]):
 if len(L)>=n:print L[n-1];exit(0)
 for i in range(2,n):
    if L.count(i)<L[i-1]and L[-1]!=i:f(n,L+[i])
 f(n,L)

Исправлена. Я думал, что могу использовать -1вместо того, n-1чтобы сохранить байт, я думаю, нет.
mbomb007
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.