code-golf - example - html code tag
Código de golf: eliminación de caracteres duplicados en cadena (30)
El desafío: el código más corto, por número de caracteres , que detecta y elimina los caracteres duplicados en una cadena. La eliminación incluye TODAS las instancias del carácter duplicado (por lo tanto, si encuentra 3 n, las tres tienen que ir), y se debe preservar el orden original de los caracteres.
Ejemplo de entrada 1:
nbHHkRvrXbvknEjemplo de salida 1:
RrX
Ejemplo de entrada 2:
nbHHkRbvnrXbvknEjemplo de salida 2:
RrX
(El segundo ejemplo elimina las letras que aparecen tres veces; algunas soluciones no lo han tenido en cuenta)
(Esto se basa en mi otra pregunta, en la que necesitaba la forma más rápida de hacerlo en C #, pero creo que es un buen Code Golf en todos los idiomas).
APL
23 caracteres:
(((1+ρx)-(ϕx)ιx)=xιx)/x
Soy un novato en APL (lo aprendí ayer), así que sé amable: ciertamente no es la forma más eficiente de hacerlo. Me avergüenzo de no vencer a Perl mucho.
Por otra parte, tal vez diga algo cuando la forma más natural para un novato de resolver este problema en APL era aún más concisa que cualquier otra solución en cualquier idioma hasta ahora.
C: 83 89 93 99 101 caracteres
- O (n 2 ) tiempo.
- Limitado a 999 caracteres.
- Solo funciona en modo de 32 bits (debido a que no
#include
-ing<stdio.h>
(cuesta 18 caracteres) haciendo que el tipo de retornogets
interprete como unint
y corte la mitad de los bits de dirección). - Muestra una "advertencia amigable: este programa usa gets (), que no es seguro". en Macs.
.
main(){char s[999],*c=gets(s);for(;*c;c++)strchr(s,*c)-strrchr(s,*c)||putchar(*c);}
(y esta versión similar de 82- carros toma entrada a través de la línea de comando:
main(char*c,char**S){for(c=*++S;*c;c++)strchr(*S,*c)-strrchr(*S,*c)||putchar(*c);}
)
Golfscript (sym) - 15
.`{/{=}+,,(!}+,
+-------------------------------------------------------------------------+
|| | | | | | | | | | | | | | | |
|0 10 20 30 40 50 60 70 |
| |
+-------------------------------------------------------------------------+
Haskell
Seguramente hay maneras más cortas de hacer esto en Haskell, pero:
Prelude Data.List> let h y=[x|x<-y,(<2).length$filter(==x)y]
Prelude Data.List> h "nbHHkRvrXbvkn"
"RrX"
Ignorando let, ya que solo se requiere para las declaraciones de funciones en GHCi, tenemos hy=[x|x<-y,(<2).length$filter(==x)y]
, que es de 37 caracteres (esto une el Python "núcleo" actual de "".join(c for c in s if s.count(c)<2)
, y es prácticamente el mismo código de todos modos).
Si quieres hacer un programa completo de eso,
h y=[x|x<-y,(<2).length$filter(==x)y]
main=interact h
$ echo "nbHHkRvrXbvkn" | runghc tmp.hs
RrX
$ wc -c tmp.hs
54 tmp.hs
O podemos eliminar a un personaje de esta manera:
main=interact(/y->[x|x<-y,(<2).length$filter(==x)y])
$ echo "nbHHkRvrXbvkn" | runghc tmp2.hs
RrX
$ wc -c tmp2.hs
53 tmp2.hs
Funciona en todos los stdin, no línea por línea, pero eso parece IMO aceptable.
PHP
Código real de 118 caracteres (más 6 caracteres para la etiqueta de bloque de PHP):
<?php
$s=trim(fgets(STDIN));$x='''';while(strlen($s)){$t=str_replace($s[0],'''',substr($s,1),$c);$x.=$c?'''':$s[0];$s=$t;}echo$x;
Shell / Coreutils, 37 personajes
fold -w1|sort|uniq -u|paste -s -d ''''
C89 (106 caracteres)
Este utiliza un método completamente diferente que mi respuesta original. Curiosamente, después de escribirlo y luego buscar otra respuesta , vi que los métodos eran muy similares. Créditos a caf por idear este método antes que yo.
b[256];l;x;main(c){while((c=getchar())>=0)b[c]=b[c]?1:--l;
for(;x-->l;)for(c=256;c;)b[--c]-x?0:putchar(c);}
En una línea, es 58 + 48 = 106 bytes .
C89 (173 caracteres)
Esta fue mi respuesta original. Como se dijo en los comentarios, no funciona muy bien ...
#include<stdio.h>
main(l,s){char*b,*d;for(b=l=s=0;l==s;s+=fread(b+s,1,9,stdin))b=realloc(b,l+=9)
;d=b;for(l=0;l<s;++d)if(!memchr(b,*d,l)&!memchr(d+1,*d,s-l++-1))putchar(*d);}
En dos líneas, es 17 + 1 + 78 + 77 = 173 bytes .
DO#
65 personajes:
new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());
67 personajes con reasignación:
h=new String(h.Where(x=>h.IndexOf(x)==h.LastIndexOf(x)).ToArray());
DO#
new string(input.GroupBy(c => c).Where(g => g.Count() == 1).ToArray());
71 caracteres
Haskell Pointfree
import Data.List
import Control.Monad
import Control.Arrow
main=interact$liftM2(//)nub$ap(//)nub
El programa completo tiene 97 caracteres, pero la verdadera es solo 23 caracteres. El resto es solo importaciones y llevar la función a la mónada IO. En Ghci con los módulos cargados es solo
(liftM2(//)nub$ap(//)nub) "nbHHkRvrXbvkn"
En un estilo libre de puntos aún más ridículo (¿un estilo sin sentido?):
main=interact$liftM2 ap liftM2 ap(//)nub
Aunque es un poco más largo en 26 caracteres para la función en sí.
Javascript 1.6
s.match(/(.)(?=.*/1)/g).map(function(m){s=s.replace(RegExp(m,''g''),'''')})
Más corto que la solución Javascript 1.8 publicada anteriormente (71 caracteres frente a 85)
Javascript 1.8
s.split('''').filter(function (o,i,a) a.filter(function(p) o===p).length <2 ).join('''');
o alternativamente, similar al ejemplo de python:
[s[c] for (c in s) if (s.split("").filter(function(p) s[c]===p).length <2)].join('''');
LabVIEW 7.1
UN carácter y esa es la constante azul '' 1 '' en el diagrama de bloques. Lo juro, la entrada fue copiar y pegar ;-)
PHP (136 caracteres)
<?PHP
function q($x){return $x<2;}echo implode(array_keys(array_filter(
array_count_values(str_split(stream_get_contents(STDIN))),''q'')));
En una línea, es 5 + 1 + 65 + 65 = 136 bytes . Usando PHP 5.3 podría guardar unos pocos bytes haciendo que la función sea anónima, pero no puedo probar eso ahora. Quizás algo como:
<?PHP
echo implode(array_keys(array_filter(array_count_values(str_split(
stream_get_contents(STDIN))),function($x){return $x<2;})));
Eso es 5 + 1 + 66 + 59 = 131 bytes.
Perl
21 caracteres de perl, 31 para invocar, 36 pulsaciones de teclas totales (contando turno y retorno final):
perl -pe''s/$1//gwhile/(.).*/1/''
Pitón:
s=raw_input()
print filter(lambda c:s.count(c)<2,s)
Este es un programa de trabajo completo, que lee y escribe en la consola. La versión de una sola línea se puede usar directamente desde la línea de comandos
python -c ''s=raw_input();print filter(lambda c:s.count(c)<2,s)''
Potencia Shell
61 caracteres. Donde $s="nbHHkRvrXbvkn"
y $a
es el resultado.
$h=@{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}
Script parametrizado completamente funcional:
param($s)
$h=@{}
($c=[char[]]$s)|%{$h[$_]++}
$c|%{if($h[$_]-eq1){$a+=$_}}
$a
Rubí
63 caracteres.
puts (t=gets.split(//)).map{|i|t.count(i)>1?nil:i}.compact.join
Ruby - 61 53 51 56 35
61 caracteres, dice la regla. (Me da una idea para otro código de golf ...)
puts ((i=gets.split(''''))-i.select{|c|i.to_s.count(c)<2}).join
+-------------------------------------------------------------------------+
|| | | | | | | | | | | | | | | |
|0 10 20 30 40 50 60 70 |
| |
+-------------------------------------------------------------------------+
gets.chars{|c|$><<c[$_.count(c)-1]}
... 35 por Nakilon
Scala
54 caracteres para el cuerpo del método solamente, 66 con declaración del método (estáticamente tipado):
def s(s:String)=(""/:s)((a,b)=>if(s.filter(c=>c==b).size>1)a else a+b)
TCL
123 caracteres. Podría ser posible acortarlo, pero esto es lo suficientemente bueno para mí.
proc h {i {r {}}} {foreach c [split $i {}] {if {[llength [split $i $c]]==2} {set r $r$c}}
return $r}
puts [h [gets stdin]]
VB.NET / LINQ
96 caracteres para una declaración de trabajo completa
Dim p=New String((From c In"nbHHkRvrXbvkn"Group c By c Into i=Count Where i=1 Select c).ToArray)
Declaración de trabajo completa, con la cadena original y el VB específico "Lista bonita (reformateo de código" desactivada, con 96 caracteres, declaración no operativa sin cadena original con 84 caracteres).
(Por favor, asegúrese de que su código funcione antes de responder. Gracias.)
VB.NET
For Each c In s : s = IIf(s.LastIndexOf(c) <> s.IndexOf(c), s.Replace(CStr(c), Nothing), s) : Next
Por supuesto, VB no es el lenguaje óptimo para tratar de salvar personajes, pero la línea sale a 98 caracteres.
do
Programa completo en C, 141 bytes (contabilizando nuevas líneas).
#include<stdio.h>
c,n[256],o,i=1;main(){for(;c-EOF;c=getchar())c-EOF?n[c]=n[c]?-1:o++:0;for(;i<o;i++)for(c=0;c<256;c++)n[c]-i?0:putchar(c);}
otra solución APL
Como función dinámica (18 caracteres).
{(1+=/¨(ω∘∊¨ω))/ω}
línea suponiendo que la entrada está en la variable x (16 caracteres):
(1+=/¨(x∘∊¨x))/x
C # (53 caracteres)
Donde s es su cadena de entrada:
new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());
O 59 con reasignación:
var a=new string(s.Where(c=>s.Count(h=>h==c)<2).ToArray());
Haskell
(solo derribando algunos personajes del esfuerzo de Mark Rushakoff, preferiría que se publicara como un comentario sobre el suyo)
h y=[x|x<-y,[_]<-[filter(==x)y]]
que es mejor el lenguaje de Haskell, pero tal vez sea más difícil de seguir para los que no son Haskellers que esto:
h y=[z|x<-y,[z]<-[filter(==x)y]]
Editar para agregar una explicación para hiena y otros:
Asumiré que entiendes la versión de Mark, así que cubriré el cambio. La expresión de Mark:
(<2).length $ filter (==x) y
filtros y
para obtener la lista de elementos que == x
, encuentra la longitud de esa lista y se asegura de que sea menor que dos. (de hecho, debe tener la longitud uno, pero ==1
es más largo que <2
) Mi versión:
[z] <- [filter(==x)y]
hace el mismo filtro, luego coloca la lista resultante en una lista como el único elemento. Ahora, la flecha (¡que parece ser una inclusión de conjunto!) Dice "para cada elemento de la lista RHS a su vez, llame a ese elemento [z]
". [z]
es la lista que contiene el elemento único z
, por lo que el elemento " filter(==x)y
" solo se puede llamar " [z]
" si contiene exactamente un elemento. De lo contrario, se desecha y nunca se usa como un valor de z
. Entonces, las z
(que se devuelven a la izquierda de |
en la lista de comprensión) son exactamente las x
que hacen que el filter
devuelva una lista de longitud uno.
Esa fue mi segunda versión, mi primera versión devuelve x
lugar de z
, porque de todos modos son iguales, y cambia el nombre de z
a _
que es el símbolo de Haskell para "este valor no se utilizará, así que no voy a ir Para complicar mi código dándole un nombre ".
do
(1ª versión: 112 caracteres; 2ª versión: 107 caracteres)
k[256],o[100000],p,c;main(){while((c=getchar())!=-1)++k[o[p++]=c];for(c=0;c<p;c++)if(k[o[c]]==1)putchar(o[c]);}
Eso es
/* #include <stdio.h> */
/* int */ k[256], o[100000], p, c;
/* int */ main(/* void */) {
while((c=getchar()) != -1/*EOF*/) {
++k[o[p++] = /*(unsigned char)*/c];
}
for(c=0; c<p; c++) {
if(k[o[c]] == 1) {
putchar(o[c]);
}
}
/* return 0; */
}
Como getchar () devuelve int y putchar acepta int, el #include puede eliminarse ''de forma segura''. Sin el include, EOF no está definido, así que usé -1 en su lugar (y gané un char). ¡Este programa solo funciona para entradas con menos de 100000 caracteres!
Versión 2, gracias a strager 107 caracteres.
#ifdef NICE_LAYOUT
#include <stdio.h>
/* global variables are initialized to 0 */
int char_count[256]; /* k in the other layout */
int char_order[999999]; /* o ... */
int char_index; /* p */
int main(int ch_n_loop, char **dummy) /* c */
/* variable with 2 uses */
{
(void)dummy; /* make warning about unused variable go away */
while ((ch_n_loop = getchar()) >= 0) /* EOF is, by definition, negative */
{
++char_count[ ( char_order[char_index++] = ch_n_loop ) ];
/* assignment, and increment, inside the array index */
}
/* reuse ch_n_loop */
for (ch_n_loop = 0; ch_n_loop < char_index; ch_n_loop++) {
(char_count[char_order[ch_n_loop]] - 1) ? 0 : putchar(char_order[ch_n_loop]);
}
return 0;
}
#else
k[256],o[999999],p;main(c){while((c=getchar())>=0)++k[o[p++]=c];for(c=0;c<p;c++)k[o[c]]-1?0:putchar(o[c]);}
#endif
Ensamblador
Probado con el cuadro de WinXP DOS (cmd.exe):
xchg cx,bp
std
mov al,2
rep stosb
inc cl
l0: ; to save a byte, I''ve encoded the instruction to exit the program into the
; low byte of the offset in the following instruction:
lea si,[di+01c3h]
push si
l1: mov dx,bp
mov ah,6
int 21h
jz l2
mov bl,al
shr byte ptr [di+bx],cl
jz l1
inc si
mov [si],bx
jmp l1
l2: pop si
l3: inc si
mov bl,[si]
cmp bl,bh
je l0+2
cmp [di+bx],cl
jne l3
mov dl,bl
mov ah,2
int 21h
jmp l3
Se ensambla a 53 bytes. Lee la entrada estándar y escribe los resultados en la salida estándar, por ejemplo:
programname < input > output
J ( 16 12 caracteres)
(~.{~[:I.1=#/.~)
Ejemplo:
(~.{~[:I.1=#/.~) ''nbHHkRvrXbvkn'' RrX
Solo necesita que el paréntesis sea ejecutado tácitamente. Si se pone en un verbo, el código real en sí sería 14 caracteres.
Ciertamente hay formas más inteligentes de hacer esto.
EDITAR: la forma más inteligente en cuestión:
(~.#~1=#/.~) ''nbHHkRvrXbvkn'' RrX
12 caracteres, solo 10 si se establece en un verbo. Todavía odio el hecho de que esté repasando la lista dos veces, una vez para contar (# /.) Y otra para devolver uniques (nub o ~.), Pero incluso nubcount, un verbo estándar en la biblioteca ''misc'' lo hace dos veces.