Слово Spinner головоломки


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

Пітон, 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

слідовід - 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), і він може знайти цей шлях близько 1s, я буду опублікуйте його окремо, пізніше, як тільки я пограв у гольф.
ВИ

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 секунди для "Цинкового кремнію" і менше 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
Martin York

Це має спрацювати зараз :-)
Арно Ле Бланк

Я знайду більшу машину: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

Пітон

Оскільки я не міг коди гольф-дикстра, щоб стиснутись до кількох сотень байтів, ось моя нелетована версія.

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'

Додано тести користувача300

$ 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. Також здається, що ви дозволяєте перестановки та вставки в будь-якому місці, які заборонені :-)
Арно Ле Блан

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