Удалить повторяющиеся слова из предложения


10

В этом задании вы удалите повторяющиеся слова из каждого предложения .

Примеры

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

Спецификация

  • На входе будет строка символов ASCII.
  • Предложение определяется как что-либо до конца строки, перевода строки ( \n) или пунктуации ( .!?).
  • Слово определяется как последовательность A-Za-z.
  • Слова не чувствительны к регистру ( Hello== heLlO).
  • Сохраняется только первое вхождение слова в предложении.
  • Если слово удалено, пробелы перед удаленным словом должны быть удалены. (например A A B-> A B).

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


1
a b a.идет к чему?
lirtosiast

@ThomasKwa, a b.потому что `a` удалено.
Downgoat

Для a__b_b_a, вы получите a_b_a(первый bудален) или a__b_a(второй bудалены)?

@CamilStaps вы получили бы, a__b__потому что повторение bудалено, а повторное aудалено
Downgoat

1
@ BradGilbertb2gills Все символы ASCII допускаются на входе. Только буквы считаются словами
Downgoat

Ответы:


3

Vim, 27 байт

:s/\v\c(<\a+>).{-}\zs\s+\1

Обратите внимание, что 27 байтов включают в себя возврат каретки в конце.

Попробуйте онлайн! Примечание: это ссылка на другой язык, который я пишу, который называется «V». V в основном обратно совместим с vim, поэтому он может рассматриваться как интерпретатор vim. Я также добавил один байт, %чтобы вы могли проверить все тестовые случаи одновременно.

Объяснение:

:s/\v                       "Substitute with the 'Magic flag' on. This magic flag allows us
                            "to shorten the regex by removing a lot of \ characters.
     \c(<\a+>)              "A case-insensitive word
              .{-}          "Any character (non-greedy)
                  \zs       "Start the selection. This means everything after this atom
                            "will be removed
                     \s+    "One or more whitespace characters,
                        \1  "Followed by the first word

6

JavaScript (ES6), 98

Заметьте, хотя я и нашел его сам, он раздражающе похож на @ Neil's, только с дополнительной логикой для разделения всей входной строки на предложения.

s=>s.replace(/[^\n.!?]+/g,s=>s.replace(/ *([a-z]+)/ig,(r,w)=>k[w=w.toUpperCase()]?'':k[w]=r,k=[]))

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

f=s=>s.replace(/[^\n.!?]+/g,s=>s.replace(/ *([a-z]+)/ig,(r,w)=>k[w=w.toUpperCase()]?'':k[w]=r,k=[]))

console.log=x=>O.textContent+=x+'\n'

;[['Hello Hello, World!','Hello, World!']
,['Code Code! Golf Code','Code! Golf Code']
,['Hello  hello   World','Hello   World']
,['Programming Golf Programming!','Programming Golf!']]
.forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
  console.log((r==k?'OK ':'KO ')+i+' -> '+r)
})  
<pre id=O></pre>


6

Сетчатка , 66 46 байт

Количество байтов предполагает кодировку ISO 8859-1.

i`[a-z]+
·$0·
i` *(·[a-z]+·)(?<=\1[^.!?¶]+)|·

Попробуйте онлайн!

объяснение

Поскольку только слова должны рассматриваться как символы слова (но регулярное выражение также рассматривает цифры и подчеркивания как символы слова), нам необходимо создать собственные границы слов. Поскольку входные данные гарантированно содержат только символы ASCII, я вставляю ·(вне ASCII, но внутри ISO 8859-1) все слова и удаляю их снова с дубликатами. Это экономит 20 байтов за счет использования обходных путей для реализации общих границ слов.

i`[a-z]+
·$0·

Это соответствует каждому слову и окружает его ·.

i` *(·[a-z]+·)(?<=\1[^.!?¶]+)|·

Это два шага, сжатых в один. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)соответствует полному слову (обеспечивается включением ·в совпадение) вместе с любыми пробелами, предшествующими ему, при условии, что (как обеспечивает просмотр сзади) мы можем найти то же слово где-то ранее в предложении. (Соответствует переводу строки.)

Другая часть - просто ·, которая соответствует всем искусственным границам слов, которые не были сопоставлены как часть первой половины. В любом случае совпадение просто удаляется из строки.


4

C 326 байт

Кому нужны регулярные выражения?

#include <ctype.h>
#define a isalpha
#define c(x)*x&&!strchr(".?!\n",*x)
#define f(x)for(n=e;*x&&!a(*x);++x);
main(p,v,n,e,o,t)char**v,*p,*n,*e,*o,*t;{for(p=v[1];*p;p=e){f(p)for(e=p;c(e);){for(;a(*++e););f(n)if(c(n)){for(o=p,t=n;a(*o)&&(*o-65)%32==(*t-65)%32;o++,t++);if(a(*t))e=n;else memmove(e,t,strlen(t)+1);}}}puts(v[1]);}

3

Perl 6 , 104 байта

{[~] .split(/<[.!?\n]>+/,:v).map(->$_,$s?{.comb(/.*?<:L>+/).unique(as=>{/<:L>+/;lc $/}).join~($s//'')})} # 104

Применение:

# give it a lexical name
my &code = {...}

say code "Hello Hello, World!
Code Code! Golf Code
Hello  hello   World
Programming Golf Programming!";
Hello, World!
Code! Golf Code
Hello   World
Programming Golf!

объяснение

{
  [~]                         # join everything that follows:

  .split(/<[.!?\n]>+/,:v)     # split on boundaries, keeping them
  .map(                       # loop over sentence and boundary together
    -> $_, $s? {              # boundary is optional (at the end of the string)
      .comb(/.*?<:L>+/)       # grab the words along with leading non letters
      .unique(                # keep the unique ones by looking at …
        as => {/<:L>+/;lc $/} # only the word chars in lowercase
      )
      .join                   # join the sentence parts
      ~                       # join that with …
      ($s//'')                # the boundary characters or empty string 
    }
  )
}

1

Perl 5, 57 байт

56 байт код + 1 для -p

s/[^.!?
]+/my%h;$&=~s~\s*([A-z]+)~!$h{lc$1}++&&$&~egr/eg

Применение:

perl -pe 's/[^.!?
]+/my%h;$&=~s~\s*([A-z]+)~!$h{lc$1}++&&$&~egr/eg' <<< 'Hello Hello, World!
Code Code! Golf Code
Hello  hello   World
Programming Golf Programming!
'
Hello, World!
Code! Golf Code
Hello   World
Programming Golf!

Возможно, должно быть +1, в настоящее время я предполагаю, что на входе будут только пробелы, без вкладок.


Из комментария «Все символы ASCII разрешены на входе. Только слова считаются словами» (думаю, я отредактирую это в вызове)
Мартин Эндер

@ MartinBüttner Черт, хорошо, я обновлю, чтобы использовать \sвместо этого ... Тем не менее, еще далеко не ваш ответ сетчатки глаза, хотя!
Дом Гастингс

О, я понимаю, почему ты спросил сейчас. Если нам нужно удалить пробелы перед словами, тогда мне нужен еще один байт. Вопрос, в частности, говорит «пробелы», хотя. Я попросил разъяснений.
Мартин Эндер

@ MartinBüttner Полагаю, мой комментарий тоже не совсем понятен! Спасибо за ваши комментарии, хотя!
Дом Гастингс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.