Ketikkan uniqchars!

41

Diberikan string yang terdiri dari karakter ASCII yang dapat dicetak , menghasilkan output yang terdiri dari karakter uniknya dalam urutan asli . Dengan kata lain, outputnya sama dengan input kecuali bahwa char dihapus jika sudah muncul sebelumnya.

Tidak ada built-in untuk menemukan elemen unik dalam array yang dapat digunakan (misalnya, MATLAB memiliki uniquefungsi yang melakukan itu). Idenya adalah melakukannya secara manual.

Keterangan lebih lanjut:

  • Entah fungsi atau program yang diperbolehkan.
  • Input dan output dapat berupa argumen fungsi, stdin / stdout (bahkan untuk fungsi), atau gabungan dari keduanya.
  • Jika stdin atau stdout digunakan, string dipahami hanya sebagai urutan karakter . Jika argumen fungsi digunakan, urutan karakter mungkin perlu dilampirkan dalam tanda kutip atau simbol yang setara yang digunakan bahasa pemrograman pilihan untuk mendefinisikan string.
  • Keluaran harus berupa string yang hanya berisi karakter unik dari input. Jadi tidak ada linebreak tambahan, spasi dll. Satu-satunya pengecualian adalah: jika output ditampilkan di stdout, sebagian besar fungsi tampilan menambahkan trailing \n(untuk memisahkan string dari apa yang akan terjadi selanjutnya). Jadi satu trailing \ndapat diterima di stdout .
  • Jika memungkinkan, poskan tautan ke juru bahasa / kompiler online sehingga orang lain dapat mencoba kode Anda.

Ini adalah kode golf , jadi kode terpendek dalam byte menang.

Beberapa contoh , dengan asumsi stdin dan stdout:

  1. String input:

    Type unique chars!
    

    String output:

    Type uniqchars!
    
  2. Input string

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

    Output string

    "I think'sdarloe,yu
    
  3. Input string

    3.1415926535897932384626433832795
    

    Output string

    3.14592687
    
Luis Mendo
sumber
5
Hanya untuk mengecek: Apakah aturan no builtin berarti bahwa set objek tidak diizinkan?
Sp3000
@ Sp3000 Set objek diizinkan. Hanya saja, jangan gunakan fungsi atau metode (jika ada) yang memberi Anda elemen uniknya. Dan input / output harus berupa string, bukan set tobjects
Luis Mendo
@ Sp3000 Apakah Anda pikir akan membuatnya lebih menarik untuk mengurangi jumlah byte hingga setengahnya jika tidak ada fungsi set yang digunakan? Atau lebih baik tidak mengubah aturan begitu tantangan telah ditetapkan?
Luis Mendo
5
Saya pikir hanya jawaban saya yang menggunakan set saat ini, dan saya tidak keberatan jika Anda mengubahnya. Namun, saya tidak begitu yakin bonus seperti itu akan banyak berubah, misalnya saya ragu CJam akan bisa dilakukan dalam <6 byte tanpa set. Juga, saya tidak yakin di mana garis berada di antara builtin yang menemukan elemen unik, dan membangun satu set dari sejumlah elemen ...
Sp3000
1
@ Sp3000 Ya, ini perbatasan buram. Saya belum mengantisipasi fungsi yang ditetapkan. Saya pikir saya akan meninggalkan tantangan seperti sekarang
Luis Mendo

Jawaban:

13

GolfScript, 2 byte

.&

atau, sebagai alternatif:

.|

Saya memposting ini beberapa waktu lalu di Tips untuk bermain golf di utas GolfScript . Ini bekerja dengan menduplikasi string input (yang diletakkan di tumpukan secara otomatis oleh juru GolfScript, dan yang berperilaku dalam banyak cara seperti array karakter) dan kemudian mengambil persimpangan set ( &) atau union ( |) dengan sendirinya. Menerapkan operator yang ditetapkan ke array (atau string) runtuh setiap duplikat, tetapi mempertahankan urutan elemen.

Ilmari Karonen
sumber
23

CJam, 3 byte

qL|

Setwise atau input dengan daftar kosong. CJam mengatur operasi mempertahankan urutan elemen.

Cobalah online

