Supprimer les mots en double d'une phrase

10

Dans ce défi, vous supprimerez les mots en double de chaque phrase .

Exemples

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

spécification

  • L'entrée sera une chaîne de caractères ASCII.
  • Une phrase est définie comme n'importe quoi jusqu'à la fin de la chaîne, un saut de ligne ( \n) ou une ponctuation ( .!?).
  • Un mot est défini comme une séquence de A-Za-z.
  • Les mots ne respectent pas la casse ( Hello== heLlO).
  • Seule la première occurrence d'un mot dans une phrase est conservée.
  • Si un mot est supprimé, les espaces avant le mot supprimé doivent être supprimés. (par exemple A A B-> A B).

C'est le donc le code le plus court en octets gagne!

Downgoat
la source
1
a b a.va à quoi?
lirtosiast
@ThomasKwa a b.car le «a» est supprimé.
Downgoat
Pour a__b_b_a, obtenez-vous a_b_a(premier bsupprimé) ou a__b_a(deuxième bsupprimé)?
@CamilStaps vous obtiendriez a__b__parce que la répétition best supprimée et la répétition aest supprimée
Downgoat
1
@ BradGilbertb2gills Tous les caractères ASCII sont autorisés dans l'entrée. Cependant, seules les lettres sont considérées comme des mots
Downgoat

Réponses:

3

Vim, 27 octets

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

Notez que les 27 octets incluent un retour chariot fin à la fin.

Essayez-le en ligne! Note latérale: Ceci est un lien vers une autre langue que j'écris appelée "V". V est principalement rétrocompatible avec vim, donc à toutes fins utiles, il peut compter comme un interprète vim. J'ai également ajouté un octet %pour que vous puissiez vérifier tous les cas de test à la fois.

Explication:

: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
la source
6

JavaScript (ES6), 98

Notez que même si je l'ai trouvé moi-même, il ressemble énormément à @ Neil, juste avec la logique supplémentaire pour diviser la chaîne d'entrée entière en phrases.

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

Tester

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
la source
6

Rétine , 66 46 octets

Le nombre d'octets suppose un codage ISO 8859-1.

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

Essayez-le en ligne!

Explication

Étant donné que seules les lettres doivent être considérées comme des caractères de mots (mais l'expression régulière traite les chiffres et les traits de soulignement comme des caractères de mots), nous devons créer nos propres limites de mots. Étant donné que l'entrée ne contient que des caractères ASCII, j'insère ·(en dehors de l'ASCII, mais à l'intérieur de l'ISO 8859-1) autour de tous les mots et je les supprime à nouveau avec les doublons. Cela économise 20 octets sur l'utilisation de contournements pour implémenter des limites de mots génériques.

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

Cela correspond à chaque mot et l'entoure ·.

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

Il s'agit de deux étapes compressées en une seule. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)correspond à un mot complet (garanti en incluant le ·dans le match), ainsi que tous les espaces qui le précèdent, à condition que (comme assuré par le lookbehind) nous puissions trouver le même mot quelque part plus tôt dans la phrase. (Le correspond à un saut de ligne.)

L'autre partie est simplement le ·, qui correspond à toutes les limites de mots artificiels qui ne correspondaient pas à la première moitié. Dans les deux cas, la correspondance est simplement supprimée de la chaîne.

Martin Ender
la source
4

C, 326 octets

Qui a besoin d'expressions régulières?

#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
la source
3

Perl 6 , 104 octets

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

Usage:

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

Explication

{
  [~]                         # 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
la source
1

Perl 5, 57 octets

Code de 56 octets + 1 pour -p

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

Usage:

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!

Peut-être besoin d'être +1, actuellement je suppose qu'il n'y aura que des espaces dans l'entrée, pas d'onglets.

Dom Hastings
la source
D'après un commentaire "Tous les caractères ASCII sont autorisés dans l'entrée. Cependant, seules les lettres sont considérées comme des mots" (je vais modifier cela dans le défi, je pense)
Martin Ender
@ MartinBüttner Damn, ok je vais mettre à jour pour utiliser à la \splace ... Toujours loin de votre réponse rétine cependant!
Dom Hastings
Oh je vois pourquoi tu as demandé maintenant. Si nous devons supprimer les espaces devant les mots, j'ai également besoin d'un autre octet. Cependant, la question dit spécifiquement "espaces". J'ai demandé des éclaircissements.
Martin Ender
@ MartinBüttner Je suppose que mon commentaire n'était pas vraiment clair non plus! Merci pour vos commentaires!
Dom Hastings