Digite uniqchars!

41

Dada uma sequência que consiste em caracteres ASCII imprimíveis , produza uma saída que consiste em seus caracteres exclusivos na ordem original . Em outras palavras, a saída é a mesma que a entrada, exceto que um caractere é removido se ele tiver aparecido anteriormente.

Nenhum componente interno para localizar elementos exclusivos em uma matriz pode ser usado (por exemplo, o MATLAB possui uma uniquefunção que faz isso). A ideia é fazê-lo manualmente.

Detalhes adicionais:

  • De qualquer funções ou programas são permitidos.
  • A entrada e a saída podem estar na forma de argumentos de função, stdin / stdout (mesmo para funções) ou uma mistura deles.
  • Se stdin ou stdout forem usados, uma string será entendida apenas como a sequência de caracteres . Se forem usados argumentos de função, a seqüência de caracteres podem precisar de ser fechado entre aspas ou símbolos equivalentes que a linguagem de programação de usos de escolha para definir strings.
  • A saída deve ser uma sequência contendo apenas os caracteres exclusivos da entrada. Portanto, não há quebras de linha extras, espaços etc. A única exceção é: se a saída for exibida no stdout, a maioria das funções de exibição adicionará um final \n(para separar a string do que virá a seguir). Portanto, um final \né aceitável no stdout .
  • Se possível, poste um link em um intérprete / compilador on - line para que outros possam experimentar seu código.

Este é o código golf , pelo que o código mais curto em bytes vence.

Alguns exemplos , assumindo stdin e stdout:

  1. String de entrada:

    Type unique chars!
    

    Cadeia de saída:

    Type uniqchars!
    
  2. String de entrada

    "I think it's dark and it looks like rain", you said
    

    String de saída

    "I think'sdarloe,yu
    
  3. String de entrada

    3.1415926535897932384626433832795
    

    String de saída

    3.14592687
    
Luis Mendo
fonte
5
Apenas para verificar: a regra no builtins significa que os objetos definidos não são permitidos?
Sp3000 4/15
@ Sp3000 Objetos definidos são permitidos. Apenas não use uma função ou método (se existir) que fornece seus elementos exclusivos. E de entrada / saída deve ser cordas, não definidos tobjects
Luis Mendo
@ Sp3000 Você acha que seria mais interessante reduzir a contagem de bytes pela metade se nenhuma função definida for usada? Ou melhor, não mudar as regras depois que o desafio for definido?
Luis Mendo
5
Acho que apenas minha resposta usa conjuntos atualmente e não me importaria se você a alterasse. No entanto, não tenho certeza se um bônus como esse mudaria muito, por exemplo, duvido que o CJam seja possível em <6 bytes sem conjuntos. Além disso, eu não tenho certeza de onde a linha entre um builtin que encontra elementos únicos, e construir um conjunto de um número de elementos ...
SP3000
11
@ Sp3000 Sim, é uma borda borrada. Eu não tinha previsto funções definidas. Acho que vou deixar o desafio como é agora
Luis Mendo

Respostas:

13

GolfScript, 2 bytes

.&

ou alternativamente:

.|

Eu publiquei isso há um tempo atrás no tópico Dicas para jogar golfe no GolfScript . Ele funciona duplicando a sequência de entrada (que é colocada na pilha automaticamente pelo intérprete GolfScript e que se comporta da maioria das maneiras como uma matriz de caracteres) e, em seguida, levando consigo a interseção ( &) ou união ( |) definida . A aplicação de um operador set a uma matriz (ou sequência) reduz as duplicatas, mas preserva a ordem dos elementos.

Ilmari Karonen
fonte
23

CJam, 3 bytes

qL|

Setwise ou da entrada com uma lista vazia. As operações de conjunto CJam preservam a ordem dos elementos.

Experimente online

Sp3000
fonte
Estou assumindo que isso é válido, pois os conjuntos são permitidos, mas não tenho certeza ...
Sp3000 4/15
Muito esperto! Eu sabia que o CJam seria um dos melhores, mas não esperava apenas 3 bytes!
Luis Mendo
19

C # 6, 18 + 67 = 85 bytes

Requer esta usingdeclaração:

using System.Linq;

O método real:

string U(string s)=>string.Concat(s.Where((x,i)=>s.IndexOf(x)==i));

