Muchos idiomas tienen formas integradas para deshacerse de los duplicados, o "deduplicar" o "uniquificar" una lista o cadena. Una tarea menos común es "detriplicar" una cadena. Es decir, por cada personaje que aparece, el primero se mantienen las dos ocurrencias.
Aquí hay un ejemplo donde los caracteres que deben eliminarse están etiquetados con ^
:
aaabcbccdbabdcd
^ ^ ^^^ ^^
aabcbcdd
Su tarea es implementar exactamente esta operación.
Reglas
La entrada es una sola cadena, posiblemente vacía. Puede suponer que solo contiene letras minúsculas en el rango ASCII.
La salida debe ser una sola cadena con todos los caracteres eliminados que ya han aparecido al menos dos veces en la cadena (por lo que se conservan las dos ocurrencias más a la izquierda).
En lugar de cadenas, puede trabajar con listas de caracteres (o cadenas de un solo tono), pero el formato debe ser coherente entre la entrada y la salida.
Puede escribir un programa o una función y utilizar cualquiera de nuestros métodos estándar para recibir entradas y proporcionar salidas.
Puede usar cualquier lenguaje de programación , pero tenga en cuenta que estas lagunas están prohibidas de forma predeterminada.
Este es el código de golf , por lo que gana la respuesta válida más corta, medida en bytes .
Casos de prueba
Cada par de líneas es un caso de prueba, entrada seguido de salida.
xxxxx
xx
abcabc
abcabc
abcdabcaba
abcdabc
abacbadcba
abacbdc
aaabcbccdbabdcd
aabcbcdd
Tabla de clasificación
El Fragmento de pila al final de esta publicación genera una tabla de clasificación a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.
Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:
## Language Name, N bytes
¿Dónde N
está el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:
## Perl, 43 + 3 (-p flag) = 45 bytes
También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 86503; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 8478; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
Respuestas:
Jalea , 6 bytes
Pruébalo en línea! o verificar todos los casos de prueba .
Cómo funciona
fuente
JavaScript (ES6), 42
48Editar la friolera de 6 bytes guardados gracias a @Neil
Explicación: Utilizo las propiedades 'a' ... 'z' del objeto
k
para almacenar información para cada carácter (el objeto k es una expresión regular en este caso solo para guardar bytes). Estas propiedades son inicialmenteundefined
. En javascript, agregar un número paraundefined
darNaN
(bastante razonable), pero agregar una cadena 'X' da"undefinedX"
- una cadena de longitud 10 (tonto). Agregando más caracteres obtienes cadenas más largas. Si la cadena obtenida para un carácter dado es mayor que 11, ese carácter no se copia a la salida.Prueba
fuente
v=>v.filter(x=>!(v[x]+=x)[11])
. Felicitaciones por el truco "indefinido".Python 2, 48 bytes
c[r.count(c)/2:]
es una alternativa de la misma longitud ac*(r.count(c)<2)
.49 bytes:
fuente
Retina , 17 bytes
Pruébalo en línea!
Reemplazo simple de expresiones regulares: empareja un personaje si ya apareció dos veces y retíralo.
fuente
{2}
ambos con 18 bytes.:P
. ¡Gracias!Brachylog , 25 bytes
Pruébalo en línea! o verificar todos los casos de prueba .
Explicación
Esto funciona porque
s - Subset
primero se unificará con subconjuntos más grandes, por lo tanto, por ejemplo"aaa"
, lo intentará"aa"
antes"a"
.Predicado principal:
Predicado 1: compruebe que todos los caracteres solo aparezcan dos veces como máximo. Entrada =
[String:Char]
Predicado 2: Obtener una ocurrencia de un personaje. Entrada =
[String:Char]
fuente
> <> , 22 bytes
Pruébalo en línea! Utiliza el cuadro de código para realizar un seguimiento de los recuentos hasta ahora.
fuente
J,
2015 bytesEsto define una función monádica que toma y devuelve una cadena. Pruébalo aquí . Uso:
Explicación
Cambié al mismo algoritmo que usan otras soluciones, ya que resultó ser más corto ...
fuente
Haskell,
4039 bytesEjemplo de uso:
foldl(\s c->s++[c|filter(==c)s<=[c]])"" "aaabcbccdbabdcd"
->"aabcbcdd"
.Mantenga el siguiente carácter
c
si la cadena de todos losc
s hasta ahora son lexicográficos menores o iguales que la cadena singleton[c]
.Editar: @xnor guardó un byte al cambiar de comprensión de lista a
filter
. ¡Gracias!fuente
filter(==c)s<=[c]
para guardar un byte.Perl, 22 bytes
Código de 21 bytes + 1 para
-p
.Uso
fuente
C, 57 bytes
Llame
f()
con la cuerda para detriplicar. La función modifica su parámetro. Requiere C99 debido a lafor
declaración -loop.fuente
s
en la primera declaración de lafor
?JavaScript (ES6), 35 bytes
Toma una matriz de caracteres como entrada y devuelve la matriz destriplicada.
fuente
c=>(s[c]=-~s[c])<3
para guardar algunos bytes.map
. Golfizado se parecía esencialmente al tuyo. La principal diferencia era la asignación, que si la cambia, ahorrará unos pocos bytes. Pruebas.filter(c=>(s[c]=s[c]+1|0)<3)
por 33 bytes. EDITAR: Whoops, se perdió el comentario sobre mí, eso es aún mejor :)PowerShell v2 +, 31 bytes
Utiliza la misma expresión regular que en la respuesta Retina de Kobi , simplemente encapsulada en el
-replace
operador PowerShell . Funciona porque ambos usan .NET-taste regex en segundo plano.Alternativamente, sin expresiones regulares, 56 bytes
Crea una matriz auxiliar
$b
previamente rellenada con0
s. Lanza la cadena de entrada$args[0]
como unachar
matriz, la canaliza a través de un bucle|%{...}
. Cada iteración genera el carácter actual$_
como una cadena"$_"
multiplicada por un booleano que solo$TRUE
(se arroja implícitamente1
aquí) si el punto apropiado en la matriz auxiliar es menor que2
(es decir, no hemos visto este carácter dos veces). La colección resultante de cadenas se encapsula en parens y se editan-join
juntas para formar una sola cadena de salida. Eso queda en la tubería y la salida es implícita.fuente
$b=@{};-join($args|% t*y|?{++$b.$_-lt3})
.Mathematica, 39 bytes
Función anónima. Toma una lista de caracteres como entrada y devuelve la lista destriplicada como salida. Utiliza el método de plegar sobre la lista y rechazar elementos triplicados, no es demasiado complicado.
fuente
05AB1E, 12 bytes
Explicación
Pruébalo en línea
fuente
MATL , 8 bytes
Pruébalo en línea!
Explicación
Ejemplo
Suponiendo una entrada
'aaababbc'
, la pila contiene lo siguiente después de las declaraciones indicadas:t
t&=
t&=R
t&=Rs
t&=Rs3<
t&=Rs3<)
fuente
Retina , 14 bytes
Verifique todos los casos de prueba. (
%
Activa el modo por línea)Utiliza la nueva etapa "Deduplicar" para guardar un par de bytes sobre el enfoque de Kobi . Deduplicate reúne una lista de todas las coincidencias con la expresión regular y reemplaza todas menos la primera con la cadena vacía. La expresión regular coincide con un carácter que ya aparece una vez en la cadena, lo que significa que se mantendrán los dos primeros.
fuente
Pyke, 16 bytes
Pruébalo aquí!
fuente
K, 18 bytes
K4 está disponible para descarga gratuita ; K6 está en desarrollo . Si ha descargado KDB, puede ingresar a K con barra invertida .
Puede ser más fácil ver esto dividido, pero primero una sintaxis: se
g:x
estableceg
enx
.{x+1}
es una función que toma un argumento x . En K, el primer argumento para una función esx
(el segundo esy
y el tercero esz
. No necesita un cuarto).Ahora:
=x
significa grupo x , que produce:2#'
significa dos tomados (de) cada uno que produceComo puede ver, estos son los desplazamientos de las dos primeras coincidencias de cada personaje. los 2 podrían ser generalizados.
,/
significa unirse a cada uno y a menudo se llama raze . Nos dará los valores de nuestro diccionario. Por lo tanto,,/"abcd"!(0 1;3 5;4 6;8 12)
produce:que debemos clasificar
{x@<x}@
es un idioma que los programadores de K a menudo ven (Q lo llama asc ), que dice x al subir de grado x . Rompiéndolo aparte:devolvió los índices de la matriz ordenada, que queremos tomar de la matriz original.
x@y
significa x en y así que esto indexa la matriz con los índices del tipo (si eso tiene sentido).que simplemente indexamos ahora en nuestra matriz original. Nosotros podríamos decir
x@
aquí, pero K es compatible con un concepto muy potente, que podemos aprovechar aquí: aplicación de función es la indexación. Eso significa quea[0]
podría estar buscando la ranura cero dea
o podría estar aplicando el0
a la función llamadaa
. La razón por la que necesitábamos@
anteriormente{x@<x}
es porquex<y
significa xs menos que ys : los operadores en K tienen una forma diádica (dos argumentos) y una forma monádica (un argumento) que proviene de APL. Q no tiene esta "ambivalencia".fuente
g"aaabcbccdbabdcd"
g"..."
funciona. Desafortunadamente, su código vuelveaabbcc
para la entradaabc
.{x{?x@<x}@,/2#'=x}"abc"
definitivamente regresa"abc"
. Volvería"aabbcc"
si te perdieras lo?
distinto.Python 2, 51 bytes
Pruébalo en Ideone .
fuente
Java 8 lambda, 90 caracteres
Versión sin golf:
Crea una matriz para todos los caracteres ascii. Si se produce un personaje, el contador correspondiente aumentará. Si es superior a 2, el carácter no se agregará a la cadena de resultados. Muy fácil, muy corto;)
fuente
Perl 6, 27 bytes
Explicación:
(Nota: Perl 6 no está tan "orientado al golf" como su hermana Perl 5 ... Entonces sí, ese espacio antes de que
<
sea necesario.%.{}
Es un hash anónimo).fuente
SmileBASIC,
77726968 bytesExplicado:
fuente
Lisp común, 127
Bonito estampado
fuente
Q , 52 bytes
fuente
K , 27 bytes
fuente
Ruby ,
796257 bytesEsto es bastante difícil de manejar, pero no estoy seguro de poder jugar golf mucho mejor en este momento. Cualquier sugerencia de golf es bienvenida. Pruébalo en línea!
Editar: -17 bytes gracias a Value Ink al sugerir una forma más golfista de eliminar los caracteres triplicados. -5 bytes de eliminar el
.uniq
método.Sin golf:
fuente
->s{s.chars.uniq.map{|a|s[s.rindex a]=""while s.count(a)>2};s}
JavaScript, 30 bytes
Usando el método que @ edc65 ideó para contar pero con un filtro de matriz. La primera vez que aparece el carácter, el valor del objeto se vuelve "indefinido" más el carácter (es decir, "undefinedx"). La próxima vez que el valor del objeto se convierta en "undefinedxx".
Después de eso, v [x] [11] devuelve verdadero y cuando se combina con el operador no, falso, lo que significa que los caracteres que ya han aparecido dos veces se filtrarán.
fuente
Javascript (usando una biblioteca externa) (80 bytes)
Esta fue una buena! No gané pero fue divertido
Enlace a lib: https://github.com/mvegh1/Enumerable/
Explicación del código: el método acepta una cadena, la biblioteca la analiza como una matriz de caracteres y la cláusula Where es un predicado de filtrado complejo que verifica la presencia del carácter actual del hashmap 'a'. Si existe, incremente el contador, si no, ajústelo a 1. Si <2, el predicado (y el carácter actual) pasa, de lo contrario falla
fuente
return
, sino de hacer su función de una lista separada por comas de una de las expresiones entre paréntesis:n=>(a={},_From(n)....)
. La última expresión es el valor de retorno. En suWhere
función, se puede eliminar la intermediab
por completo mediante la comparación contra el resultado de la cesión o de la subasta:x=>(a[x]?a[x]++:a[x]=1)<2
.filter
conjoin
:[...n].filter(...).join("")
. Voltee la lógica verdadero / falso al cambiarWhere
afilter
.Clojure, 72 bytes
Tantos bytes ...
fuente
Pascal (FPC) , 103 bytes
Pruébalo en línea!
Explicación:
fuente