Tapez uniqchars!


41

Avec une chaîne composée de caractères imprimables ASCII , produisez une sortie composée de ses caractères uniques dans l'ordre d'origine . En d'autres termes, la sortie est la même que l'entrée, sauf qu'un caractère est supprimé s'il est apparu précédemment.

Aucune fonctionnalité intégrée permettant de rechercher des éléments uniques dans un tableau ne peut être utilisée (par exemple, MATLAB a une uniquefonction qui le fait). L'idée est de le faire manuellement.

Plus de détails:

  • Les fonctions ou les programmes sont autorisés.
  • L'entrée et la sortie peuvent être sous la forme d' arguments de fonction, stdin / stdout (même pour des fonctions), ou un mélange de ceux-ci.
  • Si stdin ou stdout sont utilisés, une chaîne est comprise comme une simple séquence de caractères . Si des arguments de fonction sont utilisés, il peut être nécessaire de placer la séquence de caractères entre guillemets ou symboles équivalents utilisés par le langage de programmation choisi pour définir les chaînes.
  • La sortie doit être une chaîne contenant uniquement les caractères uniques de l'entrée. Donc, pas de sauts de ligne, d'espaces, etc. La seule exception est que si la sortie est affichée en stdout, la plupart des fonctions d'affichage ajoutent un fin \n(pour séparer la chaîne de ce qui va suivre). Donc, une fuite \nest acceptable en stdout .
  • Si possible, poster un lien vers un ligne interprète / compilateur afin que les autres peuvent essayer votre code.

C'est le code de golf , donc le code le plus court en octets gagne.

Quelques exemples , en supposant que stdin et stdout:

  1. Chaîne d'entrée:

    Type unique chars!
    

    Chaîne de sortie:

    Type uniqchars!
    
  2. Chaîne d'entrée

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

    Chaîne de sortie

    "I think'sdarloe,yu
    
  3. Chaîne d'entrée

    3.1415926535897932384626433832795
    

    Chaîne de sortie

    3.14592687
    

5
Juste pour vérifier: la règle de non-intégration signifie-t-elle que les objets définis sont interdits?
Sp3000

@ Sp3000 Les objets de set sont autorisés. N'utilisez simplement pas une fonction ou une méthode (si elle existe) qui vous donne ses éléments uniques. Et les entrées / sorties doivent être des chaînes et non des objets
Luis Mendo

@ Sp3000 Pensez-vous qu'il serait plus intéressant de réduire de moitié le nombre d'octets si aucune fonction n'est utilisée? Ou mieux ne pas changer les règles une fois que le défi a été défini?
Luis Mendo

5
Je pense que seule ma réponse utilise actuellement des ensembles, et cela ne me dérangerait pas si vous le changiez. Cependant, je ne suis pas vraiment sûr qu'un bonus comme celui-ci changerait beaucoup, par exemple, je doute que CJam soit réalisable en <6 octets sans ensembles. De plus, je ne suis pas sûr de savoir où se situe la ligne entre un élément intégré qui trouve des éléments uniques et la construction d'un ensemble à partir de plusieurs éléments ...
Sp3000

1
@ Sp3000 Oui, c'est une bordure floue. Je n'avais pas prévu les fonctions de set. Je pense que je vais laisser le défi tel qu'il est maintenant
Luis Mendo

Réponses:


13

GolfScript, 2 octets

.&

Ou bien:

.|

