Оде Гольф - Удаление Письма


17

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

Например, вход

cat
cart
code
golf
ode
verify
versify

должен дать вывод

ca(r)t
(c)ode
ver(s)ify

Несколько способов получить одну и ту же пару должны отображаться только один раз. Вы можете вывести scra(p)pedили scrap(p)ed, но не оба.

Вывод должен быть упорядочен в алфавитном порядке по более длинной записи;

mart
mar
mat
ma

должен иметь выход

ma(r)
ma(t)
ma(r)t
mar(t)

и последние два могут быть в любом порядке.

Файл словаря может содержать заглавные буквы, пробелы, дефисы или апострофы; это следует игнорировать. Например,

inlay 
in-play

должен производить in(p)lay. Ваш вывод должен быть в одном и том же случае. Дополнительные пробелы разрешены.

Ввод может быть STDIN или из файла; это разделено новыми строками. Вывод может быть возвращаемым значением функции или STDOUT (или записываться в файл, если вы хотите).

Это , поэтому выигрывает самый короткий код в байтах.

(Это мой первый вызов на PPCG - дайте мне знать, если я сделал что-то не так, и я это исправлю.)


3
Для чего должен быть выход mart mar mat ma? Это будет mar(t) ma(r)t ma(r) ma(t)?
Sp3000

@Sp: Забыл указать порядок - отредактирован для уточнения.
Деусови,

В первом примере слово «гольф» отсутствует в выводе. Это потому, что у этого слова нет других комбинаций?
LukStorms

@Luk: Да! Для большинства файлов словарей будет много слов, которые вообще не образуют других слов - они не должны появляться нигде в выводе.
Деусови,

2
Как насчет разрешения функции с (большим) строковым параметром возвращать запрошенный вывод в виде строкового массива? Это делает акцент на алгоритме, избегая необходимости управлять файловым вводом / выводом.
edc65

Ответы:


1

Perl -an0, 101 + 3 байта