Esse método salva alguns caracteres definindo a função como um lambda , suportado no C # 6. É assim que ficaria no C # pré-6 (mas não destruído):

string Unique(string input)
{
    return string.Concat(input.Where((x, i) => input.IndexOf(x) == i));
}

Como funciona: chamo o Wheremétodo na string com um lambda com dois argumentos: xrepresentando o elemento atual, irepresentando o índice desse elemento. IndexOfsempre retorna o primeiro índice do caractere passado para ele; portanto, se inão for igual ao primeiro x, é um caractere duplicado e não deve ser incluído.

ProgramFOX
fonte
3
Sinceramente, eu não esperava que o C # fosse tão curto. Excelente trabalho!
Alex A.
Uhm. Eu acho que você deve enviar um programa completo (com static void Mainetc.).
Timwi #
3
@ Timwi Este desafio declara "Funções ou programas são permitidos".
hvd 5/10
O C # permite uma abordagem mais curta, também usando o LINQ. Eu postei uma resposta concorrente. :)
hvd
@hvd Nice one! 1
ProgramFOX
14

Retina , 14 bytes

+`((.).*)\2
$1

Cada linha deve ter seu próprio arquivo separado, ou você pode usar o -ssinalizador para ler um arquivo.

Para explicar, usaremos esta versão mais longa, porém mais simples:

+`(.)(.*)\1
$1$2

