Задача состоит в том, чтобы найти самую длинную цепочку английских слов, где первые 3 символа следующего слова соответствуют последним 3 символам последнего слова. Вы будете использовать общий словарь, доступный в дистрибутивах Linux, который можно скачать здесь:
https://www.dropbox.com/s/8tyzf94ps37tzp7/words?dl=0
который имеет 99171 английских слов. Если ваш локальный Linux /usr/share/dict/words
это тот же файл (имеет md5sum == cbbcded3dc3b61ad50c4e36f79c37084), вы можете использовать его.
Слова могут быть использованы только один раз в ответе.
РЕДАКТИРОВАТЬ: буквы должны точно соответствовать, включая верхний / нижний регистр, апострофы и ударения.
Пример правильного ответа:
idea deadpan panoramic micra craftsman mantra traffic fiche
который набрал бы 8 баллов.
Ответ с самой длинной действительной цепочкой слов будет победителем. В случае ничьей победит самый ранний ответ. Ваш ответ должен содержать цепочку слов, которые вы нашли, и (конечно) программу, которую вы написали для этого.
источник
Ответы:
Ява, эвристика в пользу вершины, которая порождает самый большой граф:
1825 18551873Код ниже выполняется менее чем за 10 минут и находит следующий путь:
Основные идеи
В Приближении длинных направленных путей и циклов , Бьорклунд, Хусфельдт и Ханна, Конспект лекций в области компьютерных наук (2004), 222-233, авторы предлагают, что в разреженных графах расширителей можно найти длинный путь с помощью жадного поиска, который выбирает в каждом шаг соседа текущего хвоста пути, который охватывает самый большой подграф в G ', где G' - исходный граф с удаленными вершинами в текущем пути. Я не уверен, что есть хороший способ проверить, является ли граф расширителем, но мы, конечно, имеем дело с разреженным графом, и поскольку его ядро составляет около 20000 вершин, а его диаметр составляет всего 15, у него должно быть хорошее свойства расширения. Поэтому я принимаю эту жадную эвристику.
Учитывая граф
G(V, E)
, мы можем найти, сколько вершин достижимо от каждой вершины, используя Флойд-Варшалл вTheta(V^3)
времени или используя алгоритм Джонсона воTheta(V^2 lg V + VE)
времени. Однако я знаю, что мы имеем дело с графом, который имеет очень большой сильно связанный компонент (SCC), поэтому я использую другой подход. Если мы идентифицируем SCC, используя алгоритм Тарьяна, то мы также получим топологическую сортировку для сжатого графаG_c(V_c, E_c)
, которая будет намного меньше поO(E)
времени. ПосколькуG_c
это DAG, мы можем вычислить достижимостьG_c
воO(V_c^2 + E_c)
времени. (Впоследствии я обнаружил, что на это намекают в упражнении 26-2.8 CLR ).Поскольку доминирующим фактором во времени выполнения является
E
, я оптимизирую его, вставляя фиктивные узлы для префиксов / суффиксов. Таким образом, вместо 151 * 64 = 9664 ребер от слов, заканчивающихся -res до слов, начинающихся с res-, у меня есть 151 ребро от слов, заканчивающихся -res до # res # и 64 ребер от # res # до слов, начинающихся с res- .И, наконец, поскольку на моем старом ПК каждый поиск занимает около 4 минут, я пытаюсь объединить результаты с предыдущими длинными путями. Это намного быстрее, и оказалось мое лучшее решение на данный момент.
Код
org/cheddarmonk/math/graph/Graph.java
:org/cheddarmonk/math/graph/MutableGraph.java
:org/cheddarmonk/math/graph/StronglyConnectedComponents.java
:org/cheddarmonk/ppcg/PPCG.java
:источник
Рубин, 1701
"Del" -> "ersatz's"
( полная последовательность )Попытка найти оптимальное решение оказалась слишком дорогой во времени. Так почему бы не выбрать случайные выборки, кэшировать то, что мы можем, и надеяться на лучшее?
Сначала строится a,
Hash
который отображает префиксы в полные миры, начиная с этого префикса (например"the" => ["the", "them", "their", ...]
). Затем для каждого слова в спискеsequence
вызывается метод . Он получает слова, которые могут последовать изHash
, берет образец100
и вызывает себя рекурсивно. Самый длинный взят и гордо показан. Начальное число для RNG (Random::DEFAULT
) и длина последовательности также отображаются.Мне пришлось запустить программу несколько раз, чтобы получить хороший результат. Этот конкретный результат был получен с семенами
328678850348335483228838046308296635426328678850348335483228838046308296635426
.скрипт
источник
0.0996
секунды.Оценка:
16311662 словаВы можете найти всю последовательность здесь: http://pastebin.com/TfAvhP9X
У меня нет полного исходного кода. Я пробовал разные подходы. Но вот некоторые фрагменты кода, которые должны быть способны генерировать последовательность примерно одинаковой длины. Извините, это не очень красиво.
Код (Python):
Сначала некоторая предварительная обработка данных.
Затем я определил рекурсивную функцию (поиск в глубину).
Конечно, это занимает слишком много времени. Но через некоторое время он нашел последовательность из 1090 элементов, и я остановился.
Следующее, что нужно сделать, это локальный поиск. Для каждого из двух соседей n1, n2 в последовательности я пытаюсь найти последовательность, начинающуюся с n1 и заканчивающуюся на n2. Если такая последовательность существует, я ее вставляю.
Конечно, мне также пришлось остановить программу вручную.
источник
PHP,
17421795Я возился с PHP на этом. Уловка определенно отбрасывает список к приблизительно 20 000, которые фактически действительны, и просто выбрасывает остальное. Моя программа делает это итеративно (некоторые слова, которые она выбрасывает в первой итерации, означают, что другие больше не действительны) в начале.
Мой код ужасен, он использует несколько глобальных переменных, он использует слишком много памяти (он хранит копию всей таблицы префиксов для каждой итерации), и потребовались буквально дни, чтобы найти мой лучший результат, но он все еще справляется быть победителем - пока. Он начинается довольно быстро, но с течением времени он становится все медленнее и медленнее.
Очевидным улучшением было бы использование сиротского слова для начала и конца.
В любом случае, я действительно не знаю, почему мой список вставок был перенесен в комментарий, он вернулся как ссылка на вставку, так как теперь я включил свой код.
http://pastebin.com/Mzs0XwjV
источник
Питон:
1702-1704- 1733 словаЯ использовал Dict, чтобы сопоставить все префиксы со всеми словами, как
Отредактируйте небольшое улучшение: удаление всех
useless
слов в начале, если их суффиксов нет в списке префиксов (очевидно, это будет конечное слово)Затем возьмите слово в списке и просмотрите карту префиксов, как узел дерева.
Программе нужно несколько слов, чтобы узнать, когда остановиться, можно найти как
1733
в методеcheckForNextWord̀
Программе нужен путь к файлу в качестве аргумента
Не очень питонно, но я пытался.
Для вычисления этой последовательности потребовалось менее 2 минут: полный вывод :
источник
Оценка:
2495001001Вот мой код:
Изменить: 1001:
http://pastebin.com/yN0eXKZm
Изменить: 500:
источник
Mathematica
14821655С чего начать ...
Ссылки - это префиксы пересечений и суффиксы для слов.
Края - это все направленные ссылки от слова к другим словам:
Найдите путь между «исправлением» и «изюминкой».
Результат (1655 слов)
источник
Питон, 90
Сначала я очищаю список вручную, удалив все
это стоит мне максимум 2 пункта, потому что эти слова могут быть только в начале или в конце цепочки, но это сокращает список слов на 1/3, и мне не нужно иметь дело с юникодом.
Затем я создаю список всех пре- и суффиксов, нахожу перекрытие и отбрасываю все слова, если только пре- и суффикс не входит в набор перекрытий. Опять же, это сбивает не более 2 баллов с моей максимально достижимой оценки, но сокращает список слов до трети от исходного размера (попробуйте запустить свой алгоритм на short_list для возможного ускорения), а остальные слова сильно связаны (за исключением некоторых 3 Буквенные слова, которые связаны только с собой). Фактически, почти любое слово может быть достигнуто из любого другого слова по пути со средним числом 4 ребер.
Я храню количество ссылок в матрице смежности, которая упрощает все операции и позволяет мне делать классные вещи, такие как просмотр на n шагов вперед или подсчет циклов ... по крайней мере в теории, поскольку для возведения в квадрат матрицы, которая на самом деле не выполняется, требуется около 15 секунд это во время поиска. Вместо этого я начинаю со случайного префикса и хожу случайно, либо выбирая окончание равномерно, отдавая предпочтение тем, которые встречаются часто (например, «-ing»), или тем, которые встречаются реже.
Все три варианта сосут одинаково и производят цепи в диапазоне 20-40, но по крайней мере это быстро. Думаю, я должен добавить рекурсию в конце концов.
Изначально я хотел попробовать что-то похожее на это но так как это ориентированный граф с циклами, ни один из стандартных алгоритмов для топологической сортировки, самого длинного пути, самого большого эйлерова пути или китайской проблемы почтальона не работает без серьезных модификаций.
И только потому, что это выглядит красиво, вот изображение матрицы смежности M, M ^ 2 и M ^ бесконечность (бесконечность = 32, впоследствии она не меняется) с белыми = ненулевыми записями
источник