Это было написано как часть Первой Периодической Премьер-программы .
Игра
Начальное и конечное слово одинаковой длины. Цель игры состоит в том, чтобы изменить одну букву в начальном слове, чтобы сформировать другое допустимое слово, повторяя этот шаг до достижения конечного слова, используя наименьшее количество шагов. Например, учитывая слова TREE и FLED, результат будет:
TREE
FREE
FLEE
FLED
2
Характеристики
- Статьи из Википедии для OWL или SOWPODS могут быть полезной отправной точкой для составления списков слов.
- Программа должна поддерживать два способа выбора начального и конечного слов:
- Определяется пользователем с помощью командной строки, стандартного ввода или любого другого, подходящего для вашего языка (просто укажите, что вы делаете).
- Выбор 2 случайных слов из файла.
- Начальные и конечные слова, а также все промежуточные слова должны быть одинаковой длины.
- Каждый шаг должен быть напечатан в своей строке.
- Последняя строка вашего вывода должна содержать количество промежуточных шагов, необходимых для перехода между начальным и конечным словами.
- Если не удается найти совпадение между начальным и конечным словами, выходные данные должны состоять из 3 строк: начальное слово, конечное слово и слово OY.
- Включите в свой ответ обозначение Big O для вашего решения
- Пожалуйста, включите 10 уникальных пар начальных и конечных слов (с их выводом, конечно), чтобы показать шаги, которые производит ваша программа. (Чтобы сэкономить место, в то время как ваша программа должна выводить их в отдельных строках, вы можете объединить их в одну строку для публикации, заменяя новые строки пробелами и запятой между каждым запуском.
Цели / Критерии победы
- Победит самое быстрое / лучшее решение Big O, обеспечивающее кратчайшие промежуточные этапы за одну неделю.
- Если в результате критерия «Большой О» выбрана ничья, победит самый короткий код.
- Если все еще есть ничья, победит первое решение, достигшее самой быстрой и самой короткой ревизии.
Тесты / Образец Вывода
DIVE
DIME
DAME
NAME
2
PEACE
PLACE
PLATE
SLATE
2
HOUSE
HORSE
GORSE
GORGE
2
POLE
POSE
POST
PAST
FAST
3
Проверка
Я работаю над сценарием, который можно использовать для проверки выходных данных.
Это будет:
- Убедитесь, что каждое слово является действительным.
- Убедитесь, что каждое слово точно на 1 букву отличается от предыдущего слова.
Он не будет:
- Убедитесь, что было использовано самое короткое количество шагов.
Как только я получу это, я, конечно, обновлю этот пост. (:
code-challenge
word-puzzle
1p5
Ребекка Чернофф
источник
источник
HOUSE
доGORGE
, указывается как 2. Я понимаю, что есть 2 промежуточных слова, так что это имеет смысл, но число операций было бы более интуитивно понятным.The fastest/best Big O solution producing the shortest interim steps after one week will win.
поскольку вы не можете гарантировать, что самое быстрое решение - это то, которое использует наименьшее количество шагов, вы должны предоставить предпочтение, если одно решение использует меньше шагов, но достигает цели позже.BAT
иCAT
будет ноль шагов, верно?Ответы:
Поскольку длина указана в качестве критерия, вот версия для гольфа с 1681 символом (вероятно, все еще может быть улучшена на 10%):
Версия ungolfed, которая использует имена пакетов и методы и не дает предупреждений или расширяет классы только для их псевдонимов, такова:
Как видите, анализ текущих затрат
O(filelength + num_words * hash + V * n * (n + hash) + E * hash)
. Если вы примете мое предположение, что вставка / поиск в хэш-таблице является постоянным временем, это такO(filelength + V n^2 + E)
. Конкретная статистика графиков в SOWPODS означает, что этоO(V n^2)
действительно доминируетO(E)
для большинстваn
.Пример выходов:
ИДОЛА, ИДОЛЫ, ИДИЛЫ, ОДИЛЫ, ОДАЛЫ, ОВАЛЫ, СУМКИ, ДУХОВКИ, ДАЖЕ, ЭТЕНС, СТЕНЫ, КОЖИ, КОЖИ, СПИНЫ, СПИНЬ, 13
WICCA, PROSY, OY
BRINY, BRINS, TRINS, TAINS, TARNS, YARNS, YAWNS, YAWPS, YAPPS, 7
ГАЛЕЙ, ГАЗЫ, ГАСТЫ, ГАСТЫ, GESTE, GESSE, DESSE, 5
SURES, DURES, DUNES, DINES, DINGS, DINGY, 4
СВЕТ, СВЕТ, СВЕТ, БОЛЬШОЙ, БИГОС, БИРОС, ГИРОС, ДЕВУШКИ, ГУРНЫ, ГУАНЫ, ГУАНА, РУАНА, 10
SARGE, SERGE, SERRE, SERRS, SEERS, DEERS, DYERS, OYERS, OVERS, OVELS, овалы, ODALS, ODYLS, IDYLS, 12
КИРСЫ, SEIRS, SEERS, ПИВО, BRERS, BRERE, BREME, КРЕМ, КРЕП, 7
Это одна из 6 пар с самым длинным кратчайшим путем:
GAINEST, FAINEST, FAIREST, SAIREST, SAIDEST, SADDEST, MADDEST, MIDDEST, MILDEST, WILDEST, WILIEST, WILIEST, WIIEST, CANIEST, CANTEST, КОНКУРС, КОНФЕСС, КОНФЕРСЫ, КОНКЕРЫ, КУХНИ, КУПЕРЫ, КОТЛЫ, КОПЫ, POPPITS, маки, POPSIES, MOPSIES, MOUSIES, муссы, POUSSES, плюсы, PLISSES, PRISSES, прессы, PREASES, уреазы, UNEASES, UNCASES, бескорпусный, UNBASED, UNBATED, Разъединенный, UNMETED, UNMEWED, ENMEWED, ENDEWED, INDEWED, индексированный, УКАЗАТЕЛИ, УКАЗАНИЯ, УКАЗАНИЯ, ОТНОШЕНИЯ, ИНВЕСТЫ, ИНФЕСТЫ, ИНФЕКЦИИ, ВСТАВКИ, 56
И одна из разрешимых 8-буквенных пар в худшем случае:
ENROBING, UNROBING, UNROBING, UNCOPING, UNCINGING, UNCAGING, ENCAGING, ENRACING, ENLACING, UNLACING, UNLAY, UPLING, SPLAY, SPRAY, STRAYING, STROYING, STROBING, STINGINGING, STINGPING, STINGPING, STINGPING, STINGINGING Обжимные, хрустящие, хрустящие, хрустящие, хрустящие, скребки, скребки, скреперы, скреперы, скребки, скребки, молния, молния, мятеж, мятеж, мятежник, мятежник, мятежник, мятежник ЛАНЧЕРЫ, ЛИНЧЕРЫ, ЛИНЧЕТЫ, ЛИНЧЕТЫ, 52
Теперь, когда я думаю, что у меня есть все требования этого вопроса, моя дискуссия.
Для CompSci вопрос, очевидно, сводится к кратчайшему пути в графе G, вершинами которого являются слова, а ребра которого соединяют слова, отличающиеся одной буквой. Эффективное создание графа не тривиально - у меня действительно есть идея, которую я должен пересмотреть, чтобы уменьшить сложность до O (V n hash + E). То, как я это делаю, включает в себя создание графа, который вставляет дополнительные вершины (соответствующие словам с одним символом подстановки) и гомеоморфен рассматриваемому графу. Я подумал об использовании этого графа, а не о сокращении до G - и я полагаю, что с точки зрения игры в гольф я должен был это сделать - исходя из того, что подстановочный узел с более чем 3 ребрами уменьшает число ребер в графе, и Стандартное время выполнения алгоритмов кратчайшего пути составляет
O(V heap-op + E)
.Тем не менее, первое, что я сделал, - запустил анализ графиков G для разных длин слов, и я обнаружил, что они чрезвычайно редки для слов из 5 или более букв. 5-буквенный граф имеет 12478 вершин и 40759 ребер; добавление узлов ссылок ухудшает график. К тому времени, когда у вас до 8 букв, ребер меньше, чем узлов, и 3/7 слов «в стороне». Поэтому я отклонил эту идею оптимизации как не очень полезную.
Идея, которая оказалась полезной, состояла в том, чтобы изучить кучу. Я могу честно сказать, что я реализовал несколько умеренно экзотических куч в прошлом, но ни одна из них не была такой экзотической, как эта. Я использую A-star (поскольку C не дает никакой пользы, учитывая кучу, которую я использую) с очевидной эвристикой количества букв, отличных от цели, и небольшой анализ показывает, что в любой момент времени не более 3 различных приоритетов в кучу. Когда я открываю узел с приоритетом (стоимость + эвристика) и смотрю на его соседей, я рассматриваю три случая: 1) стоимость соседа равна стоимости + 1; эвристика соседа - эвристика-1 (потому что буква, которую она меняет, становится «правильной»); 2) стоимость + 1 и эвристика + 0 (потому что буква, которую она меняет, переходит от «неправильно» к «все еще неправильно»; 3) стоимость + 1 и эвристика + 1 (потому что буква, которую она меняет, переходит от «правильной» к «неправильной»). Поэтому, если я расслаблю соседа, я собираюсь вставить его с тем же приоритетом, приоритетом + 1 или приоритетом + 2. В результате я могу использовать массив из 3-х элементов связанных списков для кучи.
Я должен добавить примечание о моем предположении, что поиск хеша является постоянным. Хорошо, вы можете сказать, но как насчет хэш-вычислений? Ответ в том, что я их амортизирую:
java.lang.String
кэширует ихhashCode()
, поэтому общее время, затрачиваемое на вычисление хэшей, составляетO(V n^2)
(при создании графика).Есть еще одно изменение, которое влияет на сложность, но вопрос о том, является ли это оптимизацией или нет, зависит от ваших предположений о статистике. (IMO, ставя «лучшее решение Big O» в качестве критерия, является ошибкой, потому что нет лучшей сложности по простой причине: не существует единственной переменной). Это изменение влияет на шаг генерации графика. В приведенном выше коде это:
Это
O(V * n * (n + hash) + E * hash)
. Но этаO(V * n^2)
часть получается из генерации новой строки из n символов для каждой ссылки и последующего вычисления ее хеш-кода. Этого можно избежать с помощью вспомогательного класса:Тогда первая половина генерации графа становится
Используя структуру хеш-кода, мы можем генерировать ссылки в
O(V * n)
. Тем не менее, это имеет эффект удара. Мое предположение о том, что поиск по хешу является постоянным временем, предполагает, что сравнение объектов на равенство обходится дешево. Тем не менее, тест на равенство LinkO(n)
в худшем случае. Худший случай - когда у нас есть столкновение хешей между двумя равными ссылками, сгенерированными из разных слов - т.е. это происходитO(E)
раз во второй половине генерации графа. Кроме этого, за исключением маловероятного случая столкновения хэша между неравными ссылками, мы хороши. Итак, мы обменялисьO(V * n^2)
наO(E * n * hash)
. Смотрите мой предыдущий пункт о статистике.источник
Джава
Сложность : (У меня нет степени CompSci, поэтому я был бы признателен за помощь в этом вопросе.)
Ввод : укажите пару слов (более 1 пары, если хотите) в командной строке. Если командная строка не указана, выбираются 2 разных случайных слова.
источник
System.nanoTime()
.c на Unix
Используя алгоритм Дейкстры.
Большая часть кода представляет собой реализацию костюмного n-арного дерева, которая служит для хранения
Любой заинтересованный в том , как это работает , вероятно , следует прочитать
findPath
,process
иprocessOne
(и связанные с ними комментарии). А может бытьbuildPath
иbuildPartialPath
. Остальное - бухгалтерия и строительные леса. Несколько подпрограмм, используемых во время тестирования и разработки, но не в «производственной» версии, остались на месте.Я использую
/usr/share/dict/words
на моем Mac OS 10.5 ящик, который имеет так много длинных, эзотерические записи, позволяя ему работать полностью случайным образом генерирует много изOY
с.Некоторый вывод:
Анализ сложности нетривиален. Поиск является двусторонним, итеративным углублением.
W
.S_min = (<number of different letter>-1)
что если мы на расстоянии только одной буквы, мы оцениваем изменение в 0 промежуточных шагов. Максимум трудно измерить, см. Выше «ТРИКИ - ОГОНЬ». Каждая половина дерева будетS/2-1
вS/2
B
.Таким образом, минимальное количество операций около
2 * (S/2)^B * W
, не очень хорошо.источник
O(|V|+|E|)
вместоO(|E|+|V| log |V|)
?