Это последовательность A054261
- е простое число сдерживания является наименьшим числом , которое содержит первые простых чисел как подстрок. Например, число - это наименьшее число, которое содержит первые 3 простых числа в качестве подстрок, что делает его третьим основным номером содержания.
Нетрудно понять, что первые четыре простых числа локализации - это , 23 , 235 и 2357 , но тогда это становится более интересным. Поскольку следующее простое число равно 11, следующее простое число содержимого не 235711 , но это 112357, так как оно определено как наименьшее число со свойством.
Однако настоящая проблема возникает, когда вы выходите за пределы 11. Следующее простое число сдерживания - . Обратите внимание, что в этом номере подстроки 11
и 13
перекрываются. Номер 3
также совпадает с номером 13
.
Легко доказать, что эта последовательность увеличивается, так как следующее число должно соответствовать всем критериям числа перед ним и иметь еще одну подстроку. Однако последовательность строго не увеличивается, как показывают результаты для n=10
и n=11
.
Вызов
Ваша цель - найти как можно больше простых чисел локализации. Ваша программа должна выводить их упорядоченным образом, начиная с 2 и увеличивая.
правила
- Вам разрешено жестко задавать простые числа.
- Вам не разрешается жестко кодировать простые числа содержания (
2
это единственное исключение) или любые магические числа, которые делают задачу тривиальной. Пожалуйста будь вежлив. - Вы можете использовать любой язык, который пожелаете. Пожалуйста, включите список команд, чтобы подготовить среду к выполнению кода.
- Вы можете использовать как процессор, так и графический процессор, и вы можете использовать многопоточность.
счет
Официальная оценка будет от моего ноутбука (Dell XPS 9560). Ваша цель - создать как можно больше простых чисел локализации за 5 минут.
Спекуляции
- 2,8 ГГц Intel Core i7-7700HQ (3,8 ГГц) 4 ядра, 8 потоков.
- 16 ГБ 2400 МГц DDR4 RAM
- NVIDIA GTX 1050
- Linux Mint 18.3 64-битный
Числа, найденные до сих пор, вместе с последним простым числом, добавленным к числу:
1 => 2 ( 2)
2 => 23 ( 3)
3 => 235 ( 5)
4 => 2357 ( 7)
5 => 112357 ( 11)
6 => 113257 ( 13)
7 => 1131725 ( 17)
8 => 113171925 ( 19)
9 => 1131719235 ( 23)
10 => 113171923295 ( 29)
11 => 113171923295 ( 31)
12 => 1131719237295 ( 37)
13 => 11317237294195 ( 41)
14 => 1131723294194375 ( 43)
15 => 113172329419437475 ( 47)
16 => 1131723294194347537 ( 53)
17 => 113172329419434753759 ( 59)
18 => 2311329417434753759619 ( 61)
19 => 231132941743475375961967 ( 67)
20 => 2311294134347175375961967 ( 71)
21 => 23112941343471735375961967 ( 73)
22 => 231129413434717353759619679 ( 79)
23 => 23112941343471735359619678379 ( 83)
24 => 2311294134347173535961967837989 ( 89)
25 => 23112941343471735359619678378979 ( 97)
26 => 2310112941343471735359619678378979 (101)
27 => 231010329411343471735359619678378979 (103)
28 => 101031071132329417343475359619678378979 (107)
29 => 101031071091132329417343475359619678378979 (109)
30 => 101031071091132329417343475359619678378979 (113)
31 => 101031071091131272329417343475359619678378979 (127)
32 => 101031071091131272329417343475359619678378979 (131)
33 => 10103107109113127137232941734347535961967838979 (137)
34 => 10103107109113127137139232941734347535961967838979 (139)
35 => 10103107109113127137139149232941734347535961967838979 (149)
36 => 1010310710911312713713914923294151734347535961967838979 (151)
Спасибо Ardnauld, Ourous и japh за расширение этого списка.
Обратите внимание, что n = 10
и n = 11
это одно и то же число, так как является самым низким числом, которое содержит все числа , но также содержит .
Для справки, вы можете использовать тот факт, что оригинальный скрипт Python, который я написал для генерации этого списка выше, вычисляет первые 12 терминов примерно за 6 минут.
Дополнительные правила
После того, как появились первые результаты, я понял, что есть хороший шанс, что лучшие результаты могут закончиться тем же результатом. В случае ничьей, победителем будет тот, у которого меньше всего времени для генерации своего результата. Если два или более ответов дают одинаково быстрый результат, это будет просто победа.
Конечная нота
5-минутное время выполнения ставится только для обеспечения справедливой оценки. Мне было бы очень интересно посмотреть, сможем ли мы продвинуть последовательность OEIS дальше (сейчас она содержит 17 чисел). С помощью кода Ourous я сгенерировал все числа до тех пор n = 26
, но я планирую позволить коду работать дольше.
Табло
- Python 3 + Google OR-Tools : 169
- Scala : 137 (неофициально)
- Concorde TSP solver : 84 (неофициальный)
- C ++ (GCC) + сборка x86 : 62
- Чистый : 25
- JavaScript (Node.js) : 24
n=11
тривиальным, так как вам просто нужно проверить, чтоn=10
также удовлетворяет новому условию. Я также утверждаю, что жесткое кодирование помогает только до тех порn=17
, пока , насколько мне удалось выяснить, не известны никакие числа за пределами этой точки.[1,22,234,2356,112356,113256,1131724,113171924,1131719234,113171923294,113171923294,1131719237294]
и начало поиска с каждогоОтветы:
Python 3 + Google OR-Tools , оценка 169 за 295 секунд (официальный результат)
Как это работает
После отбрасывания избыточных простых чисел, содержащихся в других простых числах, нарисуйте ориентированный граф с ребром от каждого простого числа до каждого из его суффиксов с нулевым расстоянием и ребром до каждого простого числа от каждого из его префиксов с расстоянием, определяемым количеством добавленных цифр. , Мы ищем лексикографически первый кратчайший путь через граф, начиная с пустого префикса, проходя через каждое простое число (но не обязательно через каждый префикс или суффикс) и заканчивая пустым суффиксом.
Например, вот ребра оптимального пути ε → 11 → 1 → 13 → 3 → 31 → 1 → 17 → ε → 19 → ε → 23 → ε → 29 → ε → 5 → ε для n = 11, соответствующие к выходной строке 113171923295.
По сравнению с простым решением проблемы коммивояжера , обратите внимание, что, соединяя простые числа косвенно через эти дополнительные узлы суффикса / префикса, а не напрямую друг с другом, мы значительно сократили число ребер, которые нам нужно рассмотреть. Но так как дополнительные узлы не нужно проходить ровно один раз, это уже не экземпляр TSP.
Мы используем средство расчета ограничений CP-SAT в Google OR-Tools, сначала чтобы минимизировать общую длину пути, а затем минимизировать каждую группу добавленных цифр по порядку. Мы инициализируем модель только с локальными ограничениями: каждое простое число предшествует одному суффиксу и следует один префикс, а каждый суффикс / префикс предшествует одному и тому же числу простых чисел. Полученная модель может содержать отключенные циклы; если это так, мы добавляем дополнительные ограничения связности динамически и перезапускаем решатель.
Код
Полученные результаты
Вот первые 1000 простых чисел защитной оболочки , рассчитанные за полтора дня в системе с 8 ядрами и 16 потоками.
источник
C ++ (GCC) + сборка x86, оценка
323662 за 259 секунд (официально)Результаты рассчитаны до сих пор. Мой компьютер исчерпал память после
65
.Все они согласуются с результатами решателя на основе Concorde , поэтому у них есть все шансы быть правильными.
Changelog:
Неправильный расчет необходимой длины контекста. Более ранняя версия была слишком большой, а также имела ошибку. Счет:
3234Добавлена равноправная контекстно-групповая оптимизация. Оценка:
3436Переработан алгоритм для правильного использования строк без контекста, а также некоторые другие оптимизации. Счет:
3662Добавлена правильная запись.
Добавлен вариант простых чисел.
Как это работает
Предупреждение: это мозговая свалка. Прокрутите до конца, если вы просто хотите код.
Сокращения:
Эта программа в основном использует учебный алгоритм динамического программирования для TSP.
Это много потенциальных ошибок. После того, как я поигрался с вступлением Ансельма и не сумел обмануть его, я должен хотя бы доказать, что мой общий подход верен.
Хотя решение на основе Concorde (намного, намного) быстрее, оно основано на одном и том же сокращении, поэтому это объяснение применимо к обоим. Кроме того, это решение может быть адаптировано для OEIS A054260 , простой последовательности, содержащей простые числа; Я не знаю, как решить это эффективно в рамках TSP. Так что это все еще несколько актуально.
Снижение TSP
Давайте начнем с того, что фактически докажем, что сокращение до TSP является правильным. У нас есть набор строк, скажем
и мы хотим найти самую маленькую суперструну, которая содержит эти элементы.
Зная длину достаточно
Для PCN, если есть несколько кратчайших строк, мы должны вернуть лексикографически наименьшую. Но мы рассмотрим другую (и более простую) проблему.
Если мы сможем решить SCS-Length, мы сможем восстановить наименьшее решение и получить PCN. Если мы знаем, что наименьшее решение начинается с нашего префикса, мы пытаемся расширить его, добавляя каждый элемент в лексикографическом порядке и снова решая для длины. Когда мы находим наименьший элемент, для которого длина решения одинакова, мы знаем, что это должен быть следующий элемент в наименьшем решении (почему?), Поэтому добавьте его и обработайте оставшиеся элементы. Этот метод достижения решения называется самоуничтожением .
Путешествие по графику максимального перекрытия
Предположим, мы начали решение СКС для приведенного выше примера вручную. Вероятно, мы бы:
13
и37
, потому что они уже подстроки других элементов. Любое решение, которое содержит137
, например, также должно содержать13
и37
.113,137 → 1137
,211,113 → 2113
и т.д.Это на самом деле правильно, но давайте докажем это для полноты картины. Возьмите любое решение СКС; например, самая короткая суперструнных для
A
ISи он может быть разложен на объединение всех элементов в
A
:(Мы игнорируем избыточные элементы
13, 37
.) Обратите внимание, что:Мы покажем, что каждая кратчайшая суперструна может быть разложена таким образом:
Для каждой пары смежных элементов
x,y
,y
начинаются и заканчиваются на более поздних позициях , чемx
. Если это не так, то либоx
является подстрокой,y
либо наоборот. Но мы уже удалили все элементы, которые являются подстрока, так что это не может произойти.Предположим, что смежные элементы в последовательности имеют перекрытие меньше максимального, например,
21113
вместо2113
. Но это сделало бы1
лишнее. Никакой более поздний элемент не нуждается в начальном1
(как в 2 1 113), потому что это происходит раньше113
, и все элементы, которые появляются после,113
не могут начинаться с цифры до113
(см. Пункт 1). Подобный аргумент предотвращает использование последнего дополнительного1
(как в 211 1 3) любым элементом ранее211
. Но наша самая короткая суперструна, по определению, не будет иметь избыточных цифр, поэтому таких немаксимальных перекрытий не будет.С помощью этих свойств мы можем преобразовать любую проблему SCS в TSP:
x
,y
добавьте край отx
кy
, вес которого количество дополнительных символов , добавленного путем добавленияy
кx
с максимальным перекрытием. Например, мы добавили бы ребро от211
до113
с весом 1, потому что2113
добавляет еще одну цифру211
. Повторите для края отy
доx
.Любой путь на этом графе, начиная с исходного префикса, соответствует конкатенации с максимальным перекрытием всех элементов на этом пути, а общий вес пути равен длине конкатенированной строки. Поэтому каждый тур с наименьшим весом, который посещает все предметы хотя бы один раз, соответствует самой короткой суперструне.
И это сокращение от SCS (и SCS-Length) до TSP.
Алгоритм динамического программирования
Это классический алгоритм, но мы его немного изменим, так что вот небольшое напоминание.
(Я написал это как алгоритм для SCS-Length вместо TSP. Они по сути эквивалентны, но словарь SCS помогает, когда мы добираемся до специфических для SCS оптимизаций.)
Вызовите набор элементов ввода
A
и заданный префиксP
. Для каждогоk
-элементного подмножестваS
вA
, и каждый элементe
изS
, мы вычислить длину самой короткой строки , которая начинается сP
, содержит всеS
и заканчиваетсяe
. Это включает в себя сохранение таблицы от значений(S, e)
до их SCS-длины.Когда мы дойдем до каждого подмножества
S
, таблица должна уже содержать результатыS - {e}
для всехe
вS
. Поскольку таблица может быть довольно большой, я вычисляю результаты для всехk
подэлементов, затемk+1
и т. Д. Для этого нам нужно только сохранить результаты дляk
иk+1
в любое время. Это уменьшает использование памяти примерно в два разаsqrt(|A|)
.Еще одна деталь: вместо вычисления минимальной длины SCS, я фактически вычисляю максимальное общее перекрытие между элементами. (Чтобы получить длину SCS, просто вычтите общее перекрытие из суммы длин элементов.) Использование перекрытий помогает в некоторых из следующих оптимизаций.
[2.] Контексты предметов
Контекст является самым длинным суффиксом элемента , который может перекрываться с следующими пунктами. Если наши элементы есть
113,211,311
, то11
это контекст для211
и311
. (Это также префиксный контекст для113
, который мы рассмотрим в части [4.])В приведенном выше алгоритме DP мы отслеживали решения SCS, которые заканчиваются каждым элементом, но на самом деле нам все равно, на каком элементе заканчивается SCS. Все, что нам нужно знать, это контекст. Таким образом, например, если два SCS для одного и того же набора оканчиваются на,
23
и43
любая SCS, которая продолжается от одного, также будет работать для другого.Это значительная оптимизация, потому что нетривиальные простые числа заканчиваются только цифрами
1 3 7 9
. Четыре однозначных контекста1,3,7,9
(плюс пустой контекст) на самом деле достаточно для вычисления PCN для простых чисел вплоть до131
.[3.] Контекстные элементы
Другие уже указали, что многие простые числа начинаются с цифр
2,4,5,6,8
, таких как23,29,41,43...
. Ни один из них не может перекрываться с предыдущим штрихом ( в стороне от2
и5
, простых числа не могут заканчиваться в этих цифрах,2
и5
уже было удалены в качестве избыточного). В коде они упоминаются как строки без контекста .Если в нашем входе есть контекстно-свободные элементы, каждое решение SCS можно разбить на блоки
и перекрытия в каждом блоке не зависят от других блоков. Мы можем перетасовать блоки или поменять их местами между блоками, имеющими одинаковый контекст, без изменения длины SCS.
Таким образом, нам нужно только отслеживать возможные мультимножества контекстов, по одному на каждый блок.
Полный пример: для простых чисел менее 100 у нас есть 11 контекстно-свободных элементов и их контексты:
Наш начальный мультимножественный контекст:
Код именует их как комбинированные контексты или ccontexts . Затем нам нужно рассмотреть только подмножества оставшихся элементов:
[4.] Слияние контекста
Как только мы получим простые числа с 3 цифрами или более, есть больше избыточностей:
Эти группы имеют одинаковый начальный и конечный контексты (обычно - это зависит от того, какие другие простые числа входят во входные данные), поэтому они неразличимы при перекрытии других элементов. Мы заботимся только о перекрытиях, поэтому мы можем рассматривать простые числа в этих группах с равным контекстом как неразличимые. Теперь наши подмножества DP сгущаются в мультисубсеты
(Именно поэтому решатель максимизирует длину перекрытия, а не минимизирует длину SCS: эта оптимизация сохраняет длину перекрытия.)
Резюме: оптимизация высокого уровня
Запуск с
INFO
выводом отладки выведет статистикуЭта конкретная строка предназначена для длины SCS первых 62 простых чисел,
2
до293
.1,3,7,11,13,27
плюс пустая строка.43,47,53,59,61,89,211,223,227,229,241,251,257,263,269,281,283
. Эти и данный префикс (в данном случае пустая строка) образуют основу исходного комбинированного контекста .N_search
) есть 16 нетривиальных групп с равным контекстом .Используя эти структуры, для расчета длины SCS необходимо проверить только 8498336
(multiset, ccontext)
комбинаций. Простое динамическое программирование будет предпринимать43×2^43 > 3×10^14
шаги, а грубое форсирование6×10^52
перешагивает шаги. Программе по-прежнему нужно запускать SCS-Length еще несколько раз, чтобы восстановить решение PCN, но это не займет много времени.[5., 6.] Низкоуровневые оптимизации
Вместо выполнения строковых операций решатель длины SCS работает с индексами элементов и контекстов. Я также предварительно вычисляю количество совпадений между каждым контекстом и парой элементов.
В коде изначально использовались GCC
unordered_map
, которые кажутся хэш-таблицами со связанными списками и размерами простых хешей (т.е. дорогими делениями). Поэтому я написал свою собственную хеш-таблицу с линейным зондированием и степенями двух размеров. Это обеспечивает 3-кратное ускорение и 3-кратное уменьшение памяти.Каждое состояние таблицы состоит из множества элементов, объединенного контекста и количества перекрытий. Они упакованы в 128-битные записи: 8 для счетчика перекрытий, 56 для мультимножества (как набор битов с кодированием длины серии) и 64 для ccontext (RLE с 1 разделителем). Кодирование и декодирование ccontext было самой сложной частью, и я закончил тем, что использовал новую
PDEP
инструкцию (она настолько нова, что у GCC пока нет встроенной функции).Наконец, когда он
N
становится большим , доступ к хеш-таблице очень медленный , потому что таблица больше не помещается в кеш. Но единственная причина, по которой мы записываем данные в хэш-таблицу, заключается в обновлении наиболее известного количества перекрытий для каждого состояния. Программа разбивает этот шаг на очередь предварительной выборки, и внутренний цикл выполняет предварительную выборку каждой таблицы за несколько итераций, прежде чем фактически обновить этот слот. Еще одно ускорение на моем компьютере.Бонус: дальнейшие улучшения
АКА Как Конкорд так быстро?
Я не знаю много об алгоритмах TSP, так что это приблизительное предположение.
Concorde использует метод ветвления и обрезки для решения TSP.
Очевидные идеи, которые мы могли бы попробовать:
Однако комбинация ветвления и обрезки очень мощная, поэтому мы не сможем превзойти современный метод решения, такой как Concorde, для больших значений
N
.Бонусный бонус: простые простые условия сдерживания
В отличие от решения на основе Concorde, эту программу можно изменить, чтобы найти наименьшее число, содержащее простые числа ( OEIS A054260 ). Это включает в себя три изменения:
При восстановлении решения из SCS-Length проверьте, является ли решение также простым числом. Если нет, вернитесь назад и попробуйте другой порядок. Существует достаточно много простых чисел ( плотность ), поэтому обычно это удается быстро. Тем не менее, если у PCN окажется сумма цифр, делимая на 3, то PCN (и многие из его перестановок родного брата) будут делиться на 3. Чтобы не застрять в этой ситуации, мы также ...1 / лн( н )
Измените код решателя длины SCS, чтобы классифицировать решения в зависимости от того, делятся ли их суммы цифр на 3. Это включает добавление другой записи, суммы цифр mod 3, к каждому состоянию DP. Это значительно уменьшает шансы того, что основной решатель застрянет с непростыми перестановками. Это изменение, которое я не смог понять, как перевести на TSP. Он может быть закодирован с помощью ILP, но тогда мне нужно будет узнать об этой вещи, называемой «неравенством субтуров», и о том, как ее генерировать.
Может случиться так, что все самые короткие PCN делятся на 3. В этом случае наименьшее простое простое содержание должно быть как минимум на одну цифру длиннее PCN. Если наш решатель длины SCS обнаруживает это, код восстановления решения может добавить одну дополнительную цифру в любой точке процесса. Он пытается добавить каждую возможную цифру
0..9
и каждый оставшийся элемент в текущий префикс решения в лексикографическом порядке, как и раньше.С этими изменениями я могу получить решения до
N=62
. За исключением случаев47
, когда код восстановления застревает и сдается после 1 миллиона шагов (пока не знаю почему). Основными простыми числами сдерживания являются:Код
Компилировать с
Для версии с простым числом, также ссылка на GMPlib, например
Эта программа использует инструкцию PDEP, которая доступна только на последних (Haswell +) процессорах x86. И мой компьютер, и MaxB поддерживают его. Если у вас нет, программа будет компилироваться в медленной версии программного обеспечения. Когда это произойдет, будет напечатано предупреждение о компиляции.
Попробуйте онлайн!
И версия только для TIO . Извините, но я не играл в гольф в этих программах, и есть ограничение по длине поста.
источник
debug_dummy
, вы можете использовать#define DEBUG(x) void(0)
.debug_dummy
потому что хочу, чтобы аргументы были проверены и оценены, даже когда отладка выключена.N=32
мне нужно только около 500 МБ.main
, но я нашел его по ссылке TIO.JavaScript (Node.js) , оценка 24 за 241 секунду
Полученные результаты
Алгоритм
Это рекурсивный поиск, который пробует все возможные способы объединения чисел и, в конечном итоге, сортирует результирующие списки в лексикографическом порядке, когда достигается конечный узел.
В начале каждой итерации любая запись, которая может быть найдена в другой записи, удаляется из списка.
Значительное ускорение было достигнуто за счет отслеживания посещенных узлов, поэтому мы можем прервать работу на ранней стадии, когда разные операции приводят к одному и тому же списку.
Небольшое ускорение было достигнуто путем обновления и восстановления списка, когда это возможно, а не создания копии, как это было предложено
анонимным пользователемНилом.пример
Код
Попробуйте онлайн!
источник
Concorde TSP solver , оценка 84 за 299 секунд
Ну ... я чувствую себя глупо только потому, что понял это сейчас.
Все это, по сути, проблема коммивояжера . Для каждой пары простых чисел
p
иq
добавьте ребро, вес которого равен количеству добавленных цифрq
(удаляя перекрывающиеся цифры). Кроме того, добавьте начальное ребро к каждому простомуp
числу, вес которого равен длинеp
. Кратчайший путь коммивояжера соответствует длине наименьшего основного номера содержания.Тогда решатель TSP промышленного класса, такой как Concorde , справится с этой проблемой.
Эта запись, вероятно, должна рассматриваться как не конкурирующая.
Полученные результаты
Решатель получает
N=350
около 20 процессорных часов. Полные результаты слишком длинны для одного поста SE, и OEIS все равно не хочет так много терминов. Вот первые 200:Код
Вот скрипт Python 3 для многократного вызова решателя Concorde до тех пор, пока он не создаст решения.
Concorde бесплатен для академического использования. Вы можете загрузить исполняемый двоичный файл Concorde, созданный с использованием собственного пакета линейного программирования QSopt, или, если у вас есть лицензия на IBM CPLEX, вы можете собрать Concorde из исходного кода для использования CPLEX.
источник
Чистота , оценка 25 за 231 секунду (официальный результат)
Полученные результаты
1 < n <= 23
в4236 секунд на TIOn = 24 (2311294134347173535961967837989)
за3224 секунды на местеn = 25 (23112941343471735359619678378979)
за210160 секунд на местеn = 1
чтобыn = 25
был найден в 231 секунд для официального озвучивания ( под редакцией maxb)При этом используется подход, аналогичный JS-решению Арнаулда, основанный на отклонении рекурсивной перестановки, с использованием специализированного набора деревьев для увеличения скорости.
Для каждого простого числа, которое должно вписаться в число:
Затем, для каждой пары подстрок, к которым мы присоединились, удалите все подстроки этой объединенной пары из списка подстрок и рекурсируйте по нему.
Как только никакие подстроки не могут быть присоединены к любым другим подстрокам на любом плече нашей рекурсии, мы используем уже упорядоченный набор деревьев, чтобы быстро найти наименьшее число, содержащее подстроки.
Что нужно улучшить / добавить:
Были значительные падения производительности между
19 -> 20
и24 -> 25
из-за дублирования обработки на этапе пробного слияния и этапа отклонения кандидата, но они были исправлены.Оптимизации:
removeOverlap
предназначен для того, чтобы всегда отдавать набор подстрок уже в оптимальном порядкеuInsertMSpec
уменьшает check-if-is-member и insert-new-member до одного обхода набораcontainmentNumbersSt
проверяет, работает ли предыдущее решение для нового номераПопробуйте онлайн!
Сохранить в
main.icl
и скомпилировать с:clm -fusion -b -IL Dynamics -IL StdEnv -IL Platform main
Это создает файл,
a.out
который должен быть запущен какa.out -h <heap_size>M -s <stack_size>M
, где<heap_size> + <stack_size>
находится память, которая будет использоваться программой в мегабайтах.(Я обычно устанавливаю стек в 50 МБ, но у меня редко есть программы, которые используют так много)
источник
Скала , оценка 137Редактировать:
Код здесь упрощает проблему.
Таким образом, решение работает для многих входов, но не для всех.
Исходное сообщение:
Основная идея
Более простая проблема
Сначала мы генерируем множество простых чисел и удаляем все, что уже является подстрокой других. Затем мы можем применить несколько правил, т. Е. Если есть только одна строка, заканчивающаяся в последовательности, и только одна строка, начинающаяся с этой же последовательности, мы можем объединить их. Другой вариант: если строка начинается и заканчивается в той же последовательности (что и 101), мы можем добавить / добавить ее к другой строке, не изменяя ее конец. (Эти правила действуют только при определенных условиях, поэтому будьте осторожны при их применении)
Настоящая проблема
10103
0
10103
1
Таким образом, если бы правила в вышеприведенном алгоритме были всегда достаточными, было бы показано, что задача не является NP-трудной.
findSeq
Попробуй онлайн
Код
Как отметил Андерс Касеорг в комментариях, этот код может возвращать неоптимальные (а значит, неверные) результаты.
Полученные результаты
187
188
189
193
источник
1234
,3423
,2345
, вы создаете123453423
вместо оптимального12342345
.457, 571, 757
(все простые числа).findSeq
вернется7574571
за это, но самая короткая длина457571
. Итак, ваш подход - играть с огнем. Хотя голосовал за чистую смелость.