Видаліть з речення повторювані слова


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`
Пуховик

Бо a__b_b_aви отримуєте a_b_a(перший bвилучений) чи a__b_a(другий bвилучений)?

@CamilStaps ви отримаєте, a__b__тому що повторне bвидалено, а повторне aвидалено
Пуховик

1
@ BradGilbertb2gills Усі символи ASCII дозволені у вводі. Тільки букви вважаються словами, але
Пуховик

Відповіді:


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 байт за допомогою lookarounds для реалізації загальних меж слова.

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.