ลบคำที่ซ้ำกันออกจากประโยค


10

ในความท้าทายนี้คุณจะลบคำที่ซ้ำกันจากแต่ละประโยค

ตัวอย่าง

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

สเปค

  • ข้อมูลที่ป้อนจะเป็นสตริงอักขระ ASCII
  • ประโยคถูกกำหนดเป็นสิ่งใด ๆ จนกว่าจะสิ้นสุดของสตริง, linefeed ( \n) หรือเครื่องหมายวรรคตอน ( .!?)
  • A-Za-zคำที่ถูกกำหนดให้เป็นลำดับของ
  • คำเป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ( Hello== heLlO)
  • เฉพาะการเกิดขึ้นครั้งแรกของคำในประโยคจะถูกเก็บไว้
  • หากคำถูกลบออกช่องว่างก่อนคำที่ถูกลบควรถูกลบออก (เช่นA A B-> A B)

นี่คือสั้นที่สุดในหน่วยไบต์!


1
a b a.ไปเพื่ออะไร
lirtosiast

@ThomasKwa a b.เพราะ `a 'ถูกลบออก
Downgoat

สำหรับa__b_b_aคุณจะได้รับa_b_a( bนำออกครั้งแรก) หรือa__b_a( bนำออกครั้งที่สอง) หรือไม่

@CamilStaps คุณจะได้รับa__b__เนื่องจากการbลบออกซ้ำและการทำซ้ำaจะถูกลบออก
Downgoat

1
@ BradGilbertb2gills อนุญาตให้ใช้อักขระ ASCII ทั้งหมดในอินพุต ตัวอักษรเท่านั้นที่ถือว่าเป็นคำว่า
Downgoat

คำตอบ:


3

เป็นกลุ่ม 27 ไบต์

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

โปรดทราบว่า 27 ไบต์รวมถึงการขึ้นบรรทัดใหม่ที่ส่วนท้าย

ลองออนไลน์! หมายเหตุด้านข้าง: นี่คือลิงค์ไปยังภาษาอื่นที่ฉันกำลังเขียนชื่อ "V" V นั้นส่วนใหญ่ใช้งานร่วมกับ 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.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 66ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

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

ลองออนไลน์!

คำอธิบาย

เนื่องจากตัวอักษรควรได้รับการพิจารณาว่าเป็นตัวอักษรของคำ (แต่ regex ถือหลักและขีดล่างเป็นตัวอักษรของคำด้วย) เราจึงต้องสร้างขอบเขตของคำของเราเอง เนื่องจากอินพุตรับประกันว่ามีเฉพาะอักขระ ASCII เท่านั้นฉันจึงแทรก·(นอกเหนือจาก ASCII แต่อยู่ใน ISO 8859-1) รอบคำทั้งหมดและลบออกด้วยคำซ้ำ ที่ช่วยประหยัด 20 ไบต์ไปโดยใช้ lookarounds เพื่อใช้ขอบเขตคำทั่วไป

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

ตรงนี้ทุกคำและล้อมรอบมัน·มา

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

นี่คือการบีบอัดสองขั้นตอนเป็นหนึ่งเดียว <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)ตรงกับคำเต็ม (มั่นใจโดยรวม·ในการแข่งขัน) พร้อมช่องว่างใด ๆ ก่อนหน้าโดยมีเงื่อนไขว่า (ตามที่ตรวจสอบโดย lookbehind) เราสามารถค้นหาคำเดียวกันที่ไหนสักแห่งในประโยคก่อนหน้านี้ ( ตรงกับ linefeed)

อีกส่วนหนึ่งเป็นเพียงส่วน·ที่ตรงกับขอบเขตของคำศัพท์เทียมทั้งหมดที่ไม่ได้จับคู่เป็นส่วนหนึ่งของครึ่งแรก ไม่ว่าในกรณีใดการแข่งขันจะถูกลบออกจากสตริง


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 ทั้งหมดในอินพุตเฉพาะตัวอักษรที่ถือว่าเป็นคำว่า" (ฉันจะแก้ไขสิ่งนี้ให้เป็นสิ่งที่ท้าทายฉันคิดว่า)
Martin Ender

@ MartinBüttnerประณามฉันจะอัปเดตเพื่อใช้\sแทน ... ยังไม่มีคำตอบที่จอตาของคุณ!
Dom Hastings

โอ้ฉันเห็นว่าทำไมคุณถามตอนนี้ ถ้าเราต้องการลบช่องว่างต่อหน้าคำฉันก็ต้องใช้อีกไบต์เช่นกัน คำถามนี้บอกว่า "ช่องว่าง" โดยเฉพาะ ฉันขอคำชี้แจง
Martin Ender

@ MartinBüttnerฉันเดาว่าความคิดเห็นของฉันไม่ชัดเจนเช่นกัน! ขอบคุณสำหรับความคิดเห็นของคุณ!
Dom Hastings
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.