Digita uniqchars!


41

Data una stringa composta da caratteri ASCII stampabili , produce un output costituito dai suoi caratteri univoci nell'ordine originale . In altre parole, l'output è uguale all'input, tranne per il fatto che un carattere viene rimosso se è apparso in precedenza.

Non è possibile utilizzare elementi integrati per trovare elementi univoci in un array (ad esempio MATLAB ha una uniquefunzione che lo fa). L'idea è di farlo manualmente.

Maggiori dettagli:

  • O funzioni o programmi sono ammessi.
  • L'input e l'output possono essere sotto forma di argomenti di funzione, stdin / stdout (anche per le funzioni) o un mix di questi.
  • Se si utilizza stdin o stdout, una stringa viene intesa come solo la sequenza di caratteri . Se vengono utilizzati argomenti di funzione, potrebbe essere necessario racchiudere la sequenza di caratteri tra virgolette o simboli equivalenti che il linguaggio di programmazione scelto utilizza per definire le stringhe.
  • L'output dovrebbe essere una stringa contenente solo i caratteri univoci dell'input. Quindi nessuna interruzione di riga aggiuntiva, spazi ecc. L'unica eccezione è: se l'output viene visualizzato in stdout, la maggior parte delle funzioni di visualizzazione aggiunge un finale \n(per separare la stringa da ciò che verrà dopo). Quindi un trailing \nè accettabile in stdout .
  • Se possibile, pubblica un link a un interprete / compilatore online in modo che altri possano provare il tuo codice.

Questo è il codice golf , quindi vince il codice più breve in byte.

Alcuni esempi , supponendo stdin e stdout:

  1. Stringa di input:

    Type unique chars!
    

    Stringa di uscita:

    Type uniqchars!
    
  2. Stringa di input

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

    Stringa di output

    "I think'sdarloe,yu
    
  3. Stringa di input

    3.1415926535897932384626433832795
    

    Stringa di output

    3.14592687
    

5
Solo per ricontrollare: la regola no builtins significa che gli oggetti impostati non sono ammessi?
Sp3000,

@ Sp3000 Gli oggetti impostati sono consentiti. Basta non usare una funzione o un metodo (se esiste) che ti dia i suoi elementi unici. E input / output dovrebbero essere stringhe, non impostare i tablini
Luis Mendo,

@ Sp3000 Pensi che sarebbe più interessante ridurre della metà il numero di byte se non si utilizzano funzioni impostate? O meglio non cambiare le regole una volta che la sfida è stata impostata?
Luis Mendo,

5
Penso che al momento solo la mia risposta usi i set e non mi dispiacerebbe se la cambiassi. Tuttavia, non sono sicuro che un bonus del genere cambierebbe molto, ad esempio dubito che CJam sarebbe realizzabile in <6 byte senza set. Inoltre, non sono sicuro di dove sia la linea tra un builtin che trova elementi unici e la costruzione di un set da un numero di elementi ...
Sp3000

1
@ Sp3000 Sì, è un bordo sfocato. Non avevo previsto le funzioni impostate. Penso che lascerò la sfida così com'è ora
Luis Mendo,

Risposte:


13

GolfScript, 2 byte

.&

o, in alternativa:

.|

L'ho pubblicato qualche tempo fa nei suggerimenti per giocare a golf nel thread GolfScript . Funziona duplicando la stringa di input (che viene messa in pila automaticamente dall'interprete GolfScript e che si comporta in molti modi come una matrice di caratteri) e quindi prendendo la stessa intersezione ( &) o unione ( |) di essa con se stessa. L'applicazione di un operatore set a un array (o stringa) comprime i duplicati, ma mantiene l'ordine degli elementi.


23

CJam, 3 byte

qL|

Setwise o dell'input con un elenco vuoto. Le operazioni di set CJam mantengono l'ordine degli elementi.

Provalo online



Molto intelligente! Sapevo che CJam sarebbe stato uno dei migliori, ma non mi aspettavo solo 3 byte!
Luis Mendo,

19

C # 6, 18 + 67 = 85 byte

Richiede questa usingaffermazione:

using System.Linq;

Il metodo attuale:

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

Questo metodo salva alcuni caratteri definendo la funzione come lambda , che è supportata in C # 6. Ecco come apparirebbe in C # pre-6 (ma non golfizzato):

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

