Removendo elementos exclusivos da string

12

Eu me deparei com essa pergunta, porque parece ser um caso de uso muito comum encontrar caracteres únicos na string. Mas e se quisermos nos livrar deles?

A entrada contém apenas letras minúsculas. Somente letras de a a z são usadas. O comprimento da entrada pode ter de 1 a 1000 caracteres.

Exemplo:
input: helloworld
output: llool

Objetivo: o menor código vence
Idioma: qualquer um dos 20 principais idiomas do TIOBE

user14742
fonte

Respostas:

7

Perl, 28 24 caracteres (inclui 1 para a opção 'p')

s/./$&x(s!$&!$&!g>1)/eg

Uso:

> perl -pe 's/./$&x(s!$&!$&!g>1)/eg'
helloworld
llool

No começo, pensei que poderia fazer isso com um look-ahead negativo e um look-behind negativo, mas acontece que os look-behind negativos devem ter um comprimento fixo. Então, eu fui para expressões regulares aninhadas. Com agradecimentos ao mob pela $&dica.

Gareth
fonte
+1. Ingenuamente, pensei que poderia aceitar isso com a minha resposta Ruby.
9118 Steven Rumbalski
Eu tentei isso no texto chinês e não fez o truque. = (
ixtmixilix 12/12/12
@ixtmixilix - perl, em seguida, executado com a -CDSopção
mob
@ixtmixilix Não sei o suficiente sobre o unicode e o suporte do Perl para sugerir uma maneira de fazê-lo funcionar com texto em chinês. Felizmente para mim, a pergunta diz apenas letras minúsculas de a a z.
Gareth
1
Substitua tudo $1por $&e você poderá perder alguns pares de parênteses.
Mob
12

(GolfScript, 15 13 caracteres)

:;{.;?);>?)},

O GolfScript não é um dos 20 principais, mas um codegolf sem o GolfScript ... ( execute você mesmo )

Versão anterior: ( executar script )

1/:;{;\-,;,(<},
Howard
fonte
1
:;? Você está deliberadamente tentando confundir novatos, não é? ;)
Peter Taylor
@ PeterTaylor Você está certo. Eu deveria ter escolhido um )- seria um sorriso então :). Infelizmente, não encontrei uma maneira de eliminar o dígito 1. (Nota para iniciantes no GolfScript: você pode substituir qualquer um ;no código por um x(ou qualquer outra letra ou dígito - ou qualquer caractere não utilizado no script). Nesse caso especial, ;é apenas um nome de variável - e não tem o significado "pop and descarte". No GolfScript, quase todos os tokens são variáveis, e o uso de símbolos predefinidos é uma ótima maneira de tornar os scripts ainda mais ilegíveis para quem está de fora ;-).)
1011 Howard
Outra solução de 13-char::a{]a.@--,(},
Ilmari Karonen
7

J, 12 caracteres

Depois de inserir uma resposta Perl válida, eis uma resposta inválida (o idioma não está no top 20 do TIOBE).

a=:#~1<+/@e.

Uso:

   a 'helloworld'
llool

Declara um verbo aque gera apenas itens não exclusivos.

Gareth
fonte
5

GolfScript (14 caracteres)

