Entfernen Sie doppelte Wörter aus einem Satz

10

Bei dieser Herausforderung entfernen Sie doppelte Wörter aus jedem Satz .

Beispiele

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

Spezifikation

  • Die Eingabe erfolgt durch eine Zeichenfolge aus ASCII-Zeichen.
  • Ein Satz ist definiert als alles bis zum Ende der Zeichenfolge, ein Zeilenvorschub ( \n) oder eine Interpunktion ( .!?).
  • Ein Wort ist definiert als eine Folge von A-Za-z.
  • Bei Wörtern wird die Groß- und Kleinschreibung nicht Helloberücksichtigt ( == heLlO).
  • Es wird nur das erste Vorkommen eines Wortes in einem Satz beibehalten.
  • Wenn ein Wort entfernt wird, sollten die Leerzeichen vor dem entfernten Wort entfernt werden. (zB A A B-> A B).

Dies ist also gewinnt der kürzeste Code in Bytes!

Downgoat
quelle
1
a b a.geht zu was?
Lirtosiast
@ThomasKwa a b.weil das `a` entfernt wird.
Downgoat
Für a__b_b_a, bekommen Sie a_b_a(zuerst bentfernt) oder a__b_a(zweite bentfernt)?
@CamilStaps würden Sie erhalten, a__b__weil das wiederholte bentfernt wird und das wiederholte aentfernt wird
Downgoat
1
@ BradGilbertb2gills Alle ASCII-Zeichen sind in der Eingabe zulässig. Nur Buchstaben gelten jedoch als Wörter
Downgoat

Antworten:

3

Vim, 27 Bytes

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

Beachten Sie, dass die 27 Bytes am Ende einen nachgestellten Wagenrücklauf enthalten.

Probieren Sie es online aus! Randnotiz: Dies ist ein Link zu einer anderen Sprache, die ich schreibe und die "V" heißt. V ist größtenteils abwärtskompatibel mit vim, sodass es in jeder Hinsicht als vim-Interpreter gelten kann. Ich habe auch ein Byte hinzugefügt, %damit Sie alle Testfälle gleichzeitig überprüfen können.

Erläuterung:

: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
quelle
6

JavaScript (ES6), 98

Beachten Sie, dass es @ Neil's ärgerlich ähnlich ist, obwohl ich es selbst gefunden habe, nur mit der zusätzlichen Logik, die gesamte Eingabezeichenfolge in Sätze aufzuteilen.

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

Prüfung

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
quelle
6

Netzhaut , 66 46 Bytes

Die Byteanzahl setzt die ISO 8859-1-Codierung voraus.

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

Probieren Sie es online aus!

Erläuterung

Da nur Buchstaben als Wortzeichen betrachtet werden sollten (Regex behandelt jedoch auch Ziffern und Unterstriche als Wortzeichen), müssen wir unsere eigenen Wortgrenzen festlegen. Da die Eingabe garantiert nur ASCII-Zeichen enthält, füge ich ·(außerhalb von ASCII, aber innerhalb von ISO 8859-1) alle Wörter ein und entferne sie erneut mit den Duplikaten. Das spart 20 Bytes gegenüber der Verwendung von Lookarounds zum Implementieren generischer Wortgrenzen.

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

Dies passt zu jedem Wort und umgibt es ·.

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

Dies sind zwei Schritte, die zu einem komprimiert sind. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)stimmt mit einem vollständigen Wort ·überein (sichergestellt durch Einfügen des Wortes in die Übereinstimmung), zusammen mit allen vorangestellten Leerzeichen, vorausgesetzt, dass wir (wie durch das Aussehen sichergestellt) dasselbe Wort irgendwo früher im Satz finden können. (Das entspricht einem Zeilenvorschub.)

Der andere Teil ist einfach der ·, der allen künstlichen Wortgrenzen entspricht, die in der ersten Hälfte nicht übereinstimmten. In beiden Fällen wird die Übereinstimmung einfach aus der Zeichenfolge entfernt.

Martin Ender
quelle
4

C 326 Bytes

Wer braucht reguläre Ausdrücke?

#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
quelle
3

Perl 6 , 104 Bytes

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

Verwendungszweck:

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

Erläuterung

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

Perl 5, 57 Bytes

56 Bytes Code + 1 für -p

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

Verwendungszweck:

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!

Möglicherweise muss +1 sein. Derzeit gehe ich davon aus, dass die Eingabe nur Leerzeichen enthält, keine Tabulatoren.

Dom Hastings
quelle
Aus einem Kommentar "Alle ASCII-Zeichen sind in der Eingabe erlaubt. Nur Buchstaben werden jedoch als Wörter betrachtet" (ich werde dies in der Herausforderung bearbeiten, denke ich)
Martin Ender
@ MartinBüttner Verdammt, ok, ich werde es aktualisieren, um es \sstattdessen zu verwenden ... Immer noch nicht annähernd deine Antwort auf die Netzhaut!
Dom Hastings
Oh, ich verstehe, warum du jetzt gefragt hast. Wenn wir Leerzeichen vor Wörtern entfernen müssen, brauche ich auch ein weiteres Byte. Die Frage sagt jedoch speziell "Leerzeichen". Ich habe um Klarstellung gebeten.
Martin Ender
@ MartinBüttner Ich denke mein Kommentar war auch nicht wirklich klar! Vielen Dank für Ihre Kommentare!
Dom Hastings