Je l'ai posté il y a quelque temps dans les astuces pour jouer au golf dans le fil GolfScript . Cela fonctionne en dupliquant la chaîne d'entrée (qui est automatiquement mise sur la pile par l'interpréteur GolfScript, et qui se comporte généralement comme un tableau de caractères), puis en prenant l'intersection ( &) ou l'union ( |) avec elle-même. L'application d'un opérateur de jeu à un tableau (ou une chaîne) réduit tout doublon, mais conserve l'ordre des éléments.


23

CJam, 3 octets

qL|

Setwise ou de l'entrée avec une liste vide. CJam les opérations sur les ensembles préservent l’ordre des éléments.

Essayez-le en ligne


Je suppose que cela est valable puisque les sets sont autorisés, mais je ne suis pas sûr ...
Sp3000

Très intelligent! Je savais que CJam serait l'un des meilleurs, mais je ne m'attendais pas à 3 octets!
Luis Mendo

19

C # 6, 18 + 67 = 85 octets

Nécessite cette usingdéclaration:

using System.Linq;

La méthode actuelle:

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

Cette méthode enregistre certains caractères en définissant la fonction en tant que lambda , qui est prise en charge en C # 6. Voici comment cela se présenterait en C # pré-6 (mais non golfé):

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

Comment ça marche: J'appelle la Whereméthode sur la chaîne avec un lambda avec deux arguments: xreprésentant l'élément en cours, ireprésentant l'index de cet élément. IndexOfrenvoie toujours le premier index du caractère qui lui est passé, donc si in'est pas égal au premier index de x, il s'agit d'un caractère en double et ne doit pas être inclus.


3
Honnêtement, je ne m'attendais pas à ce que C # soit aussi court. Excellent travail!
Alex A.

Uhm. Je pense que vous devriez soumettre un programme complet (avec static void Mainetc.).
Timwi

3
@Timwi Ce défi indique "Les fonctions ou les programmes sont autorisés."
hvd

C # permet une approche plus courte, en utilisant également LINQ. J'ai posté une réponse concurrente. :)
hvd

@hvd Nice one! +1
ProgramFOX du

14

Rétine , 14 octets

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

Chaque ligne doit aller dans son propre fichier séparé, ou vous pouvez utiliser l' -sindicateur pour lire à partir d'un fichier.

Pour l'expliquer, nous allons utiliser cette version plus longue mais plus simple:

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

La première ligne est la regex avec laquelle faire correspondre ( +`est la chaîne de configuration qui continue à s'exécuter jusqu'à ce que tous les remplacements aient été effectués). La regex recherche un caractère (nous l'appellerons C), suivi de zéro ou de plusieurs caractères arbitraires, suivi de C. Les parenthèses désignent les groupes capturés. Nous remplaçons donc la correspondance par C ( $1) et les caractères entre ( $2), enlever la copie de C.

Par exemple, si la chaîne d'entrée était unique, la première exécution correspondrait uniquavec, avec uet niqcomme $1et $2, respectivement. Il remplacerait alors la sous-chaîne correspondante dans l'entrée d'origine avec uniq, en donnant uniqe.


3
Je cherchais une regex pour le faire; Je n'avais pas réalisé que c'était si court! +1
ETHproductions

13

Perl, 21 (20 octets + -p)

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

Usage:

perl -pe 's/./!$h{$&}++&&$&/eg' <<< 'Type unique chars!'
Type uniqchars!

1
Vous pourriez économiser 1 octet en annulant $h{$&}et en utilisant une logique ET à la place d'un opérateur ternaire:s/./!$h{$&}++&&$&/eg
kos

@ Kos, si vous me l'aviez demandé, je vous aurais dit que je l'avais essayé à 100% et que j'avais fini avec 1s dans la sortie, mais ce n'est pas le cas! Merci, mise à jour!
Dom Hastings

1
Déjà voté :) Je pense que vous avez essayé s/./$h{$&}++||$&/eg(je suis tombé amoureux de ça aussi au début). Dommage car cela aurait été un autre octet enregistré.
kos

11

Macaroni 0.0.2 , 233 octets

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
  • créer un langage "anti-golf": check
  • le golf quand même: check

Ceci est un programme complet, qui entre à partir de STDIN et qui sort sur STDOUT.

Version enveloppée, pour la valeur esthétique:

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

Et une version fortement "commentée" et non-golfée (il n'y a pas de commentaire dans Macaroni, je n'utilise donc que des littéraux de chaîne nue):

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

(Ceci est le premier vrai programme Macaroni (qui fait quelque chose)! \ O /)


5
• donnez à la langue un nom amusant et approprié: chèque
Luis Mendo

11

JavaScript ES7, 37 33 25 octets

Approche assez simple en utilisant ES6 Setet ES7 multidisque compréhensions OPERATEUR:

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

22 octets de moins que l' indexOfapproche. Travaillé sur une poignée de cas de test.


Les espaces autour de forl'expression « ne sont pas nécessaires et vous pourriez le faire fonctionner anonyme que d'autres solutions ont: s=>[for(c of Set(s))c].join``. (Mise à jour de Pale: pas sûr à 100%, mais le newmot clé semble également inutile.)
manatwork

Je n'étais pas sûr des règles avec les fonctions anon, et une bonne prise sur l'espace.
azz

Le code transpilé sans newrésultat Uncaught TypeError: Constructor Set requires 'new'dans Google Chrome.
azz

Veuillez excuser mon ignorance, mais à quel moment cela filtre-t-il des valeurs uniques? Il semble que cela convertisse simplement une chaîne en un ensemble en un tableau, puis joint les valeurs résultant de la chaîne d'origine.
Patrick Roberts

@PatrickRoberts c'est la conversion en un ensemble. Un ensemble par définition n'a pas de doublons
edc65

8

C # 6 - 18 + 46 = 64

using System.Linq;

et alors

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

La Enumerable.Unionméthode d'extension spécifie que les éléments sont renvoyés dans l'ordre d'origine:

Lorsque l'objet renvoyé par cette méthode est énuméré, Union énumère les premier et deuxième dans cet ordre et renvoie chaque élément qui n'a pas déjà été généré.

Les opérations sur les ensembles qui ne sont pas spécifiquement destinées à rechercher des valeurs uniques semblent être autorisées à en juger par les autres réponses.


Un joli, je pensais à string u(string s)=>String.Join("",s.Distinct());mais c'est un peu plus long.
germi

@ germi Merci. Une réponse a Distinct()déjà été utilisée , mais elle a été supprimée car elle Distinct()n'est pas autorisée dans ce défi, car il s'agit d'une méthode spécifiquement conçue pour rechercher des valeurs uniques.
hvd

Ah
oui

Est s => string.Concat(s.Union(s))valide? Ce serait le délégué passé à un Func<string, string>comme argument.
Tyler StandishMan

@TylerStandishMan Si cela est valide, je m'attendrais à ce que plus de personnes l'utilisent, et je ne l'ai pas vu auparavant, alors je ne le pense pas. Mais peut-être que cela devrait être valide - cela semble être une chose à vérifier sur Meta si cela vous intéresse.
hvd

7

JavaScript ES6, 47 octets

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

Le test ci-dessous fonctionne sur tous les navigateurs.

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>


Que fait la <i?'':epartie?
DanTheMan

1
C'est un opérateur ternaire. Si la première instance d'un caractère eest antérieure à l'index actuel i, elle renvoie une chaîne vide, éliminant ainsi le caractère. S'il s'agit de la première instance, elle retourne simplement eet aucune modification n'est apportée.
NinjaBearMonkey

7

MATLAB, 23 ans

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

Est-ce que "set union" de la chaîne d'entrée avec lui-même, en utilisant la méthode 'stable' qui ne trie pas, puis imprime.

Cela fonctionne car unionrenvoie uniquement les valeurs non dupliquées après la fusion. Donc, essentiellement, si vous unionla chaîne avec elle-même, elle produit d'abord une chaîne comme Type unique chars!Type unique chars!, puis supprime tous les doublons sans trier.

Pas besoin de unique:)


uniquenon autorisé, désolé! C'est dans la définition du défi
Luis Mendo

J'ai raté ça, ça ne fait rien.
Tom Carpenter

Après la réponse de Sp3000, puis-je suggérer setdiffavec l' 'stable'option?
Luis Mendo

1
Agréable! Et oui, vous pouvez supprimer dispcar vous avez alors une fonction qui renvoie une chaîne, ce qui est autorisé
Luis Mendo

1
Vous pouvez également utiliser intersectavec 'stable'pour obtenir le même effet. J'allais écrire ça, mais vu cette réponse, ce n'est plus l'original lol.
rayryeng

7

> <> , 16 octets

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

> <> n'a pas de chaînes, nous utilisons donc la boîte à code. En raison de la nature toroïdale de> <>, les opérations suivantes tournent en boucle:

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

Notez que cela utilise le fait que l'entrée ne contient que de l'ASCII imprimable, car cela ne fonctionnerait pas si l'ASCII 0 était présent.


1
....... c'est génial. J'aurais aimé y penser. Je vais inclure une version Befunge de cela dans ma réponse, mais pas en tant que primaire. EDIT: À la réflexion, cela ne fonctionnerait pas car Befunge n’a pas d’espace de code infini. Dangit!
El'endia Starman

@ El'endiaStarman Je pense que la réponse Beam fait également la même chose, donc je ne peux malheureusement pas dire que j'étais le premier: P
Sp3000

Ahh ouais, je pense que tu as raison. Votre explication est plus claire cependant.
El'endia Starman


5

Element , 22 19 18 octets

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

Exemple d'entrée / sortie: hello world->helo wrd

Cela fonctionne simplement en traitant la chaîne un caractère à la fois et en gardant une trace de ceux qu’il a vus auparavant.

_'{"(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


4

Python 3, 44

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

Construit la chaîne de sortie rcaractère par caractère, y compris le caractère cde l'entrée uniquement si nous ne l'avons pas encore vue.

Python 2 aurait 47 ans, perdant 4 caractères avec raw_inputet en sauvegardant 1 sans avoir besoin de parers print.


Le consensus semble maintenant être que vous pouvez utiliser inputPython 2, vous pouvez donc raccourcir votre octet.
mbomb007

4

APL, 3

∊∪/

Ceci s'applique à l'union () entre chaque élément du vecteur, obtenant une itération ayant pour effet de supprimer les doublons.

Testez-le sur tryapl.org

Le vieux:

~⍨\

Ceci utilise ~ (avec les arguments inversés, en utilisant ⍨) appliqué entre chaque élément de l'argument. Le résultat est que pour chaque élément, s'il est déjà dans la liste, il est effacé.


Nitpicking: "Et les entrées / sorties devraient être des chaînes" dit Luis. "Unione réduire" renvoie un tableau imbriqué, pas une chaîne. O :-)
lstefano

Vous avez raison, ajoutez un au début pour corriger.
Moris Zucca

3

Perl, 54 à 27 octets

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

Tester:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$

1
print exists($h{$_})?"":$_$h{$_}||print
manatwork

SO a-t-il inséré un caractère → unicode le rendant cassé?
Steve

1
utiliser un modificateur de déclaration vous permettrait d'économiser quelques octets, ainsi que la suggestion de @ manatwork. L' $h{$_}||=printutilisation <>=~/./gdevrait également vous aider à économiser un peu plus!
Dom Hastings

1
Non, je l'ai inséré, avec le sens de «changer en».
manatwork

1
Passer à mapaméliorerait également l'économie: map{$h{$_}||=print}<>=~/./g
manatwork

3

PHP, 72 octets 84 octets

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

Utilise les caractères comme clés pour un tableau associatif, puis imprime les clés. L'ordre des éléments du tableau est toujours l'ordre d'insertion.

Merci Ismael Miguel pour cette str_splitsuggestion.


1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));Plus court et fait la même chose.
Ismael Miguel

Trouvé une boucle plus courte: while($c=$argv[1][$i++*1]). Cela remplace le tout foreach. Tout le reste est pareil
Ismael Miguel

J'ai essayé quelque chose de similaire en premier, mais je m'en suis abstenu, car cela arrêterait un personnage qui est forcé de devenir "faux", c'est-à-dire "0". Essayez "abc0def" comme entrée.
Fabian Schmengler

Vous avez raison à ce sujet. Il existe sûrement une solution de contournement qui ne coûte pas plus de 2 octets.
Ismael Miguel

3

Pyth, 7 octets

soxzN{z

Pseudocode:

z = entrée

somme de l'index de classement dans z sur N sur l'ensemble de z.


3

Julia, 45 42 octets

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

Ancienne version:

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

Le code construit la nouvelle chaîne en y ajoutant de nouveaux caractères, puis joinles regroupe en une chaîne appropriée à la fin. La nouvelle version enregistre certains caractères en effectuant une itération via la compréhension du tableau. Enregistre également un octet en utilisant ?:plutôt que ||(car cela supprime le besoin de crochets autour de l'affectation).

Solution alternative, 45 octets, utilisant la récursivité et regex:

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

Julia, 17 octets

(Version alternative)

s->join(union(s))

Cela unionremplace fondamentalement unique- je ne considère pas cela comme la "vraie" réponse, car j'interprète "ne pas utiliser unique" comme signifiant "n'utilise pas une seule fonction intégrée qui a pour effet de renvoyer l'unique éléments".


J'ai eu une idée similaire mais ce n'était pas aussi concis. Bon travail!
Alex A.

3

Java, 78 octets

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

Une boucle simple lors de la vérification de la sortie pour les caractères déjà présents. Accepte l’entrée en tant que char[].


3

C, 96 octets

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

Ceci utilise un tableau d'entiers, indexé par le nombre de caractères ASCII. Les caractères ne sont imprimés que si cet endroit du tableau est défini sur FALSE. Une fois que chaque nouveau caractère est trouvé, cet emplacement du tableau est défini sur TRUE. Cela prend une ligne de texte à partir de l'entrée standard, terminée par une nouvelle ligne. Il ignore les caractères non-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);
}

3

C - 58

Merci à @hvd et @AShelly pour avoir sauvegardé de nombreux personnages. Il y avait plusieurs façons de le rendre beaucoup plus court que l'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;}

Comme vous pouvez le constater, la modification en place semble être la plus courte (à ce jour!). Le programme de test compile sans avertissements à l'aide de 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
}

Merci pour votre aide. J'apprécie tous les conseils donnés pour raccourcir autant!


Eh bien, puisque votre code est déjà pas valide C, juste accepté par les compilateurs C indulgentes: vous pouvez déclarer rque int(sans indiquer int) pour enregistrer quelques octets: f(s,r)char*s;{...}. Mais cela limite votre code aux plates-formes où char*la taille est la même int, et bien sûr où les compilateurs sont aussi indulgents que les vôtres et les miens.
hvd

@hvd C'est diabolique! J'étais prêt à utiliser la valeur de retour par défaut car je ne l'utilise pas. Mais c'est un peu plus risqué que je voudrais être. Je pense que je préférerais le rendre conforme plutôt que d'aller si loin! Merci de ramener à la lumière.
Jerry Jeremiah

Vous pouvez enregistrer un caractère en le remplaçant if(x)yparx?y:0
ugoren

Voici une fonction à 60 caractères qui écrit sur stdout au lieu d'un paramètre de tableau: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly

Vous pouvez inconditionnellement copier dans *q, et seulement incrémenter qsi le personnage est apparu plus tôt, ce qui permet la farce un peu plus ensemble: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}(Notez que strchr(r,*s++)<qtoujours bien définie, il n'y a pas UB là, parce que strchrne peut pas revenir NULLdans cette version.) A l' exception du type de retour, c'est même plus court que la version de @ AShelly.
hvd

2

Ruby, 30 24 caractères

(Code de 23 caractères + option de ligne de commande de 1 caractère.)

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

Échantillon échantillon:

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

2

CJam, 9

Lq{1$-+}/

Cela ne convertit pas une chaîne en un jeu, mais une sorte de différence pour déterminer si un caractère est trouvé dans une chaîne. Essayez-le en ligne

Explication:

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

Une autre version, 13 octets:

Lq{_2$#)!*+}/

Cela ne fait rien lié aux ensembles. Essayez-le en ligne

Explication:

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

2

TI-BASIC, 49 octets

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

Les variables d'équation sont rarement utiles, car elles nécessitent 5 octets à stocker, mais elles s'avèrent utiles Y₁ici en tant que Xcaractère de la chaîne, ce qui permet d'économiser 3 octets. Comme nous ne pouvons pas ajouter de chaînes vides dans TI-BASIC, nous commençons la chaîne par le premier caractère de Str1, puis nous parcourons le reste de la chaîne en ajoutant tous les caractères non encore rencontrés.

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

2

Matlab, 46 octets

Il utilise une fonction anonyme, avec des arguments de fonction en entrée et en sortie:

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

(Je ne pouvais pas faire fonctionner cela avec un interprète en ligne Octave.)

Exemple d'utilisation:

>> @(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!

cela aurait aussi été mon idée :) - vous n’avez pas besoin ,1de any, avec .
Jonas

@ Jonas Merci! Bien qu'il soit difficile de voir à travers ce fouillis de parenthèses, 1c'est pour triu (je dois enlever la diagonale), pas pourany
Luis Mendo

2

Befunge -93, 124 octets

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

Testez-le dans cet interprète en ligne .


C'était plus difficile que prévu. Je publierai une explication plus détaillée demain si quelqu'un le souhaite, mais voici un aperçu de ce que fait mon code.

  • Les caractères uniques vus jusqu’à présent sont stockés sur la première ligne, en partant de 2,0la droite et en s’étendant à droite. Ceci est vérifié pour voir si le caractère actuel est un doublon.
  • Le nombre de caractères uniques vus jusqu’à présent est stocké dans 0,0et le compteur de boucles de recherche de doublons est stocké 1,0.
  • Lorsqu'un caractère unique est vu, il est stocké sur la première ligne, imprimé et le compteur 0,0entré est incrémenté.
  • Pour éviter les problèmes de lecture dans les espaces présents (ASCII 32), je mets le caractère correspondant à -1 (en réalité, 65536) dans l’emplacement suivant pour le prochain caractère unique.

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]))));

Évinçant @ de fschmengler réponse en utilisant array_flipdeux fois - deuxième version utilise la méthode variable et repose sur la coulée de la chaîne à true, annihilant à faux, puis le jeter de nouveau à la chaîne vide dans le premier argument pour sauver un couple d'octets dans le second. Pas cher!


2

Haskell , 29 octets

Une doublure emboîtable sans nom de variable:

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

Même compte, enregistré dans une fonction nommée fdéclaration de niveau supérieur:

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

Notez qu’il existe une optimisation légèrement trompeuse que je n’ai pas faite dans un esprit de gentillesse: techniquement, les règles de ce défi autorisent toujours l’utilisation d’un codage d’entrée et de sortie différent pour une chaîne. En représentant any stringpar son codage Church partiellement appliqué \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](avec l’autre côté de la bijection fourni par la fonction ($ (:))) ($ \x->(x:).filter(x/=)), on ne voit que 24 caractères.

J'ai évité d'afficher la réponse de 24 caractères comme étant la réponse officielle, car la solution ci-dessus pourrait être testée sur l'interprète ci-dessus, alors foldr(\x->(x:).filter(x/=))[]"Type unique chars!"que la solution avec golf serait écrite à la place:

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

comme un raccourci pour la déclaration littérale qui serait le plus aliéné:

($ \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[]

Mais c'est une version parfaitement valide de la structure de données représentée sous forme de fonctions pures. (Bien sûr, vous pouvez \f -> foldr f [] "Type unique chars!"aussi utiliser , mais cela est probablement illégitime, car il utilise des listes pour stocker les données. Par conséquent, sa partie repliée devrait alors être composée dans la fonction "réponse", ce qui donne plus de 24 caractères.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.