Ode Golf - Вилучення листів


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: забув вказати замовлення - відредагований для уточнення.
Deusovi

У першому прикладі слово гольфу немає у висновку. Це тому, що це слово, яке не має інших комбінацій?
LukStorms

@Luk: Так! У більшості словникових файлів буде багато слів, які взагалі не створюють інших слів - вони не повинні з’являтися ніде у висновку.
Deusovi

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... якщо з'єднання всього до і після матчу є в словнику. ([boo] s [t])

5

JavaScript (ES6), 225

Функція з рядковим параметром, без введення файлу. Я запитав ОП, чи може це бути дійсно.

Перевірте запуск фрагмента в сумісному веб-переглядачі 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 right, thx
edc65

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 Цей випадок працює неправильно. Я зараз це виправляю ...
Крістіан Лупаску,

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

Ця відповідь не дає правильного результату, наприклад, ['jacklantern','jackslantern','jack-o-lantern']диктату.
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

Перл 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.