Word Spinner Puzzle


10

Это словесная загадка.

Ваша программа должна принимать два слова на стандартном вводе.
Слово одно - это начальное слово. Слово два - это последнее слово.

От начального слова вы должны достичь конечного слова, меняя / добавляя / удаляя одну букву за раз. После каждой модификации должно образовываться новое действительное слово. Добавленные буквы добавляются в начало или конец. Вы можете удалить буквы из любого места (но слово не должно опускаться ниже трех букв в длину). Примечание: вы не можете переставить буквы в одно слово.

Выходные данные программы - это последовательность слов, которые нужно получить от начального слова до конечного слова.

Пример:

Input:
    Post Shot

Output:
    Post
    cost
    coat
    goat
    got
    hot
    shot

Победитель:

  • Программа должна быть запущена за разумное время (менее 10 секунд).
  • Программа, которая может генерировать кратчайшие выходные последовательности призовых слов.
    • Цинк -> Кремний
  • Если более одной программы получает самую короткую последовательность, то самая короткая программа в символах (игнорируя пробелы).
  • Если у нас все еще есть более чем одна дата / время представления программы, должны использоваться.

Ноты:


может быть "post-> pot-> hot-> shot" короче.
ВЫ

@ S.Mark: Тогда ваш алгоритм превосходит мой, и вы выигрываете. Выше приведен пример возможного решения. Чем короче решение, тем лучше решение.
Мартин Йорк

намеренно? извини, я просто ошибся
ВЫ

2
Могу ли я решить эту проблему в Whitespace для размера программы 0?

@Tim Nordenfur: Я хотел бы видеть реализацию пробела. Запись. Есть два правила перед продолжительностью программы, чтобы определить победителя. Но если вы соответствуете этим требованиям :-)
Мартин Йорк,

Ответы:


2

Python, 288 символов

(не считая строки чтения словаря)

X=set(open('websters-dictionary').read().upper().split())

(S,E)=raw_input().upper().split()
G={S:0}
def A(w,x):
 if x not in G and x in X:G[x]=w
while E not in G:
 for w in G.copy():
  for i in range(len(w)):
   for c in"ABCDEFGHIJKLMNOPQRSTUVWXYZ":A(w,w[:i]+c+w[i+1:]);A(w,w[:i]+w[i+1:]);A(w,c+w);A(w,w+c)
s=''
while E:s=E+'\n'+s;E=G[E]
print s

за вызов zinkна silicon:

ZINK
PINK
PANK
PANI
PANIC
PINIC
SINIC
SINICO
SILICO
SILICON

В этом словаре есть несколько странных слов ...


Я на самом деле не проверял содержание. Я просто попытался найти словарь, который мог бы использовать каждый.
Мартин Йорк,

попробуйте с guester overturn(занимает некоторое время) или regatta gyrally(не возвращается) ;-)
Арно Ле Блан

Да, некоторые комбинации требуют времени. Время становится длиннее, а самое короткое решение - длиннее. И последнее не имеет решения - нет спецификации для того, что должно произойти в этом случае :) Хотя это довольно легко изменить, чтобы обработать его (сохраните дескриптор в G.copy () и сравните G с ним в конце цикла ).
Кит Рэндалл,

16

traceroute - 10 символов

traceroute 

подробно

post#traceroute shot

Type escape sequence to abort.
Tracing the route to shot (1.1.4.2)

  1 pot (1.1.1.2) 40 msec 68 msec 24 msec
  2 hot (1.1.3.2) 16 msec 32 msec 24 msec
  3 shot (1.1.4.2) 52 msec *  92 msec

Маршрутизаторы предварительно настроены с включенным OSPF и расположены таким образом.

введите описание изображения здесь

И да, мне нужно 233614 маршрутизаторов, чтобы полностью поддерживать все слова. :-)


Очень умно, но вы провалили правило 10 секунд. На настройку всех маршрутизаторов у вас уйдет больше 10 секунд. :-) Каков маршрут из: Цинк -> Силикон
Мартин Йорк