Come funziona: chiamo il Wheremetodo sulla stringa con un lambda con due argomenti: xrappresenta l'elemento corrente, irappresenta l'indice di quell'elemento. IndexOfrestituisce sempre il primo indice del carattere passato ad esso, quindi se inon è uguale al primo indice di x, è un carattere duplicato e non deve essere incluso.


3
Onestamente non mi sarei aspettato che C # fosse così corto. Lavoro eccellente!
Alex A.

Uhm. Penso che dovresti presentare un programma completo (con static void Mainecc.).
Timwi,

3
@Timwi Questa sfida afferma "Sono consentite funzioni o programmi".
hvd,

C # consente un approccio più breve, anche usando LINQ. Ho pubblicato una risposta in competizione. :)
hvd,

@hvd Nice one! +1
Programma FOX

14

Retina , 14 byte

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

Ogni riga dovrebbe andare nel suo file separato, oppure puoi usare il -sflag per leggere da un file.

Per spiegarlo, useremo questa versione più lunga ma più semplice:

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

La prima riga è la regex da abbinare ( +`è la stringa di configurazione che continua a funzionare fino a quando non sono state fatte tutte le sostituzioni). La regex cerca un personaggio (lo chiameremo C), seguito da zero o più caratteri arbitrari, seguito da C. Le parentesi indicano gruppi di acquisizione, quindi sostituiamo la corrispondenza con C ( $1) e i caratteri tra ( $2), rimuovere il duplicato di C.

Ad esempio, se la stringa di input fosse unique, la prima esecuzione corrisponderebbe uniqu, rispettivamente con ue niqcome $1e $2. Sostituirebbe quindi la sottostringa corrispondente nell'input originale con uniq, dare uniqe.


3
Stavo cercando una regex per farlo; Non mi ero reso conto che fosse così corto! +1
ETHproductions

13

Perl, 21 (20 byte + -p)

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

Uso:

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

1
È possibile salvare 1 byte negando $h{$&}e utilizzando una logica AND anziché un operatore ternario:s/./!$h{$&}++&&$&/eg
kos

@kos se me lo avessi chiesto, ti avrei detto che l'ho provato al 100% e ho finito con 1s nell'output, ma non è così! Grazie, aggiornamento!
Dom Hastings,

1
Già votato :) Penso che tu ci abbia provato s/./$h{$&}++||$&/eg(all'inizio mi sono innamorato anch'io ). Peccato perché sarebbe stato un altro byte salvato.
kos,

11

Maccheroni 0.0.2 , 233 byte

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
  • creare un linguaggio "anti-golf": controllare
  • golf comunque: controllare

Questo è un programma completo, che input da STDIN e output su STDOUT.

Versione confezionata, per valore estetico:

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 una versione pesantemente "commentata" e ungolf (non ci sono commenti nei maccheroni, quindi uso solo letterali a stringa nuda):

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

(Questo è il primo vero programma Macaroni (che in realtà fa qualcosa)! \ O /)


5
• dai un nome divertente e appropriato alla lingua: controlla
Luis Mendo il

11

JavaScript ES7, 37 33 25 byte

Approccio piuttosto semplice usando l' operatore di diffusione delle comprensioni ES6 Seted ES7 :

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

22 byte in meno rispetto indexOfall'approccio. Ha lavorato su una manciata di casi di test.


Gli spazi intorno forespressione 's non sono necessari e si potrebbe rendere funzione anonima come alcune altre soluzioni hanno fatto: s=>[for(c of Set(s))c].join``. (Aggiornamento pallido: non sicuro al 100%, ma la newparola chiave sembra anche non necessaria.)
manatwork

Non ero sicuro delle regole con anon funzioni, e buona cattura dello spazio.
azz,

Codice traspilato senza newrisultati Uncaught TypeError: Constructor Set requires 'new'in Google Chrome.
azz,

Scusa la mia ignoranza, ma a che punto questo filtro filtra valori unici? Sembra che converta solo una stringa in un set in un array, quindi unisce nuovamente i valori risultanti nella stringa originale.
Patrick Roberts,

@PatrickRoberts è la conversione in un set. Un set per definizione non ha duplicati
edc65

8

C # 6 - 18 + 46 = 64

using System.Linq;

e poi

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

Il Enumerable.Unionmetodo di estensione specifica che gli elementi vengono restituiti nell'ordine originale:

Quando viene elencato l'oggetto restituito con questo metodo, Union enumera il primo e il secondo in quell'ordine e produce ogni elemento che non è già stato prodotto.

Impostare operazioni che non sono specificamente destinate a trovare valori univoci sembra essere autorizzato a giudicare dalle altre risposte.


Bello, stavo pensando string u(string s)=>String.Join("",s.Distinct());ma è un po 'più lungo.
germi,

@germi Grazie. È già stata utilizzata una risposta Distinct(), ma è stata eliminata perché Distinct()non è consentita in questa sfida, in quanto è un metodo specificamente progettato per trovare valori univoci.
hvd,

Ah giusto ... trascurato quel poco;)
germi

È s => string.Concat(s.Union(s))valido? Quello sarebbe il delegato passato a Func<string, string>come argomento.
Tyler StandishMan,

@TylerStandishMan Se questo è valido, mi aspetterei che più persone lo usino e non l'ho mai visto prima, quindi non credo che lo sia. Ma forse dovrebbe essere valido - questo sembra qualcosa che vale la pena controllare su Meta se sei interessato.
hvd,

7

JavaScript ES6, 47 byte

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

Il test seguente funziona su tutti i browser.

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>


Cosa fa la <i?'':eparte?
DanTheMan,

1
È un operatore ternario. Se la prima istanza di un carattere si etrova prima dell'indice corrente i, restituisce una stringa vuota, eliminando così il carattere. Se questa è la prima istanza, ritorna semplicemente ee non vengono apportate modifiche.
NinjaBearMonkey il

7

MATLAB, 23

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

Fa il "set union" della stringa di input con se stesso, usando il metodo 'stable' che non ordina, e quindi stampa.

Questo funziona perché unionrestituisce solo valori non duplicati dopo l'unione. Quindi essenzialmente se unionla stringa è con se stessa, produce prima una stringa simile Type unique chars!Type unique chars!e quindi rimuove tutti i duplicati senza ordinamento.

Non c'è bisogno di unique:)


uniquenon permesso, scusa! È nella definizione di sfida
Luis Mendo,

Perso quello, non importa.
Tom Carpenter,

Dopo la risposta di Sp3000, posso suggerire setdiffl' 'stable'opzione?
Luis Mendo,

1
Bello! E sì, puoi rimuoverlo dispperché poi hai una funzione che restituisce una stringa, che è consentita
Luis Mendo

1
Puoi anche usare intersectcon 'stable'per ottenere lo stesso effetto. Stavo per scriverlo, ma data questa risposta, non è più originale lol.
rayryeng - Ripristina Monica il

7

> <> , 16 byte

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

> <> non ha stringhe, quindi utilizziamo la codebox. A causa della natura toroidale di> <>, le seguenti esecuzioni in un ciclo:

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

Si noti che questo utilizza il fatto che l'input contiene solo ASCII stampabile, in quanto non funzionerebbe se ASCII 0 fosse presente.


1
.......è brillante. Vorrei aver pensato a questo. Includerò una versione di Befunge nella mia risposta, ma non come principale. EDIT: A pensarci bene, questo non funzionerebbe perché Befunge non ha uno spazio di codice infinito. Dangit!
El'endia Starman,

@ El'endiaStarman Penso che anche la risposta Beam faccia la stessa cosa, quindi purtroppo non posso dire di essere stata la prima: P
Sp3000,

Ah, sì, penso che tu abbia ragione. La tua spiegazione è però più chiara.
El'endia Starman,


5

Elemento , 22 19 18 byte

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

Esempio di input / output: hello world->helo wrd

Funziona semplicemente elaborando la stringa un carattere alla volta e tenendo traccia di quelli che ha visto prima.

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

Crea la stringa di output rcarattere per carattere, incluso il carattere cdall'input solo se non l'abbiamo già visto.

Python 2 sarebbe 47, perdendo 4 caratteri con raw_inpute salvando 1 per non aver bisogno di parer print.


Il consenso ora sembra essere che puoi usare inputin Python 2, quindi puoi rendere il tuo un byte più breve.
mbomb007,

4

APL, 3

∊∪/

Questo applica l'unione (∪) tra ogni elemento del vettore, ottenendo un'iterazione che ha l'effetto di rimuovere i duplicati.

Provalo su tryapl.org

Vecchio:

~⍨\

Questo usa ~ (con argomenti invertiti, usando ⍨) applicato tra ogni elemento dell'argomento. Il risultato è che per ogni elemento, se è già nell'elenco, viene cancellato.


Nitpicking: "E input / output dovrebbero essere stringhe" afferma Luis. "Unione reduce" restituisce un array nidificato, non una stringa. O :-)
lstefano,

Hai ragione, aggiungendo un ∊ all'inizio per correggere.
Moris Zucca,

3

Perl, 54 27 byte

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

Test:

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

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

SO ha inserito un unicode → char lì rendendolo rotto?
steve

1
l'uso di un modificatore di istruzione ti farebbe risparmiare qualche byte, insieme al suggerimento di @ manatwork $h{$_}||=printe l'uso <>=~/./gdovrebbe aiutare a salvare anche qualche altro!
Dom Hastings,

1
No, l'ho inserito, con il significato di "modifica in".
Manatwork

1
Passare a mapmigliorerebbe anche il risparmio: map{$h{$_}||=print}<>=~/./g
manatwork

3

PHP, 72 byte 84 byte

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

Utilizza i caratteri come chiavi per un array associativo, quindi stampa le chiavi. L'ordine degli elementi dell'array è sempre l'ordine di inserimento.

Grazie Ismael Miguel per il str_splitsuggerimento.


1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));Più corto e fa lo stesso.
Ismael Miguel,

Trovato un ciclo più breve: while($c=$argv[1][$i++*1]). Questo sostituisce il tutto foreach. Tutto il resto è lo stesso
Ismael Miguel,

Ho provato prima qualcosa di simile ma mi sono astenuto perché si fermerebbe su un personaggio che si costringe a "falso", vale a dire "0". Prova "abc0def" come input.
Fabian Schmengler,

Hai ragione. Sicuramente c'è una soluzione alternativa che non costa più di 2 byte.
Ismael Miguel,

3

Pyth, 7 byte

soxzN{z

pseudocodice:

z = input

somma dell'indice per ordine in z di N sull'insieme di z.


3

Julia, 45 42 byte

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

Vecchia versione:

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

Il codice costruisce la nuova stringa aggiungendo nuovi caratteri su di essa, quindi joinli unisce alla stringa corretta alla fine. La nuova versione salva alcuni personaggi ripetendo la comprensione dell'array. Inoltre, salva un byte utilizzando ?:anziché anziché ||(poiché rimuove la necessità di parentesi attorno all'assegnazione).

Soluzione alternativa, 45 byte, usando ricorsione e regex:

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

Julia, 17 byte

(Versione alternativa)

s->join(union(s))

Questo utilizza unionin sostanza un sostituto per unique- non considero questa la risposta "reale", poiché interpreto "non usare unique" per indicare "non utilizzare una singola funzione integrata che ha l'effetto di restituire l'unicità elementi".


Avevo un'idea simile ma non era così concisa. Bel lavoro!
Alex A.

3

Java, 78 byte

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

Un semplice ciclo durante il controllo dell'output per i caratteri già presenti. Accetta input come a char[].


3

C, 96 byte

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

Questo utilizza una matrice di numeri interi, indicizzata dal numero di caratteri ASCII. I caratteri vengono stampati solo se quel posto nell'array è impostato su FALSE. Dopo aver trovato ogni nuovo personaggio, quel posto nell'array è impostato su TRUE. Questo prende una riga di testo dallo standard input, terminato da una nuova riga. Ignora i caratteri 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

Grazie a @hvd e @AShelly per aver salvato un sacco di personaggi. Sono stati suggeriti diversi modi per renderlo molto più breve dell'originale:

// @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;}

Come puoi vedere, la modifica in atto sembra essere la più breve (finora!) Il programma di test si compila senza avvisi 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
}

Grazie per tutto l'aiuto. Apprezzo tutti i consigli dati per abbreviare così tanto!


Ebbene, dal momento che il codice è già non è valido C, appena accettato dai compilatori C indulgente: è possibile dichiarare rcome int(e omette il int) per salvare alcuni byte: f(s,r)char*s;{...}. Ma limita il tuo codice a piattaforme con char*le stesse dimensioni inte, ovviamente, in cui i compilatori sono indulgenti come i tuoi e i miei.
hvd,

@hvd Questo è male! Ero disposto a default il valore restituito perché non lo uso. Ma è un po 'più complicato di quanto mi piacerebbe essere. Penso che preferirei renderlo conforme piuttosto che andare così lontano! Grazie per avermi riportato alla luce.
Jerry Jeremiah,

Puoi salvare un carattere sostituendolo if(x)yconx?y:0
ugoren il

Ecco una funzione di 60 caratteri che scrive su stdout invece di un parametro array: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly

Puoi copiare incondizionatamente *qe incrementare solo qse il personaggio è apparso in precedenza, consentendo di riempire un po 'di più insieme: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}(Nota che strchr(r,*s++)<qè sempre ben definito, non c'è UB lì, perché strchrnon può tornare NULLin questa versione.) Tranne il tipo restituito, è anche più breve della versione di @ AShelly.
hvd,

2

Rubino, 30 24 caratteri

(Codice di 23 caratteri + opzione della riga di comando di 1 carattere.)

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

Esecuzione di esempio:

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

2

CJam, 9

Lq{1$-+}/

Questo non converte una stringa in un set, ma esegue una sorta di differenza di set per determinare se un carattere viene trovato in una stringa. Provalo online

Spiegazione:

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

Un'altra versione, 13 byte:

Lq{_2$#)!*+}/

Questo non fa nulla in relazione ai set. Provalo online

Spiegazione:

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 byte

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

Le variabili di equazione sono raramente utili poiché richiedono 5 byte per l'archiviazione, ma Y₁è utile qui come il Xcarattere th della stringa, salvando 3 byte. Dal momento che non possiamo aggiungere stringhe vuote in TI-BASIC, iniziamo la stringa con il primo carattere di Str1, quindi passiamo attraverso il resto della stringa, aggiungendo tutti i caratteri non ancora incontrati.

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

2

Matlab, 46 byte

Utilizza una funzione anonima, con argomenti di funzione come input e output:

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

(Non sono riuscito a farlo funzionare in un interprete online di Octave.)

Esempio di utilizzo:

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

sarebbe stata anche una mia idea :) - non ti serve ,1con any, btw.
Jonas,

@Jonas Grazie! Anche se è difficile vedere attraverso quel casino di parentesi, 1è per triu (ho bisogno di rimuovere la diagonale), non perany
Luis Mendo

2

Befunge -93, 124 byte

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

Provalo in questo interprete online .


Questo è stato più difficile di quanto mi aspettassi. Pubblicherò una spiegazione più completa domani se qualcuno lo vuole, ma ecco una panoramica di ciò che fa il mio codice.

  • I personaggi unici visti finora sono memorizzati nella prima riga, a partire da 2,0e si estendono verso destra. Questo viene verificato per vedere se il personaggio attuale è un duplicato.
  • Il numero di caratteri univoci visti fino ad ora viene archiviato 0,0e viene archiviato il contatore di cicli di verifica per duplicati 1,0.
  • Quando viene visualizzato un carattere univoco, viene memorizzato nella prima riga, stampato e il contatore in 0,0entrata viene incrementato.
  • Per evitare problemi con la lettura negli spazi presenti (ASCII 32), inserisco il carattere corrispondente a -1 (davvero, 65536) nello slot successivo per il successivo personaggio unico.

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

Eliminare la risposta di @ fschmengler usando array_flipdue volte - la seconda versione utilizza il metodo variabile e si basa sul cast della stringa su true, negandola su false, quindi reinserendola sulla stringa vuota nel primo argomento per salvare un paio di byte nel secondo. Economico!


2

Haskell , 29 byte

One-liner annidabile senza nome variabile:

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

Stesso conteggio, salvato in una funzione denominata fcome dichiarazione di livello superiore:

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

Si noti che esiste un'ottimizzazione leggermente imbroglione che non ho fatto nello spirito di gentilezza: tecnicamente è ancora consentito dalle regole di questa sfida utilizzare una codifica di input e output diversa per una stringa. Rappresentando qualsiasistring con la sua codifica della Chiesa parzialmente applicata \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](con l'altro lato della biiezione fornita dalla funzione ($ (:))) questo viene ridotto a ($ \x->(x:).filter(x/=))solo 24 caratteri.

Ho evitato di pubblicare la risposta di 24 caratteri come mia ufficiale perché la soluzione sopra potrebbe essere provata sull'interprete sopra come foldr(\x->(x:).filter(x/=))[]"Type unique chars!" la soluzione golf sarebbe stata scritta:

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

come una scorciatoia per la dichiarazione letterale che sarebbe il più folle:

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

Ma è una versione perfettamente valida della struttura dei dati rappresentata come funzioni pure. (Naturalmente, puoi \f -> foldr f [] "Type unique chars!"anche usarlo , ma questo è presumibilmente illegittimo poiché utilizza gli elenchi per archiviare effettivamente i dati, quindi la sua parte foldr dovrebbe quindi presumibilmente essere composta nella funzione "risposta", portando a più di 24 caratteri.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.