Usuń zduplikowane słowa z zdania

10

W tym wyzwaniu usuniesz zduplikowane słowa z każdego zdania .

Przykłady

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

Specyfikacja

  • Dane wejściowe będą ciągiem znaków ASCII.
  • Zdanie jest definiowane jako cokolwiek do końca łańcucha, linefeed ( \n) lub interpunkcji ( .!?).
  • Słowo jest zdefiniowane jako ciąg A-Za-z.
  • W słowach nie jest rozróżniana wielkość liter ( Hello== heLlO).
  • Zachowywane jest tylko pierwsze wystąpienie słowa w zdaniu.
  • Jeśli słowo zostanie usunięte, spacje przed usuniętym słowem powinny zostać usunięte. (np. A A B-> A B).

To jest więc wygrywa najkrótszy kod w bajtach!

Downgoat
źródło
1
a b a.idzie do czego?
lirtosiast
@ThomasKwa, a b.ponieważ litera „a” została usunięta.
Downgoat,
Bo a__b_b_adostajesz a_b_a(pierwszy busunięty) czy a__b_a(drugi busunięty)?
@CamilStaps, który dostaniesz, a__b__ponieważ powtarzane bjest usuwane, a powtarzane ajest usuwane
Downgoat
1
@ BradGilbertb2gills Wszystkie znaki ASCII są dozwolone na wejściu. Tylko litery są uważane za słowa
Downgoat

Odpowiedzi:

3

Vim, 27 bajtów

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

Zauważ, że 27 bajtów zawiera znak końca karetki na końcu.

Wypróbuj online! Uwaga dodatkowa: To jest link do innego języka, który piszę, o nazwie „V”. V jest w większości kompatybilny wstecz z vimem, więc dla wszystkich celów i celów może być liczony jako tłumacz vim. Dodałem również jeden bajt %, abyś mógł zweryfikować wszystkie przypadki testowe jednocześnie.

Wyjaśnienie:

: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
James
źródło
6

JavaScript (ES6), 98

Zauważ , że chociaż sam go znalazłem, jest irytująco podobny do @ Neila, tylko z dodatkową logiką dzielącą cały ciąg wejściowy na zdania.

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

Test

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>

edc65
źródło
6

Siatkówka , 66 46 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

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

Wypróbuj online!

Wyjaśnienie

Ponieważ tylko litery powinny być traktowane jako znaki słowne (ale regex traktuje cyfry i znaki podkreślenia również jako znaki słowne), musimy stworzyć własne granice słów. Ponieważ gwarantowane jest, że dane wejściowe zawierają tylko znaki ASCII, wstawiam ·(poza ASCII, ale wewnątrz ISO 8859-1) wokół wszystkich słów i usuwam je ponownie z duplikatami. Pozwala to zaoszczędzić 20 bajtów w porównaniu z używaniem lookaroundów do implementacji ogólnych granic słów.

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

To pasuje do każdego słowa i otacza je ·.

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

To dwa kroki skompresowane w jeden. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)dopasowuje pełne słowo (zapewnione przez uwzględnienie ·w dopasowaniu), wraz ze spacjami poprzedzającymi go, pod warunkiem, że (jak zapewnia lookbehind) możemy znaleźć to samo słowo gdzieś wcześniej w zdaniu. ( Pasuje do linii).

Druga część to po prostu ta ·, która odpowiada wszystkim sztucznym granicom słów, które nie zostały dopasowane w pierwszej połowie. W obu przypadkach dopasowanie jest po prostu usuwane z łańcucha.

Martin Ender
źródło
4

C, 326 bajtów

Kto potrzebuje wyrażeń regularnych?

#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]);}
Cole Cameron
źródło
3

Perl 6 , 104 bajtów

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

Stosowanie:

# 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!

Wyjaśnienie

{
  [~]                         # 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 
    }
  )
}
Brad Gilbert b2gills
źródło
1

Perl 5, 57 bajtów

Kod 56 bajtów + 1 dla -p

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

Stosowanie:

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!

Może być +1, obecnie zakładam, że na wejściu będą tylko spacje, bez tabulatorów.

Dom Hastings
źródło
Z komentarza „Wszystkie znaki ASCII są dozwolone na wejściu. Jednak tylko litery są uważane za słowa” (myślę, że zmienię to w wyzwanie)
Martin Ender
@ MartinBüttner Cholera, ok, zaktualizuję, aby użyć \szamiast ... Nadal nigdzie w pobliżu odpowiedzi siatkówki!
Dom Hastings
Och, rozumiem, dlaczego pytałeś teraz. Jeśli musimy usunąć białe znaki przed słowami, potrzebuję również innego bajtu. Pytanie wyraźnie mówi jednak „spacje”. Poprosiłem o wyjaśnienia.
Martin Ender
@ MartinBüttner Wydaje mi się, że mój komentarz też nie był do końca jasny! Dzięki za komentarze!
Dom Hastings