Rimuovi parole duplicate da una frase


10

In questa sfida, rimuoverai parole duplicate da ogni frase .

Esempi

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

specificazione

  • L'input sarà una stringa di caratteri ASCII.
  • Una frase è definita come qualsiasi cosa fino alla fine della stringa, un linefeed ( \n) o punteggiatura ( .!?).
  • Una parola è definita come una sequenza di A-Za-z.
  • Le parole non fanno distinzione tra maiuscole e minuscole ( Hello== heLlO).
  • Viene mantenuta solo la prima occorrenza di una parola in una frase.
  • Se una parola viene rimossa, gli spazi prima della parola rimossa dovrebbero essere rimossi. (es. A A B-> A B).

Questo è quindi vince il codice più breve in byte!


1
a b a.va a cosa?
lirtosiast,

@ThomasKwa a b.perché la `a` è stata rimossa.
Downgoat,

Per a__b_b_a, ricevi a_b_a(prima brimosso) o a__b_a(secondo brimosso)?

@CamilStaps otterresti a__b__perché il ripetuto bviene rimosso e il ripetuto aviene rimosso
Downgoat

1
@ BradGilbertb2gills Nell'input sono consentiti tutti i caratteri ASCII. Tuttavia, solo le lettere sono considerate parole
Downgoat,

Risposte:


3

Vim, 27 byte

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

Si noti che i 27 byte include un ritorno a capo finale alla fine.

Provalo online! Nota a margine: questo è un link a una lingua diversa che sto scrivendo chiamata "V". V è principalmente retrocompatibile con vim, quindi, a tutti gli effetti, può contare come un interprete vim. Ho anche aggiunto un byte in %modo da poter verificare tutti i casi di test contemporaneamente.

Spiegazione:

: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

Nota mentre l'ho trovato da solo, è fastidiosamente simile a @ Neil's, solo con la logica aggiuntiva per dividere l'intera stringa di input in frasi.

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>


6

Retina , 66 46 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

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

Provalo online!

Spiegazione

Poiché solo le lettere devono essere considerate caratteri di parole (ma regex considera anche le cifre e i caratteri di sottolineatura come caratteri di parola), dobbiamo stabilire i nostri limiti di parole. Poiché è garantito che l'input contenga solo caratteri ASCII, sto inserendo ·(al di fuori di ASCII, ma all'interno di ISO 8859-1) attorno a tutte le parole e le rimuovo di nuovo con i duplicati. Ciò consente di risparmiare 20 byte utilizzando le soluzioni alternative per implementare limiti di parole generici.

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

Questo corrisponde a ogni parola e la circonda ·.

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

Si tratta di due passaggi compressi in uno. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)corrisponde a una parola completa (assicurata includendo il ·nella corrispondenza), insieme a tutti gli spazi che la precedono, a condizione che (come assicurato dallo sguardo dietro) possiamo trovare la stessa parola da qualche parte prima nella frase. ( Corrisponde a un avanzamento riga.)

L'altra parte è semplicemente la ·, che corrisponde a tutti i confini di parole artificiali che non sono stati abbinati come parte della prima metà. In entrambi i casi, la corrispondenza viene semplicemente rimossa dalla stringa.


4

C, 326 byte

Chi ha bisogno di espressioni regolari?

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

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

Uso:

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

Spiegazione

{
  [~]                         # 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 byte

56 byte codice + 1 per -p

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

Uso:

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!

Potrebbe essere necessario fare +1, al momento suppongo che ci saranno solo spazi nell'input, nessuna scheda.


Da un commento "Tutti i caratteri ASCII sono consentiti nell'input. Tuttavia, solo le lettere sono considerate parole" (lo modificherò nella sfida, credo)
Martin Ender,

@ MartinBüttner Dannazione, ok aggiornerò per usare \sinvece ... Ancora da nessuna parte vicino alla tua risposta alla retina!
Dom Hastings,

Oh, vedo perché l'hai chiesto ora. Se dobbiamo rimuovere gli spazi bianchi prima delle parole, allora ho bisogno anche di un altro byte. La domanda dice specificamente "spazi" però. Ho chiesto chiarimenti.
Martin Ender,

@ MartinBüttner Suppongo che il mio commento non sia stato molto chiaro! Grazie per i tuoi commenti però!
Dom Hastings,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.