Eliminar elementos únicos de la cadena

12

Encontré esta pregunta, porque parece ser un caso de uso muy común para encontrar caracteres únicos en la cadena. Pero, ¿qué pasa si queremos deshacernos de ellos?

La entrada contiene solo alfabetos en minúsculas. Solo se utilizan letras de la a a la z. La longitud de entrada puede ser de 1 a 1000 caracteres.

Ejemplo:
input: helloworld
output: llool

Objetivo: el código más corto gana
Idioma: cualquiera de los 20 principales idiomas de TIOBE

usuario14742
fuente

Respuestas:

7

Perl, 28 24 caracteres (incluye 1 para la opción 'p')

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

Uso:

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

Al principio pensé que podía hacer esto con una mirada hacia adelante negativa y una mirada hacia atrás negativa, pero resulta que las miradas negativas deben tener una longitud fija. Así que fui por expresiones regulares anidadas en su lugar. Gracias a la mafia por la informacion $&.

Gareth
fuente
+1. Ingenuamente pensé que podría tomar esto con mi respuesta de Ruby.
Steven Rumbalski
Intenté esto en texto chino y no funcionó. = (
ixtmixilix
@ixtmixilix - luego ejecuta perl con la -CDSopción
mob
@ixtmixilix No sé lo suficiente sobre Unicode y el soporte de Perl para sugerir una forma de hacerlo funcionar con texto en chino, me temo. Por suerte para mí, la pregunta dice solo minúsculas de la a a la z.
Gareth
1
Reemplace todo $1con $&y puede perder un par de paréntesis.
mafia
12

(GolfScript, 15 13 caracteres)

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

GolfScript no es uno de los 20 mejores, sino un codegolf sin GolfScript ... ( ejecútelo usted mismo )

Versión anterior: ( ejecutar script )

1/:;{;\-,;,(<},
Howard
fuente
1
:;? Intentas confundir deliberadamente a los novatos, ¿verdad? ;)
Peter Taylor
@PeterTaylor Tienes razón. Debería haber elegido un )- sería un smiley entonces :). Desafortunadamente, no encontré una forma de eliminar siquiera el dígito 1. (Nota para los novatos de GolfScript: puede reemplazar cualquiera ;en el código con un x(o cualquier otra letra o dígito, o cualquier carácter que no se use en el script). En este caso especial ;es solo un nombre de variable, y no tiene el significado "pop and descarte". En GolfScript, casi todos los tokens son variables de todos modos, y el uso de símbolos predefinidos es una excelente manera de hacer que los scripts sean aún más ilegibles para los extraños ;-).)
Howard
Otra solución de 13 caracteres::a{]a.@--,(},
Ilmari Karonen
7

J, 12 caracteres

Después de haber ingresado una respuesta Perl válida, aquí hay una respuesta no válida (idioma que no está en el top 20 de TIOBE).

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

Uso:

   a 'helloworld'
llool

Declara un verbo aque genera solo elementos no únicos.

Gareth
fuente
5

GolfScript (14 caracteres)

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

Demostración en línea

Puede que no califique para ganar, pero es útil tener un criterio.

Peter Taylor
fuente
4

Rubí 46 40 36

gets.chars{|c|$><<c if$_.count(c)>1}
Steven Rumbalski
fuente
Puede guardar 4 caracteres si está en línea sy lo usa $_para la segunda aparición (el espacio anterior es entonces prescindible).
Howard
@Howard: Buena captura. Gracias. Tengo casi cero experiencia con Ruby.
Steven Rumbalski
2

Perl 44

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

Ejecución:

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

K, 18

{x@&x in&~1=#:'=x}
tmartin
fuente
Puede guardar un byte usando 1<#en lugar de~1=#
J. Sendra
2

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

No esperaba que fuera tan corto.

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(): almacena la entrada como una cadena ( input()= eval(raw_input()))
(Python 3.0: input()se ha convertido en raw_input())

filter(lambda x:a.count(x)>1,a): Filtre a través de todos los caracteres dentro asi se encuentran en amás de una vez ( a.count(x)>1).

beary605
fuente
Si usa Python 3 en su lugar, puede usar en input()lugar de raw_input(). Aunque tiene que agregar un carácter para un corchete de cierre, ya que printes una función en Python 3.
Strigoides
@Strigoides: He agregado un fragmento de código de Python 3 a mi respuesta.
beary605
El filtro de Python 3 devuelve un iterador ... Tendrá que hacerlo''.join(...)
JBernardo
@JBernardo: :( Dang. Gracias por notificarme. Como puedes ver, no uso 3.0.
beary605
2

sed y coreutils (128)

De acuerdo, esto no es parte de la lista TIOBE, pero es 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)

Versión de golf:

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)

Explicación

El primer sed convierte la entrada en un carácter por línea. El segundo sed encuentra caracteres que solo ocurren una vez. Third sed escribe un script sed que elimina caracteres únicos. El último sed ejecuta el script generado.