Sp3000
sumber
Saya berasumsi ini valid karena set diizinkan, tetapi saya tidak yakin ...
Sp3000
Sangat pintar! Saya tahu CJam akan menjadi salah satu yang terbaik, tetapi saya tidak berharap hanya 3 byte!
Luis Mendo
19

C # 6, 18 + 67 = 85 byte

Membutuhkan usingpernyataan ini :

using System.Linq;

Metode aktual:

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

Metode ini menyimpan beberapa karakter dengan mendefinisikan fungsi sebagai lambda , yang didukung di C # 6. Ini adalah bagaimana itu akan terlihat di C # pra-6 (tetapi tidak disunat):

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

Cara kerjanya: Saya memanggil Wheremetode pada string dengan lambda dengan dua argumen: xmewakili elemen saat ini, imewakili indeks elemen tersebut. IndexOfselalu mengembalikan indeks pertama dari arang yang dilewatinya, jadi jika itidak sama dengan indeks pertama x, itu adalah duplikat char dan tidak boleh dimasukkan.

ProgramFOX
sumber
3
Jujur saya tidak akan mengharapkan C # menjadi sesingkat ini. Kerja bagus!
Alex A.
Uhm. Saya pikir Anda harus mengirimkan program lengkap (dengan static void Maindll.).
Timwi
3
@Timwi Tantangan ini menyatakan "Fungsi atau program diizinkan."
hvd
C # memungkinkan untuk pendekatan yang lebih pendek, juga menggunakan LINQ. Saya telah mengirim jawaban yang bersaing. :)
hvd
@Hvd Bagus sekali! +1
ProgramFOX
14

Retina , 14 byte

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

Setiap baris harus memiliki file terpisah sendiri, atau Anda dapat menggunakan -sflag untuk membaca dari satu file.

Untuk menjelaskannya, kami akan menggunakan versi yang lebih lama namun lebih sederhana ini:

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