@F=sort{length$a<=>length$b}map{s/\W//g;lc}@F;map{$`.$'~~@F?print"$`($1)$'\n":$\while/(.)(?!\1)/g}@F;

где

  • @Fэто словарь, хранящийся в массиве, предоставленный волшебным флагом времени выполнения. (b-oost, BoO # @% @ # $% $ # @ T)
  • map{s/\W//g;lc}@Fудаляет все символы из слов и превращает все в строчные. (буст, загрузка)
  • sort{length$b<=>length$a}сортирует по длине. (загрузка, повышение)
  • map{ (...) while/(.)(?!\1)/g}@Fсоответствует всем символам, за которыми не следует один и тот же символ ([b] oot, bo [o] t, boo [t], ...)
  • print"$`($1)$'\n"печатает части, которые предшествуют, ставят круглые скобки и следуют за соответствием ... (boo (s) t)
  • if $`.$'~~@F... если объединение всего до и после совпадения есть в словаре. ([увеличение])

5

JavaScript (ES6), 225

Функция со строковым параметром, без ввода из файла. Я спросил OP, если это может быть действительным.

Тестовый запуск фрагмента в браузере, совместимом с EcmaScript 6 (реализация функций стрелок, строки шаблона, оператора распространения - Firefox, возможно, Safari или MS Edge, а не Chrome)

f=t=>t.split`
`.map(w=>(d[k=w.replace(/\W/g,'').toLowerCase()]={},k),d={},r=[]).map(w=>[...w].map((c,i,v)=>(d[v[i]='',x=v.join``]&&!d[x][w]&&r.push(d[x][w]=(v[i]=`(${c})`,v.join``)),v[i]=c)))&&r.sort((a,b)=>a.length-b.length)

// LESS GOLFED

Q=t=>{
  // convert to canonical form and put in a dictionary
  // each value in the dictionary is an hashtable tha will store the list
  // of words that can generate the current word, removing a letter
  d={},
  t=t.split`\n`.map(w=>(k=w.replace(/\W/g,'').toLowerCase(),d[k]={},k))
  r=[], // result array 
  t.forEach(w =>
    [...w].forEach((c,i,v)=>( // for each letter in word, try to remove
      v[i]='', x=v.join``, // build string with missing letter
      v[i]='('+c+')', y=v.join``, // and build string with brackets
      v[i]=c, // restore the current letter
      d[x] && // if the word with removed letter is present in the dictionary
      !d[x][w] && // and not already from the same generating word
         r.push(d[x][w]=y) // update dictionary and add word to result array
    ))
  )
  return r.sort((a,b)=>a.length-b.length) // sort result by length
}  

// TEST
function test() { R.innerHTML=f(I.value) }
textarea { height: 20em }
Test <button onclick="test()">-></button>
<span id=R></span>
<br><textarea id=I>cat
cart
code
golf
node
scraped
scrapped
verify
versify
mart
mar
mat
ma</textarea>


@ETHproductions правильно,
спасибо

3

Руби, 173

->d{o=[]
c={}
d=d.sort_by{|w|[w.size,w]}.map{|w|w=w.upcase.gsub /[^A-Z]/,''
c[w]=l=1
w.size.times{|i|p,x,s=w[0...i],w[i],w[i+1..-1]
c[p+s]&&l!=x&&o<<p+"(#{w[i]})"+s
l=x}}
o}

Проверьте это здесь: http://ideone.com/86avbe

Читаемая версия здесь: http://ideone.com/ynFItB


На мобильном телефоне, поэтому я не могу сейчас тестировать - не могли бы вы добавить тестовый пример для SCRAPPED / SCRAPED?
Деусови,

@Deusovi Это дело не работает правильно. Я исправляю это сейчас ...
Кристиан Лупаску,

@Deusovi Обновлено!
Кристиан Лупаску,

Этот ответ не обеспечивает правильного вывода, например, для ['jacklantern','jackslantern','jack-o-lantern']dict.
14mRh4X0r

1
@ 14mRh4X0r не может найти этот запрос в вопросе ... The output should be ordered by the longer entry;...and the latter two could be in either order.
edc65

1

Руби, 211

Я решил использовать другой подход, чтобы решить эту проблему, используя регулярные выражения.

->d{o=[]
d.map{|x|x.upcase!.gsub! /[-' ]/,''}
d.map{|x|(x.size+1).times{|i|o+=d.map{|w|w.b.sub! /(#{x[0...i]})(.)(#{x[i..-1]})/,'\1(\2)\3'if w[i]!=w[i+1]}}}
o.compact.sort_by{|w|[w.size,w.gsub(/[()]/,'')]}.uniq}

0

Perl 5, 210

Код загружает входные данные в отсортированный массив и проверяет каждое значение по всем значениям в массиве, которые на 1 байт длиннее.

map{@W=split//,$w=$_;map{@X=split//,$x=$_;if(@W+1==@X){$i=0;while($W[$i]eq$X[$i]&&$i<@W){$i++}$c=$X[$i];$e=substr($w,$i);print substr($w,0,$i)."($c)$e\n",if substr($x,$i+1)eq$e}}@D}@D=sort(map{s/[^\w]//g;lc}<>)

Тестовое задание

$ perl dictionairy_same_words.pl dictionairywords.txt
ca(r)t
in(p)lay
ma(r)
ma(t)
mar(t)
ma(r)t
(c)ode
ver(s)ify

0

Haskell, 201 байт

import Data.List
import Data.Char
a#(b:c)=(a,b,c)
g a=[l++'(':m:')':n|x<-a,((l,m,n):_)<-[[o|o@(i,j,k)<-zipWith(#)(inits x)$init$tails x,elem(i++k)a]]]
f=sortOn length.g.map(filter isLetter.map toLower)

Я не уверен, какой формат ввода разрешен. fзанимает список строк. Если разрешена только одна строка (с nl разделенными словами), добавьте .linesкf (+6 байт).

Пример использования:

f ["cat","cart","code","golf","od-e","verify","versify","on","s-o-n","Scrapped","scraped"]

["(s)on","ca(r)t","(c)ode","ver(s)ify","scra(p)ped"]

Как это работает: превращайте каждое слово в строчные и оставляйте только буквы. Разбейте каждое слово xна две части в каждой возможной позиции и сделайте тройки, (i,j,k)где iпервая часть, jпервый символ второй части и kхвост второй части. Держите тройки, где i++kтакже появляется в списке слов. Если этот список не пуст, возьмите первый элемент, вызовите его (l,m,n). Включите все эти список головок в требуемый формат вывода, окружив mс ()и положить его между lи n.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.