Thor
fuente
2

Brachylog (v2), 8 bytes

⊇.oḅlⁿ1∧

Pruébalo en línea!

Presentación de funciones. Técnicamente no compite porque la pregunta tiene una limitación sobre qué idiomas pueden competir (sin embargo, varias otras respuestas ya han ignorado la restricción).

Explicación

⊇.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
fuente
¿Por qué utiliza CW todas sus soluciones?
Shaggy
1
@Shaggy: a) porque estoy de acuerdo con que otras personas los editen, b) para evitar ganar reputación si son votados. En general, creo que la diversificación de Stack Exchange es un gran perjuicio para el sitio: a veces hay una correlación negativa entre las acciones que puede tomar para mejorar el representante y las acciones que puede tomar para mejorar el sitio. Además, estar en una cuenta de alta reputación apesta; el sitio no deja de molestarte para que realices tareas administrativas, y todo lo que haces es un instrumento contundente (por ejemplo, cuando tienes poca repetición, puedes sugerir una edición, en una alta repetición simplemente se hace pasar).
ais523
2

Japt , 6 5 bytes

ÆèX É

-1 byte gracias a @Oliver

Pruébalo en línea!

Quintec
fuente
2
Bienvenido a Japt! En realidad hay un atajo para o@:Æ
Oliver
@Oliver Otro atajo que me perdí, genial, gracias :)
Quintec
@Oliver, la mejor pregunta es cómo el Feck no me lo pierda ?! : \
Shaggy
1

Pitón (56)

Aquí hay otra alternativa (pocos caracteres más) en Python:

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

Si acepta la salida como una lista (p ['l', 'l', 'o', 'o', 'l']. Ej. ), Podríamos reducirla a 49 caracteres:

a=raw_input();print[c for c in a if a.count(c)>1]
arshajii
fuente
¡Hola, >1es una buena idea! ¿Puedo incorporar eso en mi solución?
beary605
@ beary605 Claro que no hay problema en absoluto: forma fácil de recortar un personaje: D
arshajii
1

Mathematica 72 63

Ok, Mathematica no está entre los 20 idiomas principales, pero decidí unirme a la fiesta de todos modos.

x es la cadena de entrada.

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

Perl (55)

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

Lecturas de stdin.

QuasarDonkey
fuente
1

C # - 77 caracteres

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

Si acepta la salida como una matriz, se reduce a 65 caracteres:

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

Ocaml, 139 133

Utiliza ExtString.String de 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

Versión sin golf

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

La función gdevuelve el número de ocurrencias de c en la cadena s. La función freemplaza todos los caracteres, ya sea por la cadena vacía o la cadena que contiene el carácter, dependiendo del número de ocurrencias. Editar: acorté el código en 6 caracteres al abusar de la representación interna de bools :-)

Ah, y ocaml es 0 en el índice TIOBE ;-)

ReyCharles
fuente
f *** el índice TIOBE.
ixtmixilix
Estoy de acuerdo. Además, gracias por el voto a favor. Ahora puedo comentar :-)
ReyCharles
1

PHP - 70

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

con asunción $ s = 'helloworld'.

hengky mulyono
fuente
1

Java 8, 90 bytes

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

Explicación:

Pruébalo en línea.

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
fuente
1

PowerShell , 59 bytes

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

Pruébalo en línea!

Menos golfizado:

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

Nota: $repeatedCharses una matriz. Por defecto, un Powershell une elementos de la matriz por espacio de caracteres mientras convierte la matriz en cadena. Entonces, la expresión regular contiene espacios (en este ejemplo, [^l o]). Los espacios no afectan el resultado porque la cadena de entrada contiene solo letras.

mazzy
fuente
1

APL (Dyalog Extended) , SBCS de 8 bytes

Función de prefijo tácito anónimo.

∊⊢⊆⍨1<⍧⍨

Pruébalo en línea!

⍧⍨ selfie de recuento (cuenta las ocurrencias de elementos de argumento en el argumento mismo)

1< Máscara booleana donde uno es menor que eso

⊢⊆⍨ particione el argumento por esa máscara (comience una nueva partición en 1s y elimine en 0s)

ϵ nlist (aplanar)

Adán
fuente
1

JavaScript, 45 bytes

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

R , 70 bytes

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

Pruébalo en línea!

Un intento pobre, incluso de un lenguaje TIOBE top 20. Sé que se puede hacer algo en la segunda mitad, pero por el momento, cualquier golf se me escapa.

Sumner18
fuente
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
fuente
0

PHP - 83 78

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

Versión mejorada:

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

Por supuesto, esto necesita avisos para apagarse

Editar: Mejora inspirada en @hengky mulyono

Soy tan malo en codegolf :)

milo5b
fuente
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;

sin golf:

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