Введение
У A229037 довольно интригующий сюжет (по крайней мере, для первых нескольких терминов):
Существует предположение, что у него действительно может быть какое-то фрактальное свойство.
Как строится эта последовательность?
Определить a(1) = 1, a(2) = 1
то для каждого n>2
найти минимальное положительное целое число , a(n)
такое , что для каждого арифметического 3 члена последовательности n,n+k,n+2k
индексов, соответствующие значения последовательности a(n),a(n+k),a(n+2k)
является не арифметической последовательности.
Вызов
Если n
в качестве входных данных положительное целое число , выведите первые n
члены a(1), ... , a(n)
этой последовательности. (С любым разумным форматированием. Возможные начальные / обучающие символы / строки не имеют значения.)
Существуют фрагменты для генерации этой последовательности, но я думаю, что другие подходы могут быть более подходящими для игры в гольф / более подходящими для определенных языков.
Пожалуйста, дайте нам знать, как работает ваша программа. Если вы столкнетесь с особенно эффективным алгоритмом, вы также можете упомянуть об этом, так как он позволит построить больше членов последовательности за более короткое время.
Первые несколько тестов:
1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 9, 4, 4, 5, 5, 10, 5, 5, 10, 2, 10, 13, 11, 10, 8, 11, 13, 10, 12, 10, 10, 12, 10, 11, 14, 20, 13
Больше тестов:
a(100) = 4
a(500) = 5
a(1000) = 55
a(5000) = 15
a(10000) = 585
Все условия до n=100000
доступны здесь: https://oeis.org/A229037/b229037.txt
Спасибо @ MartinBüttner за помощь и поддержку.
Ответы:
Python 2, 95 байт
Основная хитрость заключается в генерации чисел, которых должно избегать новое значение. Сохранение обратной последовательности до сих пор в
l
, давайте посмотрим, какие элементы могут формировать трехчленную арифметическую прогрессию со значением, которое мы собираемся добавить.Другие числа являются парными членами
l
и каждым вторым элементомl
, поэтомуzip(l,l[1::2])
. Если эта пара,(b,c)
то арифметическая прогрессия(a,b,c)
происходит дляa=2*b-c
. После генерации набораa
символов, чтобы избежать, код берет минимум дополнения, печатает его и добавляет его в список. (На самом деле, вычисления выполняются с числами, уменьшенными на 1, и напечатанными на 1 выше, чтобы можно былоrange(n)
служить универсумом кандидатов.)источник
Mathematica, 95 байт
Конечно, это не самый удачный подход, но на самом деле он довольно эффективен по сравнению с алгоритмами, которые я попробовал со страницы OEIS.
В отличие от проверки всех запрещенных значений для каждого s (n), когда мы доберемся туда, я использую основанный на сите подход. Когда мы находим новое значение s (n), мы немедленно проверяем, какие значения это запрещает для m> n . Тогда мы просто решаем s (n + 1) , ища первое значение, которое не было запрещено.
Это можно сделать еще более эффективным, изменив условное
--i>0
на2n-#<=--i>0
. В этом случае мы избегаем проверки запрещенных значений для n больше, чем ввод.Для более удобочитаемой версии я начал с этого кода, в котором результаты сохраняются
max
в одной функцииf
, а затем применил его к указанной выше однострочной чистой функции:источник
Haskell,
90,89,84, 83 байтаВероятно, можно играть в гольф больше, но это все еще достойная
перваяпопытка:Ungolfed:
Это простая реализация, которая возвращает '0' за пределами. Затем для каждого возможного значения он проверяет, что для всех k <= n и в пределах [x, a (xk), a (x-2k)] не является арифметической последовательностью.
Верхняя граница сложности времени (используя факт из страницы OEIS, что a (n) <= (n + 1) / 2:
Я не уверен, насколько хороша эта граница, потому что вычисление первых 1k значений 't' и использование линейной модели на логах значений дало appx. O (22 ^ n), с p-значением <10 ^ (- 1291), если это имеет значение.
На уровне реализации, компилируясь с '-O2', потребовалось ~ 35 минут, чтобы вычислить первые 20 значений.
источник
Брахилог ,
3331 байтПопробуйте онлайн!
В случае, если это имеет значение: 2-байтовый гольф стал возможен благодаря функции, которую я запросил после работы над этой задачей.
объяснение
Мы итеративно генерируем последовательность в виде списка в обратном порядке, например
[2,2,1,1,2,1,1]
, и переворачиваем ее в конце.Здесь есть несколько вложенных предикатов. Давайте посмотрим на них изнутри. Первый из них,
ġh₃hᵐs₂ᶠ-ᵐ=
принимает подпоследовательность кандидатаa(n),a(n-1),...,a(0)
и определяет,a(n),a(n-k),a(n-2k)
является ли арифметическая последовательность для некоторыхk
.Например, с вводом
[1,2,1,1,2,1,1]
:Следующий предикат наружу
~b.hℕ₁≜∧.¬{...}∧
вводит подпоследовательностьa(n-1),a(n-2),...,a(0)
и выводит следующую большую подпоследовательностьa(n),a(n-1),a(n-2),...,a(0)
.Наконец, основной предикат
;Ė{...}ⁱ⁽↔
принимает входное число и выводит столько членов последовательности.источник
Рубин , 71 байт
Попробуйте онлайн!
Создает все запрещенные значения, затем принимает дополнение этого массива в (1..n) и принимает первое значение результата. Это означает, что я предполагаю, что
a[n] <= n
для всех n, что легко доказать с помощью индукции (если все первые n / 2 слагаемых меньше n / 2, то не может быть арифметической прогрессии, приводящей к n).Синтаксический трюк здесь также немного интересен:
*a
он используется для инициализации массива дополнительных аргументов (который был бы проигнорирован, если бы мы его передали), а затемa.fill
изменяет массив аргументов и неявно возвращает его.источник
a[s-o]
иa[s-2*o]
, вы можете использоватьa[s-=1]
иa[s-o]
APL (Dyalog Extended) , 37 байт SBCS
Большое спасибо Адаму за его помощь в написании и игре в гольф этот ответ в саду APL , отличном месте для изучения языка APL. Попробуйте онлайн!
Редактировать: -6 байт благодаря Адаму
объяснение
APL (Dyalog Unicode) ,
433938 байт SBCSВот более быстрое, но менее гольфовое решение, которое может рассчитать
⍺(10000)
за несколько секунд.Попробуйте онлайн!
источник
МАТЛАБ,
156147 байтНаконец-то я немного поиграл в гольф:
Ungolfed:
Ввод считывается из STDIN, и печать выполняется автоматически с
ans=
добавлением материала. Я надеюсь, что это квалифицируется как «разумный» вывод.Это также сита на основе раствора: переменная
s(i,:)
отслеживает тех значений последовательности , которые запрещены дляa(i)
.try-catch
Блок необходим для лечения случая пустых ( что означает полный ноль)s
матрицы: в этом случае наименьшее значение1
уже разрешено.Тем не менее, потребность в памяти (или время выполнения?) Становится довольно грязной выше
N=2000
. Итак, вот неконкурентное, более эффективное решение:В этой реализации
s
матрица снова содержит запрещенные значения, но в упорядоченном виде, без каких-либо нулевых блоков (которые присутствуют в конкурирующей версии). Индексный векторi
отслеживает количество запрещенных векторов вs
. С первого взгляда было бы здорово следить за информацией, хранящейся вs
, но она была бы медленной, и мы не могли индексировать кучу их одновременно.Одна из неприятных особенностей MATLAB заключается в том, что, хотя вы можете сказать
M(1,end+1)=3;
и автоматически развернуть матрицу, вы не можете сделать то же самое с линейным индексированием. Это имеет смысл (как MATLAB знать размер результирующего массива, в рамках которого он должен интерпретировать линейные индексы?), Но это все равно меня удивило. Это причина лишней линииs(N,max(i(j))) = 0;
: это расширитs
матрицу для нас всякий раз, когда это необходимо. Начальный размер угадатьN*0.07+20
Кстати, зависит от линейного соответствия первых нескольких элементов.Чтобы проверить время выполнения, я также проверил слегка измененную версию кода, где я инициализировал
s
матрицу, чтобы иметь размерN/2
. Для первых1e5
элементов это, кажется, очень щедрое предположение, поэтому я удалил шаг расширения,s
упомянутый в предыдущем абзаце. Все вместе они означают, что код будет быстрее, но также и менее устойчивым на очень высоком уровнеN
(поскольку я не знаю, как там выглядит серия).Итак, вот несколько времени выполнения, сравнивая
Я измерил их на R2012b, взяв лучший из 5 прогонов в определении именованной функции с помощью
tic/toc
.N=100
:0.011342 s
0.015218 s
0.015076 s
N=500
:0.101647 s
0.085277 s
0.081606 s
N=1000
:0.641910 s
0.187911 s
0.183565 s
N=2000
:5.010327 s
0.452892 s
0.430547 s
N=5000
:2.021213 s
1.572958 s
N=10000
:6.248483 s
5.812838 s
Казалось бы,
v3
версия значительно, но не намного быстрее. Я не знаю, стоит ли элемент неопределенности (для очень большогоN
) незначительного увеличения времени выполнения.источник
M=1;M(end+1)=2;
у меня прекрасно работает?M=rand(2); M(end+1)=2
вместо этого :)Желе ,
2419 байтЭто мой первый желейный ответ за долгое время. Рад вернуться.
Это порт моего ответа APL, который сам по себе является адаптацией многих алгоритмов, используемых здесь. Основное отличие состоит в том, что это 0-индексированный.
Изменить: -5 байтов благодаря Джонатану Аллану.
Попробуйте онлайн!
объяснение
источник
ḟ
будет делать то же самое, что иœ-
сохранение байта“”
с1
выводом представление Jelly списка из полной программы, экономя еще один.Œœị@2
можно сыграть в гольф, чтобыḊm2
спасти двоих.L‘R
может быть игра в гольф, чтобыŻJ
спасти один.ES6, 114 байт
Возвращает массив первых n элементов последовательности, поэтому индексы равны 1 для версии без заглядывания ниже. Я использовал ситчатый подход. Эта версия замедляется примерно после n = 2000; предыдущая версия избегала считывания начала массива, что означало, что он не замедлялся до n = 2500. Более старая версия использовала массив sieve как список запрещенных значений, а не логический массив, значения которого были запрещены; это могло бы достигнуть приблизительно n = 5000, не ломая пот. Моя оригинальная версия пыталась использовать битовые маски, но это оказалось бесполезным (и также было слишком длинным в 198 байт).
Не очень медленная версия без гольфа:
источник