:x{{=}+x\,,(},

Demonstração online

Pode não se qualificar para ganhar, mas é útil ter um critério.

Peter Taylor
fonte
4

Rubi 46 40 36

gets.chars{|c|$><<c if$_.count(c)>1}
Steven Rumbalski
fonte
Você pode salvar 4 caracteres se alinhar se usar $_para a segunda aparição (o espaço anterior é então dispensável).
1011 Howard
@ Howard: captura agradável. Obrigado. Eu tenho quase nenhuma experiência com Ruby.
Steven Rumbalski 11/11/12
2

Perl 44

$l=$_;print join"",grep{$l=~/$_.*$_/}split""

Execução:

perl -lane '$l=$_;print join"",grep{$l=~/$_.*$_/}split""' <<< helloworld
llool
modelo
fonte
2

K, 18

{x@&x in&~1=#:'=x}
tmartin
fonte
Você pode salvar um byte usando em 1<#vez de~1=#
J. Sendra
2

Python 2.7 ( 52 51), Python 3 (52)

Eu não esperava que fosse tão curto.

2.7: a=raw_input();print filter(lambda x:a.count(x)>1,a)

3.0: a=input();print''.join(i for i in a if a.count(x)>1)

raw_input(): armazena a entrada como uma string ( input()= eval(raw_input()))
(Python 3.0: input()foi transformado em raw_input())

filter(lambda x:a.count(x)>1,a): Filtre todos os caracteres contidos ase forem encontrados amais de uma vez ( a.count(x)>1).

beary605
fonte
Se você usar python 3, poderá usar em input()vez de raw_input(). Embora você tem que adicionar um personagem para um colchete de fechamento, uma vez que printé uma função em python 3.
strigoides
@ Strigoides: adicionei um trecho de código Python 3 à minha resposta.
beary605
O filtro do Python 3 retorna um iterador ... Você precisa fazer isso #''.join(...)
JBernardo 16/12/12
.. @JBernardo: :( Dang Obrigado por me notificar Como você pode ver, eu não uso 3.0.
beary605
2

sed e coreutils (128)

Concedido que isso não faz parte da lista TIOBE, mas é divertido (-:

<<<$s sed 's/./&\n/g'|head -c -1|sort|uniq -c|sed -n 's/^ *1 (.*)/\1/p'|tr -d '\n'|sed 's:^:s/[:; s:$:]//g\n:'|sed -f - <(<<<$s)

Versão descolada:

s=helloworld
<<< $s sed 's/./&\n/g'        \
| head -c -1                  \
| sort                        \
| uniq -c                     \
| sed -n 's/^ *1 (.*)/\1/p'   \
| tr -d '\n'                  \
| sed 's:^:s/[:; s:$:]//g\n:' \
| sed -f - <(<<< $s)

Explicação

O primeiro sed converte a entrada em um caractere por linha. O segundo sed encontra caracteres que ocorrem apenas uma vez. O terceiro sed grava um script sed que exclui caracteres únicos. O último sed executa o script gerado.

Thor
fonte
2

Brachylog (v2), 8 bytes

⊇.oḅlⁿ1∧

Experimente online!

Envio de função. Tecnicamente não competitivo, porque a pergunta tem uma limitação sobre quais idiomas podem competir (no entanto, várias outras respostas já ignoraram a restrição).

Explicação

⊇.oḅlⁿ1∧
⊇         Find {the longest possible} subset of the input
  o       {for which after} sorting it,
   ḅ        and dividing the sorted input into blocks of identical elements,
    lⁿ1     the length of a resulting block is never 1
 .     ∧  Output the subset in question.
ais523
fonte
Por que você CW todas as suas soluções?
Shaggy
1
@ Shaggy: a) porque eu estou bem com outras pessoas editando-as, b) para evitar ganhar reputação se forem votadas. Em geral, acho que a gamififcação do Stack Exchange é um enorme prejuízo para o site - às vezes há uma correlação negativa entre as ações que você pode executar para melhorar o representante e as ações que você pode executar para melhorar o site. Além disso, ter uma reputação alta é uma merda; o site continua incomodando você para executar tarefas administrativas, e tudo o que você faz é um instrumento contundente (por exemplo, quando você está em baixa rep, você pode sugerir uma edição, em alta rep, isso apenas é forçado).
ais523
2

Japonês , 6 5 bytes

ÆèX É

-1 byte graças a @Oliver

Experimente online!

Quintec
fonte
2
Bem-vindo ao Japt! Na verdade, existe um atalho para o@:Æ
Oliver
@Oliver Outro atalho que eu perdi, fresco, graças :)
QUINTEC
@ Oliver, a melhor pergunta é como diabos eu perdi ?! : \
Shaggy
1

Python (56)

Aqui está outra alternativa (alguns caracteres a mais) no Python:

a=raw_input();print''.join(c for c in a if a.count(c)>1)

Se você aceitar a saída como uma lista (por exemplo ['l', 'l', 'o', 'o', 'l']), poderemos reduzi-la para 49 caracteres:

a=raw_input();print[c for c in a if a.count(c)>1]
arshajii
fonte
Ei, >1é uma boa ideia! Posso incorporar isso na minha solução?
beary605
@ beary605 Claro nenhum problema em tudo - maneira fácil de cortar um personagem off: D
arshajii
1

Mathematica 72 63

Ok, o Mathematica não está entre os 20 principais idiomas, mas decidi me juntar à festa de qualquer maneira.

x é a sequência de entrada.

"" <> Select[y = Characters@x, ! MemberQ[Cases[Tally@y, {a_, 1} :> a], #] &]
DavidC
fonte
1

Perl (55)

@x=split//,<>;$s{$_}++for@x;for(@x){print if($s{$_}>1)}

Lê de stdin.

QuasarDonkey
fonte
1

C # - 77 caracteres

Func<string,string>F=s=>new string(s.Where(c=>s.Count(d=>c==d)>1).ToArray());

Se você aceitar a saída como uma matriz, ela se resumirá a 65 caracteres:

Func<string,char[]>F=s=>s.Where(c=>s.Count(d=>c==d)>1).ToArray();
Mormegil
fonte
1

Ocaml, 139 133

Usa ExtString.String do ExtLib

open ExtString.String
let f s=let g c=fold_left(fun a d->a+Obj.magic(d=c))0 s in replace_chars(fun c->if g c=1 then""else of_char c)s

Versão sem golfe

open ExtString.String
let f s =
  let g c =
    fold_left
      (fun a c' -> a + Obj.magic (c' = c))
      0
      s
  in replace_chars
  (fun c ->
    if g c = 1
    then ""
    else of_char c)
  s

A função gretorna o número de ocorrências de c na sequência s. A função fsubstitui todos os caracteres pela string vazia ou pela string que contém o char, dependendo do número de ocorrências. Edit: Reduzi o código em 6 caracteres abusando da representação interna de bools :-)

Ah, e ocaml é 0 no índice TIOBE ;-)