A primeira linha é o regex com o qual corresponder ( +`é a cadeia de configuração que continua em execução até que todas as substituições tenham sido feitas). A regex procura um caractere (vamos chamá-lo de C), seguido por zero ou mais caracteres arbitrários, seguido por C. Os parênteses indicam grupos de captura, portanto substituímos a correspondência por C ( $1) e os caracteres entre ( $2), removendo a duplicata de C.

Por exemplo, se a sequência de entrada fosse unique, a primeira execução corresponderia uniqucom ue niqcomo $1e $2, respectivamente. Em seguida, substituiria a substring correspondente na entrada original por uniq, dando uniqe.

NinjaBearMonkey
fonte
3
Eu estava procurando por um regex para fazer isso; Eu não sabia que era tão curto! +1
ETHproductions
13

Perl, 21 (20 bytes + -p)

s/./!$h{$&}++&&$&/eg

Uso:

perl -pe 's/./!$h{$&}++&&$&/eg' <<< 'Type unique chars!'
Type uniqchars!
Dom Hastings
fonte
11
Você poderia economizar 1 byte negando $h{$&}e usando uma lógica E em vez de um operador ternário:s/./!$h{$&}++&&$&/eg
kos
@ kos se você tivesse me perguntado, eu teria dito que eu 100% tentei isso e acabei com 1s na saída, mas não! Obrigado, atualizando!
Dom Hastings
11
Voto a favor já :) Acho que você tentou s/./$h{$&}++||$&/eg(eu me apaixonei por isso também no começo). Vergonha, porque isso teria sido outro byte salvo.
kos
11

Macarrão 0.0.2 , 233 bytes

set i read set f "" print map index i k v return label k set x _ set _ slice " " length index f e 1 1 set f concat f wrap x return label e set _ slice " " add _ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return
  • criar linguagem "anti-golfe": verifique
  • jogue de qualquer maneira: verifique

Este é um programa completo, que insere STDIN e sai em STDOUT.

Versão embrulhada, para valor estético:

set i read set f "" print map index i k v return label k set x _ set _ slice "
" length index f e 1 1 set f concat f wrap x return label e set _ slice " " add
_ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return

E uma versão fortemente "comentada" e não-golfada (não há comentários em Macarrão, então eu apenas uso literais de string nua):

set input read                  "read line from STDIN, store in 'input' var"
set found ""                    "we need this for 'keep' below"
print map index input keep val  "find indeces to 'keep', map to values, print"
return

label keep
    "we're trying to determine which indeces in the string to keep. the special
     '_' variable is the current element in question, and it's also the value
     to be 'returned' (if the '_' variable is '0' or empty array after this
     label returns, the index of the element is *not* included in the output
     array; otherwise, it is"
    set x _ set _ slice
        " "
        length index found exists
        1
        1
    "now we're using 'index' again to determine whether our '_' value exists in
     the 'found' array, which is the list of letters already found. then we
     have to apply a boolean NOT, because we only want to keep values that do
     NOT exist in the 'found' array. we can 'invert' a boolean stored as an
     integer number 'b' (hence, 'length') with 'slice(' ', b, 1, 1)'--this is
     equivalent to ' '[0:1], i.e. a single-character string which is truthy, if
     'b' was falsy; otherwise, it results in an empty string if 'b' was truthy,
     which is falsy"
    set found concat found wrap x  "add the letter to the 'found' array"
return

label exists
    set _ slice
        " "
        add _ multiply -1 x
        1
        1
    "commentary on how this works: since 0 is falsy and every other number is
     truthy, we can simply subtract two values to determine whether they are
     *un*equal. then we apply a boolean NOT with the method described above"
return

label val
    set _ unwrap slice input _ add 1 _ 1  "basically 'input[_]'"
return

(Este é o primeiro programa de macarrão real (que realmente faz alguma coisa)! \ O /)

Maçaneta da porta
fonte
5
• dê ao idioma um nome engraçado e apropriado: check
Luis Mendo
11

JavaScript ES7, 37 33 25 bytes

Abordagem bastante simples usando o operador de espalhamento de compreensão ES6 Sete ES7 Array :

s=>[...new Set(s)].join``

22 bytes a menos que a indexOfabordagem. Trabalhou em vários casos de teste.

azz
fonte
Os espaços em torno forexpressão 's não são necessários e você pode torná-lo função anônima como algumas outras soluções fiz: s=>[for(c of Set(s))c].join``. (Pálido atualização: não 100% de certeza, mas a newpalavra-chave parece também desnecessário.)
manatwork
Não tinha certeza das regras com funções anon, e boa captura do espaço.
Zz5
Código transpilado sem newresultado Uncaught TypeError: Constructor Set requires 'new'no Google Chrome.
azz
Por favor, desculpe minha ignorância, mas em que momento isso filtra valores únicos? Parece que apenas converte uma string em um conjunto em uma matriz e junta os valores que resultam na string original novamente.
Patrick Roberts
@PatrickRoberts é a conversão para um conjunto. Um conjunto, por definição, não tem dupluicates
edc65
8

C # 6 - 18 + 46 = 64

using System.Linq;

e depois

string f(string s)=>string.Concat(s.Union(s));

O Enumerable.Unionmétodo de extensão especifica que os elementos são retornados na ordem original:

Quando o objeto retornado por esse método é enumerado, o Union enumera primeiro e segundo nessa ordem e gera cada elemento que ainda não foi produzido.

Operações definidas que não se destinam especificamente a encontrar valores únicos parecem ser permitidas a julgar pelas outras respostas.

hvd
fonte
Legal, eu estava pensando, string u(string s)=>String.Join("",s.Distinct());mas isso é um pouco mais.
Germi #
@germi Obrigado. Já houve uma resposta usando Distinct(), mas ela foi excluída porque Distinct()não é permitida neste desafio, pois é um método especificamente destinado a encontrar valores únicos.
hvd
Ah certo ... negligenciei esse bit;) #
315
É s => string.Concat(s.Union(s))válido? Esse seria o delegado passado para a Func<string, string>como argumento.
usar o seguinte código
@TylerStandishMan Se isso for válido, eu esperaria que mais pessoas fizessem uso dele, e eu nunca vi isso antes, então acho que não. Mas talvez deva ser válido - isso parece algo que vale a pena conferir no Meta, se você estiver interessado.
hvd 28/09
7

JavaScript ES6, 47 bytes

f=s=>s.replace(/./g,(e,i)=>s.indexOf(e)<i?'':e)

O teste abaixo funciona em todos os navegadores.

f=function(s){
  return s.replace(/./g,function(e,i){
    return s.indexOf(e)<i?'':e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="Type unique chars!" /><button id="run">Run</button><br />
<pre id="output"></pre>

NinjaBearMonkey
fonte
O que a <i?'':epeça faz?
DanTheMan
11
É um operador ternário. Se a primeira instância de um caractere eestiver antes do índice atual i, ele retornará uma string vazia, livrando-se assim do caractere. Se essa for a primeira instância, ela simplesmente retorna ee nenhuma alteração é feita.
NinjaBearMonkey
7

MATLAB, 23

 @(n)union(n,n,'stable')

Faz a "união de conjunto" da string de entrada consigo mesma, usando o método 'stable' que não classifica e depois imprime.

Isso funciona porque unionretorna apenas valores não duplicados após a mesclagem. Então, basicamente, se você unionusar a string em si mesma, ela produzirá uma string como Type unique chars!Type unique chars!e depois removerá todas as duplicatas sem classificação.

Não há necessidade de unique:)

Tom Carpenter
fonte
uniquenão é permitido, desculpe! Está na definição de desafio
Luis Mendo
Perdeu isso, não importa.
Tom Carpenter
Seguindo a resposta do Sp3000, posso sugerir setdiffcom a 'stable'opção?
Luis Mendo
11
Agradável! E sim, você pode remover dispporque, em seguida, você tem uma função que retorna uma string, o que é permitido
Luis Mendo
11
Você também pode usar intersectcom 'stable'para obter o mesmo efeito. Eu ia escrever isso, mas, dada essa resposta, não é mais original, lol.
rayryeng - Restabelece Monica 4/15
7

> <> , 16 bytes

i:0(?;:::1g?!o1p

> <> não tem strings, então usamos o codebox. Devido à natureza toroidal de> <>, o seguinte é executado em um loop:

i         Read a char
:0(?;     Halt if EOF
:::       Push three copies of the char
1g        Get the value at (char, 1), which is 0 by default
?!o       Print the char if the value was nonzero
1p        Set the value at (char, 1) to char

Observe que isso usa o fato de que a entrada contém apenas ASCII imprimível, pois isso não funcionaria se o ASCII 0 estivesse presente.

Sp3000
fonte
11
.......isto é brilhante. Eu gostaria de ter pensado nisso. Vou incluir uma versão Befunge disso na minha resposta, mas não como a principal. EDIT: Pensando bem, isso não funcionaria porque o Befunge não possui um espaço de código infinito. Dangit!
El'endia Starman
@ El'endiaStarman Eu acho que a resposta feixe também faz a mesma coisa, por isso, infelizmente, eu não posso dizer que foi o primeiro: P
SP3000
Ahh, sim, acho que você está certo. Sua explicação é mais clara.
El'endia Starman
5

Elemento , 22 19 18 bytes

_'{"(3:~'![2:`];'}