@Martin, пожалуйста, не обращайте внимания на время настройки, это как сборка словаря, хе-хе, маршруты для Zink -> Silicon, zink->pink->pank->pani->panic->pinic->sinic->sinico->silico->siliconя действительно пытаюсь использовать алгоритм Dijkstra (который используется в OSPF), и он может найти этот путь около 1 с, я буду опубликовать его в отдельном сообщении позже, как только я играю в гольф.
ВЫ

3

PHP - 886 689 644 612

Загрузка словаря:

<?php foreach(file('websters-dictionary') as $line) {
    $word = strtolower(trim($line));
    if (strlen($word) < 3) continue;
    $c[$word] = 1;
}

Фактический код (просто конкатат оба):

list($d,$e)=explode(' ',strtolower(trim(`cat`)));$f=range(@a,@z);function w($a,&$g){global$c;if(isset($c[$a]))$g[]=$a;}$h[$d]=$b=@levenshtein;$i=new SplPriorityQueue;$i->insert($d,0);$j[$d]=0;$k[$d]=$b($d,$e);while($h){if(isset($c[$l=$i->extract()])){unset($h[$l],$c[$l]);if($l==$e){for(;$m=@$n[$o[]=$l];$l=$m);die(implode("\n",array_reverse($o)));}for($p=strlen($l),$g=array();$p--;){w(substr_replace($q=$l,"",$p,1),$g);foreach($f as$r){$q[$p]=$r;w($q,$g);w($r.$l,$g);w($l.$r,$g);}}foreach($g as$m){$s=$j[$l]+1;if(!isset($h[$m])||$s<$j[$m]){$n[$m]=$l;$i->insert($m,-(($k[$m]=$b($m,$e))+$j[$m]=$s));}$h[$m]=1;}}}

Применение:

php puzzle.php <<< 'Zink Silicon'
# or
echo 'Zink Silicon'|php puzzle.php

Результат:

zink
pink
pank
pani
panic
pinic
sinic
sinico
silico
silicon
(0.23s)

Это должно выполняться менее чем за 0,5 секунды для «Zink Silicon» и менее чем за 1 секунду в большинстве случаев (иногда дольше, когда решения не существует, но оно все равно возвращается).

При этом используется алгоритм A * с расстоянием Левенштейна для оценки нижних границ расстояний.

Некоторые интересные тесты:

  • vas arm-> vas bas bar barm arm(со словом длиннее, чем начало и конец)
  • oxy pom -> oxy poxy poy pom
  • regatta gyrally -> (нет, но скрипт корректно завершается)
  • aal presolution -> +8 символов
  • lenticulated aal -> -9 символов
  • acarology lowness -> 46 прыжков
  • caniniform lowness -> 51 хмель
  • cauliform lowness -> 52 прыжков
  • overfoul lowness -> 54 прыжков
  • dance facia -> некоторые слова в пути имеют на 4 символа больше, чем оба начала / конца

Попробуйте Zink Silicon
Мартин Йорк,

Это должно работать, теперь :-)
Арно Ле Бланк

Я найду большую машину:PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 71 bytes)
Мартин Йорк,

Вы только что установили 128M memory_limit ;-) Попробуйте php -dmemory_limit=256M.
Арно Ле Бланк

had->handне является правильным ходом, вы можете только добавить письмо в начало или конец. То же самое для vest->verst:-)
Арно Ле Блан

3

питон

Так как я не мог сжать коды dijkstra, чтобы сжать их до нескольких сотен байтов, вот моя версия без загадок.

import sys, heapq, time

# dijkstra algorithm from 
# http://code.activestate.com/recipes/119466-dijkstras-algorithm-for-shortest-paths/
def dijkstra(G, start, end):
   def flatten(L):
      while len(L) > 0:
         yield L[0]
         L = L[1]

   q = [(0, start, ())]
   visited = set()
   while True:
      (cost, v1, path) = heapq.heappop(q)
      if v1 not in visited:
         visited.add(v1)
         if v1 == end:
            return list(flatten(path))[::-1] + [v1]
         path = (v1, path)
         for (v2, cost2) in G[v1].iteritems():
            if v2 not in visited:
               heapq.heappush(q, (cost + cost2, v2, path))