Baris pertama adalah regex yang cocok dengan ( +`adalah string konfigurasi yang terus berjalan sampai semua penggantian dilakukan). Regex mencari karakter (kami akan menyebutnya C), diikuti oleh nol atau lebih karakter arbitrer, diikuti oleh C. Tanda kurung menunjukkan grup penangkap, jadi kami mengganti kecocokan dengan C ( $1) dan karakter di antara ( $2), menghapus duplikat C.

Misalnya, jika string input adalah unique, jalankan pertama akan cocok , masing-masing uniqudengan udan niqsebagai $1dan $2. Kemudian akan menggantikan substring yang cocok di input asli dengan uniq, memberi uniqe.

NinjaBearMonkey
sumber
3
Saya mencari regex untuk melakukan ini; Saya tidak menyadari bahwa itu sangat singkat! +1
ETHproduk
13

Perl, 21 (20 byte + -p)

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

Pemakaian:

perl -pe 's/./!$h{$&}++&&$&/eg' <<< 'Type unique chars!'
Type uniqchars!
Dom Hastings
sumber
1
Anda dapat menyimpan negating 1 byte $h{$&}dan menggunakan logika DAN bukannya operator ternary:s/./!$h{$&}++&&$&/eg
kos
@kos jika Anda bertanya kepada saya, saya akan memberitahu Anda bahwa saya 100% mencoba ini dan berakhir dengan 1s di output, tetapi tidak! Terima kasih, pembaruan!
Dom Hastings
1
Sudah ter-upgrade :) Saya pikir Anda sudah mencoba s/./$h{$&}++||$&/eg(saya jatuh cinta juga pada awalnya). Malu karena itu akan menjadi byte lain yang disimpan.
kos
11

Macaroni 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
  • buat bahasa "anti-golfing": centang
  • toh golf saja: periksa

Ini adalah program lengkap, yang input dari STDIN dan output pada STDOUT.

Versi yang dibungkus, untuk nilai estetika:

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

Dan versi "komentar" dan ungolfed (tidak ada komentar di Macaroni, jadi saya hanya menggunakan bare string literal):

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

(Ini adalah program Macaroni nyata pertama (yang sebenarnya melakukan sesuatu)! \ O /)

Gagang pintu
sumber
5
• beri bahasa yang lucu dan nama yang sesuai: cek
Luis Mendo
11

JavaScript ES7, 37 33 25 byte

Pendekatan yang cukup sederhana menggunakan ES6 Setdan ES7 comprehensions Array penyebaran Operator:

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

22 byte kurang dari indexOfpendekatan. Bekerja pada beberapa kasus uji.

azz
sumber
Ruang di sekitar forekspresi 's tidak diperlukan dan Anda bisa membuatnya fungsi anonim karena beberapa solusi lain lakukan: s=>[for(c of Set(s))c].join``. (Pembaruan pucat: tidak 100% yakin, tetapi newkata kunci tampaknya juga tidak perlu.)
manatwork
Tidak yakin aturan dengan fungsi langsung, dan tangkapan yang bagus di ruang.
azz
Kode yang ditranspansi tanpa newmenghasilkan Uncaught TypeError: Constructor Set requires 'new'Google Chrome.
azz
Maafkan ketidaktahuan saya, tetapi pada titik mana filter ini nilai unik? Sepertinya itu hanya mengkonversi string ke set ke array kemudian bergabung dengan nilai yang menghasilkan string asli lagi.
Patrick Roberts
@ PatrickRoberts itu adalah konversi ke set. Satu set menurut definisi tidak memiliki dupluicate
edc65
8

C # 6 - 18 + 46 = 64

using System.Linq;

lalu

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

The Enumerable.Unionekstensi metode menetapkan bahwa unsur-unsur dikembalikan dalam urutan asli:

Ketika objek yang dikembalikan oleh metode ini disebutkan, Union menyebutkan pertama dan kedua dalam urutan itu dan menghasilkan setiap elemen yang belum dihasilkan.

Mengatur operasi yang tidak secara khusus dimaksudkan untuk menemukan nilai-nilai unik tampaknya diizinkan menilai dengan jawaban lain.

hvd
sumber
Bagus, saya sedang memikirkan string u(string s)=>String.Join("",s.Distinct());tapi itu sedikit lebih lama.
germi
@ germi Terima kasih. Sudah ada jawaban yang digunakan Distinct(), tetapi dihapus karena Distinct()tidak diizinkan dalam tantangan ini, karena metode ini khusus dimaksudkan untuk menemukan nilai unik.
hvd
Ah benar ... mengabaikan bagian itu;)
germi
Apakah s => string.Concat(s.Union(s))valid Itu akan menjadi delegasi yang diteruskan ke Func<string, string>sebagai argumen.
Tyler StandishMan
@ TylerStandishMan Jika itu valid, saya akan berharap lebih banyak orang memanfaatkannya, dan saya belum pernah melihatnya, jadi saya tidak berpikir begitu. Tapi mungkin itu harus valid - ini sepertinya sesuatu yang layak diperiksa di Meta jika Anda tertarik.
hvd
7

JavaScript ES6, 47 byte

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

Tes di bawah ini berfungsi pada semua 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>

NinjaBearMonkey
sumber
Apa yang dilakukan <i?'':ebagian itu?
DanTheMan
1
Ini adalah operator ternary. Jika instance pertama dari sebuah karakter eadalah sebelum indeks saat ini i, itu mengembalikan string kosong, sehingga menghilangkan karakter. Jika itu adalah contoh pertama, itu hanya mengembalikan edan tidak ada perubahan yang dilakukan.
NinjaBearMonkey
7

MATLAB, 23

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

Apakah "set union" dari string input dengan sendirinya, menggunakan metode 'stable' yang tidak mengurutkan, dan kemudian mencetak.

Ini berfungsi karena unionhanya mengembalikan nilai-nilai yang tidak duplikat setelah penggabungan. Jadi intinya jika Anda unionmenggunakan string itu sendiri, pertama-tama menghasilkan string seperti Type unique chars!Type unique chars!, dan kemudian menghapus semua duplikat tanpa menyortir.

Tidak perlu unique:)

Tom Carpenter
sumber
uniquetidak diizinkan, maaf! Ada dalam definisi tantangan
Luis Mendo
Kehilangan itu, tidak apa-apa.
Tom Carpenter
Mengikuti jawaban Sp3000, bolehkah saya menyarankan setdiffdengan 'stable'opsi?
Luis Mendo
1
Bagus! Dan ya, Anda dapat menghapus dispkarena Anda memiliki fungsi yang mengembalikan string, yang diizinkan
Luis Mendo
1
Anda juga dapat menggunakan intersectdengan 'stable'untuk mencapai efek yang sama juga. Saya akan menulis itu, tetapi diberi jawaban ini, itu bukan lagi lol asli.
rayryeng
7

> <> , 16 byte

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

> <> tidak memiliki string, jadi kami menggunakan kotak kode. Karena sifat toroidal> <>, yang berikut berjalan dalam satu lingkaran:

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

Perhatikan bahwa ini menggunakan fakta bahwa input hanya berisi ASCII yang dapat dicetak, karena ini tidak akan berfungsi jika ASCII 0 hadir.

Sp3000
sumber
1
....... ini brilian. Saya berharap saya telah memikirkan hal ini. Saya akan memasukkan versi Befunge ini dalam jawaban saya, tetapi tidak sebagai yang utama. EDIT: Setelah dipikir-pikir, ini tidak akan berhasil karena Befunge tidak memiliki ruang kode yang tak terbatas. Dangit!
El'endia Starman
@ El'endiaStarman Saya pikir jawaban Beam juga melakukan hal yang sama, jadi sayangnya saya tidak bisa mengatakan saya yang pertama: P
Sp3000
Ahh, ya, aku pikir kamu benar. Penjelasan Anda lebih jelas.
El'endia Starman
5

Elemen , 22 19 18 byte

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

Contoh input / output: hello world->helo wrd

Ini berfungsi dengan hanya memproses karakter string satu per satu dan melacak yang mana yang telah dilihat sebelumnya.

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

Python 2, 42 byte

Menggunakan beberapa fungsi anonim dan reduce.

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

Cobalah online

mbomb007
sumber
4

Python 3, 44

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

Membangun rkarakter string keluaran berdasarkan karakter, termasuk karakter cdari input hanya jika kita belum melihatnya.

Python 2 akan menjadi 47, kehilangan 4 karakter dengan raw_inputdan menghemat 1 karena tidak membutuhkan pengupas print.

Tidak
sumber
Konsensus sekarang tampaknya adalah bahwa Anda dapat menggunakan inputPython 2, sehingga Anda dapat membuat byte Anda lebih pendek.
mbomb007
4

APL, 3

∊∪/

Ini berlaku penyatuan (∪) antara setiap elemen vektor, mendapatkan iterasi yang memiliki efek menghilangkan duplikat.

Cobalah di tryapl.org

Yang lama:

~⍨\

Ini menggunakan ~ (dengan argumen terbalik, menggunakan ⍨) yang diterapkan antara setiap elemen argumen. Hasilnya adalah bahwa untuk setiap elemen, jika sudah ada dalam daftar, itu akan terhapus.

Moris Zucca
sumber
Nitpicking: "Dan input / output harus berupa string" kata Luis. "Mengurangi pengurangan" mengembalikan array bersarang, bukan string. O :-)
lstefano
Anda benar, menambahkan ∊ di awal untuk memperbaiki.
Moris Zucca
3

Perl, 54 27 byte

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

Uji:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$
steve
sumber
1
print exists($h{$_})?"":$_$h{$_}||print
manatwork
Sudahkah SO memasukkan unicode → char di sana sehingga membuatnya rusak?
steve
1
menggunakan pengubah pernyataan akan menghemat beberapa byte, bersama dengan saran $h{$_}||=printdan penggunaan @ manatwork <>=~/./gakan membantu menghemat beberapa byte juga!
Dom Hastings
1
Tidak, saya menyisipkannya, dengan arti "ubah menjadi".
manatwork
1
Mengubah ke mapjuga akan meningkatkan penghematan: 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));

Menggunakan karakter sebagai kunci untuk array asosiatif, lalu mencetak kunci. Urutan elemen array selalu urutan penyisipan.

Terima kasih Ismael Miguel untuk str_splitsarannya.

Fabian Schmengler
sumber
1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));Lebih pendek dan melakukan hal yang sama.
Ismael Miguel
Ditemukan loop pendek: while($c=$argv[1][$i++*1]). Ini menggantikan keseluruhan foreach. Segala sesuatu yang lain adalah sama
Ismael Miguel
Saya mencoba sesuatu yang serupa pertama tetapi menahan diri karena itu akan berhenti pada karakter yang memaksa untuk "salah", yaitu "0". Coba "abc0def" sebagai input.
Fabian Schmengler
Anda benar tentang itu. Tentunya ada solusi untuk itu yang tidak memerlukan biaya lebih dari 2 byte.
Ismael Miguel
3

Pyth, 7 byte

soxzN{z

Kodesemu:

z = input

jumlah order-by index dalam z dari N lebih dari set z.

isaacg
sumber
3

Julia, 45 42 byte

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

Versi lama:

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

Kode membangun string baru dengan menambahkan karakter baru ke dalamnya, lalu joinmemasangkannya ke string yang tepat di akhir. Versi baru menyimpan beberapa karakter dengan mengulangi melalui pemahaman array. Juga menyimpan byte dengan menggunakan ?:daripada ||(karena menghilangkan kebutuhan untuk tanda kurung di sekitar tugas).

Solusi alternatif, 45 byte, menggunakan rekursi dan regex:

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

Julia, 17 byte

(Versi alternatif)

s->join(union(s))

Ini unionpada dasarnya digunakan sebagai pengganti unique- saya tidak menganggap ini sebagai jawaban "nyata", karena saya menafsirkan "tidak menggunakan unique" berarti "tidak menggunakan fungsi built-in tunggal yang memiliki efek mengembalikan yang unik elemen ".

Glen O
sumber
Saya memiliki ide yang sama tetapi tidak sesingkat itu. Kerja bagus!
Alex A.
3

Java, 78 byte

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

Simpul sederhana sambil memeriksa output untuk karakter yang sudah ada. Menerima input sebagai a char[].

Geobit
sumber
3

C, 96 byte

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

Ini menggunakan array bilangan bulat, diindeks oleh nomor karakter ASCII. Karakter hanya dicetak jika tempat dalam array diatur ke FALSE. Setelah setiap karakter baru ditemukan, tempat dalam array diatur ke TRUE. Ini mengambil satu baris teks dari input standar, diakhiri oleh baris baru. Itu mengabaikan karakter non-ASCII.


Tidak Disatukan:

#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);
}
musarithmia
sumber
3

C - 58

Terima kasih kepada @hvd dan @AShelly karena telah menyimpan banyak karakter. Ada beberapa cara yang disarankan agar lebih pendek dari aslinya:

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

Seperti yang Anda lihat memodifikasi di tempat tampaknya menjadi yang terpendek (sejauh ini!) Program uji mengkompilasi tanpa peringatan menggunakan 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
}

Terima kasih atas semua bantuannya. Saya menghargai semua saran yang diberikan untuk mempersingkat!

Jerry Jeremiah
sumber
Nah, karena kode Anda sudah tidak C valid, hanya diterima oleh C compiler lunak: Anda dapat mendeklarasikan rsebagai int(dan menghilangkan int) untuk menyimpan beberapa byte: f(s,r)char*s;{...}. Tapi itu membatasi kode Anda untuk platform di mana char*ukurannya sama int, dan tentu saja di mana kompiler sama ringannya dengan Anda dan milik saya.
hvd
@ DVD Itu jahat! Saya bersedia untuk default nilai kembali karena saya tidak menggunakannya. Tapi itu sedikit lebih cerdik dari yang saya inginkan. Saya pikir saya lebih suka membuatnya patuh daripada melangkah sejauh itu! Terima kasih telah membawa kembali ke sisi terang.
Jerry Jeremiah
Anda dapat menyimpan satu char dengan menggantinya if(x)ydenganx?y:0
ugoren
Inilah fungsi 60 char yang menulis ke stdout alih-alih parameter array: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly
Anda dapat menyalin tanpa syarat ke dalam *q, dan hanya menambah qjika karakter muncul sebelumnya, memungkinkan isian sedikit lebih bersama-sama: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}(Perhatikan bahwa strchr(r,*s++)<qselalu didefinisikan dengan baik, tidak ada UB di sana, karena strchrtidak dapat kembali NULLdalam versi ini.) Kecuali untuk tipe kembali, bahkan lebih pendek dari versi @ AShelly.
hvd
2

Ruby, 30 24 karakter

(23 karakter kode + 1 opsi baris perintah karakter.)

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

Contoh dijalankan:

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

CJam, 9

Lq{1$-+}/

Ini tidak mengonversi string ke set, tetapi melakukan semacam perbedaan set untuk menentukan apakah karakter ditemukan dalam string. Cobalah online

Penjelasan:

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

Versi lain, 13 byte:

Lq{_2$#)!*+}/

Ini tidak melakukan apa pun yang terkait dengan set. Cobalah online

Penjelasan:

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
sumber
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

Variabel persamaan jarang berguna karena mereka mengambil 5 byte untuk disimpan, tetapi Y₁berguna di sini sebagai Xkarakter th dari string, menghemat 3 byte. Karena kita tidak dapat menambahkan string kosong dalam TI-BASIC, kita memulai string dengan karakter pertama dari Str1, kemudian mengulangi seluruh string, menambahkan semua karakter yang belum ditemukan.

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

Matlab, 46 byte

Menggunakan fungsi anonim, dengan argumen fungsi sebagai input dan output:

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

(Saya tidak bisa mengaktifkan ini dalam juru bahasa online Octave.)

Contoh penggunaan:

>> @(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
sumber
itu juga ide saya :) - Anda tidak perlu ,1dengan any, btw.
Jonas
@Jonas, Terima kasih! Meskipun sulit untuk melihat melalui kurung kurung itu, 1itu untuk triu (saya harus menghapus diagonal), bukan untukany
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

Uji dalam juru bahasa online ini .


Ini lebih sulit daripada yang saya harapkan. Saya akan memposting penjelasan yang lebih lengkap besok jika ada yang menginginkan saya, tapi di sini adalah ikhtisar dari apa yang kode saya lakukan.

  • Karakter unik yang terlihat sejauh ini disimpan di baris pertama, mulai dari 2,0 dan meluas ke kanan. Ini dicentang untuk melihat apakah karakter saat ini adalah duplikat.
  • Jumlah karakter unik yang terlihat sejauh ini disimpan di 0,0dan penghitung loop cek-duplikat disimpan di 1,0.
  • Ketika karakter unik terlihat, itu disimpan di baris pertama, dicetak, dan penghitung di 0,0bertambah.
  • Untuk menghindari masalah dengan membaca di spasi sekarang (ASCII 32), saya meletakkan karakter yang sesuai dengan -1 (benar-benar, 65536) di slot berikutnya untuk karakter unik berikutnya.
El'endia Starman
sumber
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]))));

Menggeser jawaban @ fschmengler menggunakan array_flipversi dua kali - kedua menggunakan metode variabel dan bergantung pada casting string ke true, meniadakannya ke false, kemudian melemparkannya kembali ke string kosong dalam argumen pertama untuk menyimpan beberapa byte di yang kedua. Murah!

Niet the Dark Absol
sumber
2

Haskell , 29 byte

Satu baris yang nyaman, tanpa nama variabel:

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

Jumlah yang sama, disimpan ke fungsi yang disebut fsebagai deklarasi tingkat atas:

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

Perhatikan bahwa ada optimasi yang sedikit curang yang belum saya lakukan dalam semangat kebaikan: secara teknis masih diizinkan oleh aturan tantangan ini untuk menggunakan input dan output pengkodean yang berbeda untuk string. Dengan mewakili siapa saja stringdengan pengkodean Gereja yang diterapkan sebagian \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](dengan sisi lain dari penimbunan yang disediakan oleh fungsi ($ (:))) ini akan diturunkan menjadi ($ \x->(x:).filter(x/=)), hanya 24 karakter.

Saya menghindari memposting tanggapan 24 karakter sebagai jawaban resmi saya karena solusi di atas dapat dicoba pada juru bahasa di atas foldr(\x->(x:).filter(x/=))[]"Type unique chars!"sementara solusi golf akan ditulis sebagai gantinya:

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

sebagai singkatan untuk deklarasi literal yang akan menjadi lebih gila:

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

Tetapi ini adalah versi yang benar-benar valid dari struktur data yang direpresentasikan sebagai fungsi murni. (Tentu saja, Anda dapat menggunakan \f -> foldr f [] "Type unique chars!"juga, tetapi itu mungkin tidak sah karena menggunakan daftar untuk benar-benar menyimpan data, sehingga bagian foldernya kemudian dapat dikomposisikan ke dalam fungsi "jawaban", yang mengarah ke lebih dari 24 karakter.)

CR Drost
sumber