Exemplo de entrada / saída: hello world->helo wrd

Isso funciona simplesmente processando a string, um caractere de cada vez, e acompanhando quais já foram vistas antes.

_'{"(3:~'![2:`];'}
_                        input line
 '                       use as conditional
  {              }       WHILE loop
   "                     retrieve string back from control (c-) stack
    (                    split to get the first character of (remaining) string
     3:                  a total of three copies of that character
       ~                 retrieve character's hash value
        '                put on c-stack
         !               negate, gives true if undef/empty string
          [   ]          FOR loop
           2:`           duplicate and output
               ;         store character into itself
                '        put remaining string on c-stack as looping condition
PhiNotPi
fonte
5

Python 2, 42 bytes

Usa algumas funções anônimas e reduce.

lambda s:reduce(lambda x,y:x+y[y in x:],s)

Experimente online

mbomb007
fonte
4

Python 3, 44

r=''
for c in input():r+=c[c in r:]
print(r)

Constrói a string de saída rcaractere por caractere, incluindo o caractere cda entrada apenas se ainda não o tivermos visto.

O Python 2 seria 47, perdendo 4 caracteres raw_inpute economizando 1 em não precisar de parers print.

xnor
fonte
O consenso agora parece ser o de que você pode usar inputno Python 2, para tornar o seu byte mais curto.
mbomb007
4

APL, 3

∊∪/

Isso aplica a união (∪) entre cada elemento do vetor, obtendo uma iteração que tem o efeito de remover duplicatas.

Teste em tryapl.org

Antigo:

~⍨\

Isso usa ~ (com argumentos invertidos, usando ⍨) aplicado entre cada elemento do argumento. O resultado é que, para cada elemento, se já estiver na lista, ele será apagado.

Moris Zucca
fonte
Nitpicking: "E entrada / saída devem ser strings", diz Luis. "Unione reduzir" retorna uma matriz aninhada, não uma string. O :-)
lstefano 28/06
Você está certo, adicionando um ∊ no começo para corrigir.
Moris Zucca
3