nodes = tuple(sys.argv[1:])

print "Generating connections,",
current_time = time.time()

words = set(x for x in open("websters-dictionary", "rb").read().lower().split() if 3 <= len(x) <= max(5, *[len(l)+1 for l in nodes]))

print len(words), "nodes found"

def error():
    sys.exit("Unreachable Route between '%s' and '%s'" % nodes)

if not all(node in words for node in nodes):
    error()

# following codes are modified version of
# http://norvig.com/spell-correct.html
alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits(word):
   splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
   deletes = [a + b[1:] for a, b in splits if b]
   replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]
   prepends = [c+word for c in alphabet]
   appends = [word+c for c in alphabet]
   return words & set(deletes + replaces + prepends + appends)

# Generate connections between nodes to pass to dijkstra algorithm
G = dict((x, dict((y, 1) for y in edits(x))) for x in words)

print "All connections generated, %0.2fs taken" % (time.time() - current_time)
current_time = time.time()

try:
    route = dijkstra(G, *nodes)
    print '\n'.join(route)
    print "%d hops, %0.2fs taken to search shortest path between '%s' & '%s'" % (len(route), time.time() - current_time, nodes[0], nodes[1])
except IndexError:
    error()

тесты

$ python codegolf-693.py post shot
Generating connections, 15930 nodes found
All connections generated, 2.09s taken
post
host
hot
shot
4 hops, 0.04s taken to search shortest path between 'post' & 'shot'

$ python codegolf-693.py zink silicon
Generating connections, 86565 nodes found
All connections generated, 13.91s taken
zink
pink
pank
pani
panic
pinic
sinic
sinico
silico
silicon
10 hops, 0.75s taken to search shortest path between 'zink' & 'silicon'

Добавлены тесты user300

$ python codegolf-693.py vas arm
Generating connections, 15930 nodes found
All connections generated, 2.06s taken
vas
bas
bam
aam
arm
5 hops, 0.07s taken to search shortest path between 'vas' & 'arm'

$ python codegolf-693.py oxy pom
Generating connections, 15930 nodes found
All connections generated, 2.05s taken
oxy
poxy
pox
pom
4 hops, 0.01s taken to search shortest path between 'oxy' & 'pom'

$ python codegolf-693.py regatta gyrally
Generating connections, 86565 nodes found
All connections generated, 13.95s taken
Unreachable Route between 'regatta' and 'gyrally'

Еще немного

$ python codegolf-693.py gap shrend
Generating connections, 56783 nodes found
All connections generated, 8.16s taken
gap
rap
crap
craw
crew
screw
shrew
shrewd
shrend
9 hops, 0.67s taken to search shortest path between 'gap' & 'shrend'

$ python codegolf-693.py guester overturn
Generating connections, 118828 nodes found
All connections generated, 19.63s taken
guester
guesten
gesten
geste
gest
gast
east
ease
erse
verse
verset
overset
oversee
overseed
oversend
oversand
overhand
overhard
overcard
overcare
overtare
overture
overturn
23 hops, 0.82s taken to search shortest path between 'guester' & 'overturn'

3 <= len(x) <= max(map(len, [nodea, nodeb]))гарантируется ли, что путь никогда не пройдет через слово длиннее, чем начальное и конечное слова?
Арно Ле Блан

Попробуй с oxy pom; кратчайший путь oxy->poxy->poy->pom. Также кажется, что вы разрешаете перестановки и вставки в любом месте, что недопустимо :-)
Arnaud Le Blanc

@ user300, исправлены части перестановок и вставок, я слишком много копировал, спасибо ;-), и я устанавливаю начальный лимит в 5 символов и позволяю +1 больше символов начала и конца, дайте мне знать, если это все еще будет проблемой. Спасибо.
ВЫ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.