Remover palavras duplicadas de uma frase


10

Neste desafio, você removerá palavras duplicadas de cada frase .

Exemplos

Hello Hello, World!
Hello, World!

Code Code! Golf Code
Code! Golf Code

Hello  hello   World
Hello   World

Programming Golf Programming!
Programming Golf!

Especificação

  • A entrada será uma sequência de caracteres ASCII.
  • Uma sentença é definida como qualquer coisa até o final da string, avanço de linha ( \n) ou pontuação ( .!?).
  • Uma palavra é definida como uma sequência de A-Za-z.
  • As palavras não diferenciam maiúsculas de minúsculas ( Hello== heLlO).
  • Somente a primeira ocorrência de uma palavra em uma frase é mantida.
  • Se uma palavra for removida, os espaços antes da palavra removida deverão ser removidos. (por exemplo A A B-> A B).

Este é o pelo que o código mais curto em bytes vence!


11
a b a.vai para o que?
precisa saber é o seguinte

@ThomasKwa a b.porque o `a` foi removido.
Downgoat

Para a__b_b_a, você recebe a_b_a(primeiro bremovido) ou a__b_a(segundo bremovido)?

@CamilStaps você iria ficar a__b__porque o repetido bé removido e as repetidas aé removido
Downgoat

11
@ BradGilbertb2gills Todos os caracteres ASCII são permitidos na entrada. Apenas letras são consideradas palavras
Downgoat

Respostas:


3

Vim, 27 bytes

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

Observe que os 27 bytes incluem um retorno de carro à direita no final.

Experimente online! Nota lateral: este é um link para um idioma diferente que estou escrevendo chamado "V". O V é principalmente compatível com o vim, portanto, para todos os efeitos, pode contar como um intérprete do vim. Também adicionei um byte %para que você possa verificar todos os casos de teste de uma só vez.

Explicação:

: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

Note que enquanto eu o encontrei, é irritantemente semelhante ao do @ Neil, apenas com a lógica adicional para dividir toda a cadeia de entrada em frases.

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

Teste

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 bytes

A contagem de bytes assume a codificação ISO 8859-1.

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

Experimente online!

Explicação

Como apenas letras devem ser consideradas caracteres de palavras (mas o regex trata dígitos e sublinhados como caracteres de palavras também), precisamos criar nossos próprios limites de palavras. Como a entrada é garantida para conter apenas caracteres ASCII, estou inserindo ·(fora do ASCII, mas dentro da ISO 8859-1) todas as palavras e removendo-as novamente com as duplicatas. Isso economiza 20 bytes com o uso de lookarounds para implementar limites genéricos de palavras.

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

Isso corresponde a cada palavra e a envolve ·.

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

Este é dois passos compactados em um. <sp>*(·[a-z]+·)(?<=\1[^.!?¶]+)corresponde a uma palavra completa (garantida pela inclusão de ·na correspondência), juntamente com todos os espaços anteriores, desde que (conforme garantido pelo lookbehind), possamos encontrar a mesma palavra em algum lugar anteriormente na frase. ( Corresponde a um avanço de linha.)

A outra parte é simplesmente a ·, que corresponde a todos os limites de palavras artificiais que não foram correspondidos como parte da primeira metade. Em ambos os casos, a correspondência é simplesmente removida da sequência.


4

C, 326 bytes

Quem precisa de expressões regulares?

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

{[~] .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!

Explicação

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

Código de 56 bytes + 1 para -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!

Talvez precise ser +1, atualmente estou assumindo que haverá apenas espaços na entrada, sem guias.


De um comentário "Todos os caracteres ASCII são permitidas na entrada Somente letras são consideradas palavras embora." (Eu vou editar este para o desafio, eu acho)
Martin Ender

@ MartinBüttner Porra, ok, vou atualizar para usar \s... Ainda não está nem perto da sua resposta da retina!
Dom Hastings

Oh, eu vejo porque você perguntou agora. Se precisamos remover o espaço em branco na frente das palavras, também preciso de outro byte. A pergunta diz especificamente "espaços". Eu pedi esclarecimentos.
Martin Ender

@ MartinBüttner Acho que meu comentário também não foi muito claro! Obrigado pelos seus comentários!
Dom Hastings
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.