Perl, 54 27 bytes

map{$h{$_}||=print}<>=~/./g
123456789012345678901234567

Teste:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$
Steve
fonte
11
print exists($h{$_})?"":$_$h{$_}||print
manatwork
O SO inseriu um unicode → char lá, tornando-o quebrado?
Steve
11
o uso de um modificador de instrução pouparia alguns bytes, juntamente com a sugestão de @ manatwork, $h{$_}||=printe o uso <>=~/./gtambém ajudaria a economizar um pouco mais!
Dom Hastings
11
Não, eu o inseri, com o significado de "alterar para".
Manatwork
11
Mudar para maptambém melhoraria a economia: map{$h{$_}||=print}<>=~/./g
manatwork
3

PHP, 72 bytes 84 bytes

<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));

Usa os caracteres como chaves para uma matriz associativa e depois imprime as chaves. A ordem dos elementos da matriz é sempre a ordem de inserção.

Obrigado Ismael Miguel pela str_splitsugestão.

Fabian Schmengler
fonte
11
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));Mais curto e faz o mesmo.
Ismael Miguel
Encontrado um ciclo mais curto: while($c=$argv[1][$i++*1]). Isso substitui o todo foreach. Tudo o resto é igual
Ismael Miguel
Eu tentei algo semelhante primeiro, mas me abstive disso, porque ele iria parar em um personagem que obriga a "falso", ie "0". Tente "abc0def" como entrada.
Fabian Schmengler
Você está certo sobre isso. Surly, há uma solução alternativa para isso que não custa mais de 2 bytes.
Ismael Miguel
3

Pitão, 7 bytes

soxzN{z

Pseudo-código:

z = entrada

soma do índice de ordenação em z de N sobre o conjunto de z.

isaacg
fonte
3

Julia, 45 42 bytes

s->(N="";[i∈N?N:N=join([N,i])for i=s];N)

Versão antiga:

s->(N={};for i=s i∈N||(N=[N,i])end;join(N))

O código constrói a nova sequência de caracteres, acrescentando novos caracteres a ela e, em seguida, joinos reúne em uma sequência adequada no final. A nova versão salva alguns caracteres iterando através da compreensão do array. Também salva um byte usando em ?:vez de ||(pois elimina a necessidade de colchetes em torno da atribuição).

Solução alternativa, 45 bytes, usando recursão e regex:

f=s->s!=(s=replace(s,r"(.).*\K\1",""))?f(s):s

Julia, 17 bytes

(Versão alternativa)

s->join(union(s))

Isso usa unionbasicamente como um substituto para unique- eu não considero a resposta "real", pois interpreto "não use unique" para significar "não use uma única função interna que tenha o efeito de retornar o único elementos ".

Glen O
fonte
Eu tive uma ideia semelhante, mas não foi tão concisa. Bom trabalho!
Alex A.
3

Java, 78 bytes

String f(char[]s){String t="";for(char c:s)t+=t.contains(c+"")?"":c;return t;}

Um loop simples ao verificar a saída quanto a caracteres já presentes. Aceita entrada como a char[].

Geobits
fonte
3

C, 96 bytes

#include<stdio.h> 
int c,a[128];main(){while((c=getchar())-'\n')if(!a[c])a[c]=1,putchar(c);}

Isso usa uma matriz de números inteiros, indexados pelo número de caracteres ASCII. Os caracteres são impressos apenas se esse local na matriz estiver definido como FALSE. Depois que cada novo caractere é encontrado, o local na matriz é definido como TRUE. Isso pega uma linha de texto da entrada padrão, terminada por uma nova linha. Ele ignora caracteres não ASCII.


Ungolfed:

#include<stdio.h>
#include<stdbool.h>

int main(void)
{
  int i, c;
  int ascii[128];
  for (i = 0; i < 128; ++i) {
    ascii[i] = false;
  }
  while ((c = getchar()) != '\n') {
    if (ascii[c] == false) {
      ascii[c] = true;
      putchar(c);
    }
  }
  puts("\n");
  return(0);
}
musaritmia
fonte
3

C - 58

Agradecemos a @hvd e @AShelly por salvar um monte de personagens. Sugeriram várias maneiras de torná-lo muito mais curto que o original:

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

// original version - requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}

Como você pode ver, a modificação no local parece ser a mais curta (até agora!) O programa de teste é compilado sem avisos usando gcc test.c

#include <stdlib.h> // calloc
#include <string.h> // strchr
#include <stdio.h>  // puts, putchar

// 000000111111111122222222223333333333444444444455555555556666666666
// 456789012345678901234567890123456789012345678901234567890123456789

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

/* original version - commented out because it requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}
*/

// The test program:
int main(int argc,char*argv[]){
  char *r=calloc(strlen(argv[1]),1); // make a variable to store the result
  g(argv[1],r);                      // call the function
  puts(r);                           // print the result

  h(argv[1]);                        // call the function which prints result
  puts("");                          // print a newline

  i(argv[1]);                        // call the function (modifies in place)
  puts(argv[1]);                     // print the result
}

Obrigado por toda a ajuda. Agradeço todos os conselhos dados para encurtar tanto!

Jerry Jeremiah
fonte
Bem, desde que o seu código já não é válido C, apenas aceito por compiladores C branda: você pode declarar rcomo int(e omitir a int) para salvar alguns bytes: f(s,r)char*s;{...}. Mas limita seu código a plataformas onde char*é do mesmo tamanho inte, é claro, onde os compiladores são tão brandos quanto o seu e o meu.
hvd
@hvd Isso é mau! Eu estava disposto a usar como padrão o valor de retorno porque não o uso. Mas isso é um pouco mais desonesto do que eu gostaria de ser. Acho que prefiro torná-lo compatível, em vez de ir tão longe! Obrigado por trazer de volta ao lado da luz.
Jerry Jeremiah
Você pode salvar um caractere substituindo if(x)yporx?y:0
ugoren
Aqui está uma função de 60 de char que escreve na saída padrão em vez de um parâmetro de matriz: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly
Você pode copiar incondicionalmente *qe incrementar apenas qse o personagem aparecer mais cedo, permitindo um pouco mais de compilação: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}(Observe que strchr(r,*s++)<qsempre está bem definido, não há UB lá, porque strchrnão pode retornar NULLnesta versão.) Exceto pelo tipo de retorno, é ainda mais curto que a versão do @ AShelly.
hvd
2