ReyCharles
fonte
f *** o índice TIOBE.
Ixtmixilix 12/12/12
Concordo. Além disso, obrigado pelo voto positivo. Agora eu posso comentar :-)
ReyCharles 12/12/12
1

PHP - 70

while($x<strlen($s)){$c=$s[$x];echo substr_count($s,$c)>1?$c:'';$x++;}

com suposição $ s = 'helloworld'.

hengky mulyono
fonte
1

Java 8, 90 bytes

s->{for(char c=96;++c<123;s=s.matches(".*"+c+".*"+c+".*")?s:s.replace(c+"",""));return s;}

Explicação:

Experimente online.

s->{                         // Method with String as both parameter and return-type
  for(char c=96;++c<123;     //  Loop over the lowercase alphabet
    s=s.matches(".*"+c+".*"+c+".*")?
                             //   If the String contains the character more than once
       s                     //    Keep the String as is
      :                      //   Else (only contains it once):
       s.replace(c+"",""));  //    Remove this character from the String
  return s;}                 //  Return the modified String
Kevin Cruijssen
fonte
1

PowerShell , 59 bytes

"$args"-replace"[^$($args|% t*y|group|?{$_.Count-1}|% n*)]"

Experimente online!

Menos golfe:

$repeatedСhars=$args|% toCharArray|group|?{$_.Count-1}|% name
"$args"-replace"[^$repeatedСhars]"

Nota: $repeatedCharsé uma matriz. Por padrão, um PowerShell junta elementos da matriz por espaço, enquanto converte a matriz em string. Portanto, o regexp contém espaços (neste exemplo [^l o]). Os espaços não afetam o resultado porque a sequência de entrada contém apenas letras.

confuso
fonte
1

APL (Dyalog Extended) , SBCS de 8 bytes

Função de prefixo tácito anônimo.

∊⊢⊆⍨1<⍧⍨

Experimente online!

⍧⍨ selfie de contagem (contagem de ocorrências de elementos de argumento no próprio argumento)

1< Máscara booleana em que um é menor que isso

⊢⊆⍨ particione o argumento por essa máscara (iniciando uma nova partição em 1s e removendo em 0s)

ε nlist (achatar)

Adão
fonte
1

JavaScript, 45 bytes

s=>[...s].filter(c=>s.match(c+'.*'+c)).join``
kamoroso94
fonte
1

R , 70 bytes

a=utf8ToInt(scan(,''));intToUtf8(a[!a%in%names(table(a)[table(a)<2])])

Experimente online!

Uma péssima tentativa, mesmo em um dos 20 principais idiomas da TIOBE. Sei que algo pode ser feito no segundo tempo, mas, no momento, qualquer jogador de golfe me escapa.

Sumner18
fonte
0

PHP - 137

Código

implode('',array_intersect(str_split($text),array_flip(array_filter(array_count_values(str_split($text)),function($x){return $x>=2;}))));

Código normal

$text   = 'helloworld';
$filter = array_filter(array_count_values(str_split($text)), function($x){return $x>=2;});
$output = implode('',array_intersect(str_split($text),array_flip($filter)));

echo $output;
Wahyu Kristianto
fonte
0

PHP - 83 78

<?for($a=$argv[1];$i<strlen($a);$r[$a[$i++]]++)foreach($ras$k=>$c)if($c>1)echo$k

Versão melhorada:

<?for($s=$argv[1];$x<strlen($s);$c=$s[$x++]) echo substr_count($s,$c)>1?$c:'';

É claro que isso precisa ser desativado

Edit: Melhoria inspirada em @hengky mulyono

Eu sou tão ruim em codegolf :)

milo5b
fonte
0

C ++, 139 bytes

string s;cin>>s;string w{s}; auto l=remove_if(begin(s),end(s),[&w](auto&s){return count(begin(w),end(w),s)==1;});s.erase(l,end(s));cout<<s;

ungolfed:

#include <algorithm>
#include <string>
#include <iostream>

int main() {
  using namespace std;
  string s;
  cin >> s;
  const string w{s};
  auto l = remove_if(begin(s), end(s), [&w](auto& s) {
                                         return count(begin(w), end(w), s) == 1;
                                       });
  s.erase(l, end(s));
  cout << s;
  return 0;
}
zelcon
fonte