从句子中删除重复的单词


10

在这个挑战中,您将从每个句子中删除重复的单词。

例子

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

规格

  • 输入将是一串ASCII字符。
  • 句子定义为字符串末尾的任何内容,换行符(\n)或标点符号(.!?)。
  • 单词定义为的序列A-Za-z
  • 单词不区分大小写(Hello== heLlO)。
  • 仅保留单词在句子中的首次出现。
  • 如果删除了一个单词,则应删除删除的单词之前的空格。(例如A A B-> A B)。

这是因此以字节为单位的最短代码胜出!


1
a b a.去什么?
lirtosiast,2016年

@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

Answers:


3

Vim,27个字节

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

请注意,这27个字节在结尾处包括尾随回车符。

在线尝试!旁注:这是我正在写的另一种语言的链接,称为“ V”。V在大多数情况下都与vim向后兼容,因此就所有意图和目的而言,它都可以视为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 46字节

字节数假定为ISO 8859-1编码。

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

在线尝试!

说明

由于仅字母应被视为单词字符(而正则表达式也将数字和下划线视为单词字符),因此我们需要设置自己的单词边界。由于保证输入仅包含ASCII字符,因此我将·在所有单词周围插入(在ASCII之外,但在ISO 8859-1内),然后再次将它们与重复项删除。与使用环视实现通用字边界相比,这节省了20个字节。

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

这将匹配每个单词并将其括在中·

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

这是两个步骤压缩为一个步骤。<sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)匹配一个完整的单词(通过·在匹配项中包含来确保)以及其前面的所有空格,条件是(由后向保证)我们可以在句子的较早位置找到相同的单词。(匹配换行符。)

另一部分就是·,它匹配所有在上半部分没有匹配的人工词边界。无论哪种情况,都只从字符串中删除匹配项。


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

哦,我明白你为什么现在问。如果我们需要删除单词前面的空格,那么我也需要另一个字节。这个问题专门说“空格”。我已要求澄清。
马丁·恩德

@MartinBüttner我想我的评论也不太清楚!谢谢您的评论!
Dom Hastings
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.