Ruby, 30 24 caracteres

(Código de 23 caracteres + opção de linha de comando de 1 caractere.)

gsub(/./){$`[$&]?"":$&}

Exemplo de execução:

bash-4.3$ ruby -pe 'gsub(/./){$`[$&]?"":$&}' <<< 'hello world'
helo wrd
homem a trabalhar
fonte
2

CJam, 9

Lq{1$-+}/

Isso não converte uma string em um conjunto, mas executa um tipo de diferença de conjunto para determinar se um caractere é encontrado em uma string. Experimente online

Explicação:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  1$    copy the previous string
  -     subtract from the character (set difference),
         resulting in the character or empty string
  +     append the result to the string

Outra versão, 13 bytes:

Lq{_2$#)!*+}/

Isso não faz nada relacionado a conjuntos. Experimente online

Explicação:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  _     duplicate the character
  2$    copy the previous string
  #)    find the index of the character in the string and increment it
  !     negate, resulting in 0 if the character was in the string and 1 if not
  *     repeat the character that many times
  +     append the result to the string
aditsu
fonte
2

TI-BASIC, 49 bytes

Input Str1
"sub(Str1,X,1→Y₁
Y₁(1
For(X,2,length(Str1
If not(inString(Ans,Y₁
Ans+Y₁
End
Ans

As variáveis ​​da equação raramente são úteis, pois levam 5 bytes para armazenar, mas são Y₁úteis aqui como o Xcaractere da string, economizando 3 bytes. Como não podemos adicionar cadeias de caracteres vazias no TI-BASIC, iniciamos a cadeia com o primeiro caractere de Str1, depois percorremos o restante da cadeia, adicionando todos os caracteres que ainda não foram encontrados.

prgmQ
?Why no empty st
rings? Because T
I...
Why noemptysrig?Bcau.
lirtosiast
fonte
2

Matlab, 46 bytes

Ele usa uma função anônima, com argumentos de função como entrada e saída:

@(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

(Não consegui fazer isso funcionar em um intérprete on-line do Octave.)

Exemplo de uso:

>> @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')
ans = 
    @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

>> ans('Type unique chars!')
ans =
Type uniqchars!
Luis Mendo
fonte
essa teria sido minha ideia também :) - você não precisa do ,1with any, btw.
Jonas
@Jonas Thanks! Alrhough é difícil ver através dessa confusão de parênteses, o 1é para triu (eu preciso remover a diagonal), não paraany
Luis Mendo
2

Befunge -93, 124 bytes

v
<v1p02-1
0_v#`g00: <0_@#+1::~p
 1>:1+10p2+0g-!#v_v
g `#v_10g0^       >:10g00
 ^0g 00$        <
 ^  >:,00g1+:00p1+:1+01-\0p

Teste-o neste intérprete online .


Isso foi mais difícil do que eu esperava. Vou postar uma explicação mais completa amanhã, se alguém quiser, mas aqui está uma visão geral do que meu código faz.

  • Os caracteres únicos vistos até agora são armazenados na primeira linha, começando 2,0e se estendendo para a direita. Isso é verificado para ver se o caractere atual é uma duplicata.
  • O número de caracteres únicos vistos até agora é armazenado 0,0e o contador de loop de verificação de duplicação é armazenado 1,0.
  • Quando um caractere exclusivo é visto, ele é armazenado na primeira linha, impresso e o contador de entrada 0,0é incrementado.
  • Para evitar problemas com a leitura nos espaços presentes (ASCII 32), coloquei o caractere correspondente a -1 (realmente, 65536) no próximo slot para o próximo caractere exclusivo.
El'endia Starman
fonte
2

PHP, 56. 54

// 56 bytes
<?=join('',array_flip(array_flip(str_split($argv[1]))));

// 54 bytes
<?=join(!$a='array_flip',$a($a(str_split($argv[1]))));

Afastar a resposta do @ fschmengler usando a array_flipversão duas vezes segunda usa o método variável e depende da conversão da string para true, negando-a como false, e depois convertendo-a de volta para a string vazia no primeiro argumento para salvar alguns bytes no segundo. Barato!

Niet, o Escuro Absol
fonte
2

Haskell , 29 bytes

Linha única aninhada e sem nome de variável:

foldr(\x->(x:).filter(x/=))[]

Mesma contagem, salva em uma função nomeada fcomo uma declaração de nível superior:

f(x:t)=x:f[y|y<-t,x/=y];f_=[]

Observe que há uma otimização pouco trapaceira que eu não fiz no espírito de gentileza: tecnicamente ainda é permitido pelas regras deste desafio usar uma codificação de entrada e saída diferente para uma string. Ao representar qualquer um stringpor sua codificação parcialmente aplicada da Igreja \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](com o outro lado da bijeção fornecida pela função ($ (:))), isso diminui para ($ \x->(x:).filter(x/=))apenas 24 caracteres.

Evitei postar a resposta de 24 caracteres como minha resposta oficial, porque a solução acima poderia ser tentada no intérprete acima como se foldr(\x->(x:).filter(x/=))[]"Type unique chars!"a solução golfed fosse escrita:

($ \x->(x:).filter(x/=))$ foldr (\x fn f->f x (fn f)) (const []) "Type unique chars!"

como uma abreviação para a declaração literal que seria a mais insana:

($ \x->(x:).filter(x/=))$ \f->f 'T'.($f)$ \f->f 'y'.($f)$ \f->f 'p'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'u'.($f)$ \f->f 'n'.($f)$ \f->f 'i'.($f)$ \f->f 'q'.($f)$ \f->f 'u'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'c'.($f)$ \f->f 'h'.($f)$ \f->f 'a'.($f)$ \f->f 'r'.($f)$ \f->f 's'.($f)$ \f->f '!'.($f)$ const[]

Mas é uma versão perfeitamente válida da estrutura de dados representada como funções puras. (Claro, você também pode usar \f -> foldr f [] "Type unique chars!", mas isso é presumivelmente ilegítimo, pois usa listas para realmente armazenar os dados; portanto, sua parte foldr deve ser presumivelmente composta na função "resposta", com mais de 24 caracteres.)

CR Drost
fonte