Разложить слова на другие слова (например, «послесвечение» = «в кормовой части» + «эрг» + «низкий»)

13

Вот один для всех вас словесников! Напишите программу или функцию, которая берет список слов и создает список всех возможных конкатенативных разложений для каждого слова. Например:

(Примечание: это только небольшая выборка для иллюстративных целей. Фактический результат гораздо более объемный.)

afterglow = after + glow
afterglow = aft + erg + low
alienation = a + lie + nation
alienation = a + lien + at + i + on
alienation = a + lien + at + ion
alienation = alien + at + i + on
alienation = alien + at + ion
archer = arc + her
assassinate = ass + as + sin + ate
assassinate = ass + ass + in + ate
assassinate = assassin + ate
backpedalled = back + pedal + led
backpedalled = back + pedalled
backpedalled = backpedal + led
goatskin = go + at + skin
goatskin = goat + skin
goatskin = goats + kin
hospitable = ho + spit + able
temporally = tempo + rally
windowed = win + do + wed
windowed = wind + owed
weatherproof = we + at + her + pro + of
yeasty = ye + a + sty

Хорошо, вы поняли идею. :-)

правила

  • Используйте любой язык программирования по вашему выбору. Самый короткий код за счет количества символов для каждого языка выигрывает. Это означает, что есть один победитель для каждого используемого языка. Абсолютным победителем будет просто самый короткий код из всех представленных.
  • Список ввода может быть текстовым файлом, стандартным вводом или любой структурой списка, которую обеспечивает ваш язык (список, массив, словарь, набор и т. Д.). Слова могут быть английским или любым другим естественным языком. (Если список состоит из английских слов, вам нужно игнорировать или предварительно отфильтровывать однобуквенные элементы, за исключением «a» и «i». Аналогично, для других языков вы захотите игнорировать бессмысленные элементы, если они появляются в файле.)
  • Список вывода может быть текстовым файлом, стандартным выводом или любой структурой списка, которую использует ваш язык.
  • Вы можете использовать любой входной словарь, который вам нравится, но вы, вероятно, захотите использовать тот, который предоставляет разумные слова, а не тот, который содержит слишком много неясных, загадочных или однотонных слов. Этот файл, который я использовал: список Corncob из более чем 58000 английских слов

Вопросов

Эта задача, прежде всего, заключается в написании кода для выполнения задачи, но также интересно просматривать результаты ...

  1. Какие подслова встречаются чаще всего?
  2. Какое слово можно разложить на наибольшее количество подслов?
  3. Какое слово можно разложить самыми разными способами?
  4. Какие слова состоят из самых больших подслов?
  5. Какие декомпозиции вы нашли наиболее забавными?
Тодд Леман
источник
@ Geobits - Ах, спасибо! Я пропустил два разложения того, alienationкогда я вырезал и вставил это. Исправлено сейчас. Что касается других, приведенный выше список является лишь небольшой выборкой. Моя тестовая программа вызвала десятки тысяч ответов при получении списка Corncob.
Тодд Леман
1
"Какие подслова встречаются чаще всего?" Собираюсь сделать дикое предположение и сказать, что «а» может быть рядом с вершиной.
Sellyme
@SebastianLamerichs - я не знаю ... Может быть, не может быть. :)
Тодд Леман
@ToddLehman это предложение содержит ровно 0 подслов, поэтому «а» все равно сначала: P
Sellyme
@SebastianLamerichs, если вы ссылались на ответ Тодда, «не знаю» можно разделить на «dun» + «нет». ;)
я встревожил пришельца

Ответы:

3

Python 186

a=open(raw_input()).read().split()
def W(r):
 if r:
    for i in range(1,len(r)+1):
     if r[:i]in a:
        for w in W(r[i:]):yield[r[:i]]+w
 else:yield[]
while 1:
 for f in W(raw_input()):print f

Не особенно эффективно, но на самом деле не ужасно медленно. Это просто наивно (я полагаю, что это возможно, хотя я думаю, что маловероятно, что python делает некоторые умные оптимизации) проверяет, что подслов находятся в словаре кукурузного початка и рекурсивно находит столько слов, сколько может. Конечно, этот словарь довольно обширный, и вы можете попробовать тот, который не включает в себя различные сокращения и сокращения (приводя к таким вещам, какbedridden: be dr id den ). Также в связанном словаре не было слов «A» или «I» в качестве слов, поэтому я добавил их вручную.

Редактировать:

Теперь первым вводом является имя используемого словаря, а каждый дополнительный - слово.

KSab
источник
Стоит отметить, что это Python 2, потому что код не запускается в Python 3, потому что это print fдолжно бытьprint(f)
Кроме того, как мне это запустить? echo archer|python2 filename.pyвыводит EOFError для последней строки
Некоторые вещи вы можете изменить (я не проверял их, но уверен, что это сработает): for f in W(raw_input()):print f=> ''.join(W(raw_input()); a=open('c').read().split('\n')=>a=open('c').readlines()
Sepıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs Ваш первый будет работать, но readlinesсимволы перевода строки будут находиться в конце строк, поэтому я сделал это так, как сделал.
KSab
@ ɐɔıʇǝɥʇuʎs О, на самом деле кажется, что joinвсе элементы должны быть строками, и я не могу получить их в форме, меньшей, чем у меня уже есть.
KSab
2

Кобра - 160

sig Z(x,y)
def f(b)
    c as Z=do(x,y)
        if x.length<1,print y
        for z in File.readLines('t'),if z==x[:e=z.length].toLower,c(x[e:],y+' '+z)
    for t in b,c(t,'[t]:')

Это функция (сортировка двух функций), которая принимает List<of String>* и печатает строки, содержащие возможные расположения подслов для каждой строки в списке аргументов.

* тип на самом деле List<of dynamic?>, но предоставление чего-либо другого List<of String>, вероятно, сломает его.

Οurous
источник
2

Скала, 132 129

Редактировать: немного короче, чем цикл чтения из стандартного ввода, чем функция

while(true)print(readLine.:\(Seq(List(""))){(c,l)=>l.flatMap{m=>Seq(c+""::m,c+m.head::m.tail)}}filter(_.forall(args contains _)))

беги как

scala decompose.scala aft after erg glow low

(или используйте более длинный список слов :))

Оригинал:

def f(s:Seq[String])=s.map{_.:\(Seq(List(""))){(c,l)=>l.flatMap{m=>Seq(c+""::m,c+m.head::m.tail)}}filter(_.forall(args contains _))}

Функция от Seq [String] до Seq [Seq [List [String]]]. Принимает словарь в качестве аргументов командной строки.

Ungolfed:

def decompose(wordList: Seq[String]) =
  wordList.map{ word =>                              // for each word
    word.foldRight(Seq(List(""))){ (char, accum) =>  // for each character
      accum.flatMap{list =>
        Seq(char+""::list,char+list.head::list.tail) // add it as both a new list and 
      }                                              // the to start of the first list
    }.filter(_.forall(args contains _))              // filter out lists w/ invalid words
  }

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

paradigmsort
источник