Uniqchars yazın!


41

Yazdırılabilir ASCII karakterlerinden oluşan bir dize verildiğinde , orijinal karakterdeki benzersiz karakterlerinden oluşan bir çıktı üretir . Başka bir deyişle, çıktı daha önce göründüğü takdirde bir karakterin çıkarılması dışında girdiyle aynıdır.

Bir dizideki benzersiz elemanları bulmak için hiçbir yapı kullanılamaz (örneğin, MATLAB'ın bunu yapan bir uniqueişlevi vardır). Fikir manuel olarak yapmaktır.

Daha fazla detay:

  • Ya fonksiyonlara ya da programlara izin verilir.
  • Giriş ve çıkış, fonksiyon argümanları, stdin / stdout (fonksiyonlar için bile) veya bunların bir karışımı şeklinde olabilir.
  • Stdin veya stdout kullanılırsa, bir karakter dizisi sadece karakter dizisi olarak anlaşılır . Fonksiyon argümanları kullanılırsa, karakter dizisi gerekebilir kapalı tırnak işaretleri veya eşdeğer sembolleri dizeleri tanımlamak için seçim kullanımların programlama dilinde söyledi.
  • Çıktı , girişin yalnızca benzersiz karakterlerini içeren bir dize olmalıdır . Hiçbir ekstra satır aralıklarında Yani, boşluklar vb tek istisnası: çıktı stdout'ta görüntülenen edilirse, en görüntülendiği fonksiyonları bir sondaki eklemek \n(sonraki gelecek ne dize ayırmak için). Yani bir iz \nstdout içinde kabul edilebilir .
  • Mümkünse, başkalarının kodunuzu deneyebilmesi için bir çevrimiçi tercümana / derleyiciye bağlantı gönderin .

Bu kod golf , bayt cinsinden en kısa kod kazanır.

Stdin ve stdout varsayarak bazı örnekler :

  1. Giriş dizesi:

    Type unique chars!
    

    Çıkış dizesi:

    Type uniqchars!
    
  2. Giriş dize

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

    Çıkış dize

    "I think'sdarloe,yu
    
  3. Giriş dize

    3.1415926535897932384626433832795
    

    Çıkış dize

    3.14592687
    

5
Sadece kontrol etmek için: Yerleşik olmayanlar kuralı, ayarlanan nesnelere izin verilmediği anlamına mı geliyor?
Sp3000,

@ Sp3000 Set nesnelerine izin verilir. Size benzersiz öğelerini veren bir işlev veya yöntem (varsa) kullanmayın. Girdi / çıktı dizeler olmalı, hedefler belirlenmemelidir
Luis Mendo

@ Sp3000 Herhangi bir ayar işlevi kullanılmazsa, bayt sayısını yarıya indirmeyi daha ilginç hale getireceğini düşünüyor musunuz? Veya zorluk belirlendikten sonra kuralları değiştirmemek daha mı iyi?
Luis Mendo,

5
Bence şu anda yalnızca cevabım kümeler kullanıyor ve değiştirirseniz aldırmam. Ancak, bunun gibi bir bonusun çok fazla değişeceğinden emin değilim, örneğin CJam'ın setsiz <6 byte'da yapılabileceğinden şüpheliyim. Ayrıca, çizginin benzersiz elementleri bulan bir yapının arasında olduğundan ve birkaç elementten bir set oluşturduğundan emin değilim ...
Sp3000

1
@ Sp3000 Evet, bulanık bir sınır. Set fonksiyonları beklemiyordum. Sanırım şimdi olduğu gibi mücadeleyi bırakacağım
Luis Mendo

Yanıtlar:


13

GolfScript, 2 bayt

.&

Veya alternatif olarak:

.|

Bunu bir süre önce GolfScript iş parçacığındaki Golf için İpuçları bölümünde yayınladım . Giriş dizesini çoğaltarak (bu, GolfScript yorumlayıcısı tarafından otomatik olarak yığına yerleştirilen ve bir karakter dizisi gibi birçok şekilde davranan) ve ardından ayarlanan kesişimi ( &) veya |onunla birliğini ( ) alarak çalışır. Bir dizi işlecini bir diziye (veya dizeye) uygulamak, yinelemeleri daraltır, ancak öğelerin sırasını korur.


23

CJam, 3 bayt

qL|

Setwise veya giriş boş bir liste ile CJam ayar işlemleri eleman sırasını korur.

Çevrimiçi deneyin


Bunun setlere izin verildiğinden geçerli olduğunu kabul ediyorum, ancak emin değilim ...
Sp3000

Çok zeki! CJam'ın en iyilerden biri olacağını biliyordum ama sadece 3 bayt beklemiyordum!
Luis Mendo

19

C # 6, 18 + 67 = 85 bayt

Bu usingifadeyi gerektirir :

using System.Linq;

Gerçek yöntem:

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

Bu yöntem , işlevi , C # 6'da desteklenen bir lambda olarak tanımlayarak bazı karakterleri kurtarır.

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

Nasıl çalışır: Ben dize üzerindeki Whereyöntemi iki argüman içeren bir lambda ile çağırırım : xo anki elemanı itemsil eder, o elemanın indeksini temsil eder. IndexOfher zaman kendisine iletilen karakterin ilk dizinini döndürür, bu nedenle iilk dizinine eşit değilse , xyinelenen bir karakterdir ve dahil edilmemelidir.


3
Gerçekten C # bu kadar kısa olmasını beklemem. Mükemmel iş!
Alex A.

Uhm. Bence tam bir program sunmalısınız ( static void Mainvb. İle).
Timwi

3
@Timwi Bu zorluk "ya fonksiyonlara ya da programlara izin verilir."
hvd

C #, LINQ kullanarak da daha kısa bir yaklaşıma izin verir. Rekabetçi bir cevap yolladım. :)
hvd

@ hvd Güzel olanı! +1
ProgramFOX

14

Retina , 14 bayt

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

Her satır kendi ayrı bir dosyaya girmelidir veya -sbayrakla bir dosyayı okumak için kullanabilirsiniz .

Bunu açıklamak için, bunu daha uzun ama daha basit olan versiyonda kullanacağız:

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

İlk satır, eşleştirilecek regex'tir ( +`tüm değiştirmeler yapılıncaya kadar çalışmaya devam eden yapılandırma dizesidir). Regex bir karakter arar (bunu C olarak adlandırırız), ardından sıfır veya daha fazla rasgele karakter, ardından C takip eder. Parantezler, yakalama gruplarını gösterir, bu nedenle eşleşmeyi C ( $1) ve ( $2) arasındaki karakterlerle değiştiririz. C. kopyasının kaldırılması

Giriş dizesi Söz gelimi, uniqueilk çalıştırma eşleşir uniquile, uve niqolarak $1ve $2sırasıyla. Daha sonra orijinal girişteki Eşleşen alt yerini alacak uniqvererek uniqe.


3
Bunu yapmak için bir regex arıyordum; Çok kısa olduğunu bilmiyordum! +1
ETHProductions

13

Perl, 21 (20 bayt + -p)

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

Kullanımı:

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

1
$h{$&}Üçlü bir operatör yerine olumsuz ve mantıksal bir AND kullanarak 1 bayttan tasarruf edebilirsiniz :s/./!$h{$&}++&&$&/eg
kos

Bana sorarsan kos, sana% 100 bunu denediğimi ve 1çıktıda sonuçlandığımı söylemiştim, ama yapmadı! Teşekkürler, güncelleniyor!
Dom Hastings

1
Zaten oylandı :) Denedim sanırım s/./$h{$&}++||$&/eg(ilk başta ben de bunun için düştüm). Utanç, çünkü bu başka bir kaydedilmiş byte olurdu.
kos

11

Makarna 0.0.2 , 233 bayt

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
  • "anti-golf" dilini yarat: kontrol et
  • Yine de golf: kontrol

Bu, STDIN'den giriş yapan ve STDOUT'dan çıkış yapan tam bir programdır.

Sarılmış versiyon, estetik değer için:

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

Ve ağır bir şekilde "yorumladı" ve asılsız bir versiyon (Macaroni'de hiç yorum yok, bu yüzden sadece salt string literals kullanıyorum):

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

(Bu ilk gerçek Macaroni programıdır (aslında bir şey yapar)! \ O /)


5
• dile komik ve uygun bir isim verin: kontrol edin
Luis Mendo

11

JavaScript ES7, 37 33 25 bayt

ES6 Setve ES7 Array anlamalarının yaygınlaştırılması operatörünü kullanan oldukça basit bir yaklaşım :

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

indexOfYaklaşımdan 22 bayt daha az . Bir avuç test vakası üzerinde çalıştı.


Etrafında boşluklar forbireyin ifadesi gerekli değildir ve bazı diğer çözümler yaptığı gibi anonim işlev bunu yapabilir: s=>[for(c of Set(s))c].join``. (Soluk güncelleme:% 100 emin değil, ancak newanahtar kelime de gereksiz görünüyor.)
manatwork

Anon işlevli kurallardan emin değildim ve uzayda iyi yakalamalar.
azz

Google Chrome'da newsonuçlanmayan aktarılan kod Uncaught TypeError: Constructor Set requires 'new'.
azz

Lütfen cehaletimi affedersiniz ama bu noktada hangi değerler benzersizdir? Sadece bir dizgiyi diziye çevirir, sonra dizgeye geri dönen değerleri tekrar ekler.
Patrick Roberts

@PatrickRoberts bu kümeye dönüşüm. Tanım kümesine göre yineleme yok
edc65

8

C # 6 - 18 + 46 = 64

using System.Linq;

ve sonra

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

Enumerable.UnionElementler orijinal düzende döndürülür uzatma yöntemi belirtir:

Bu yöntemin döndürdüğü nesne numaralandırıldığında, Birlik bu sırayla birinci ve ikinci numaralandırır ve daha önce elde edilmemiş her elemanı verir.

Özel olarak benzersiz değerler bulması amaçlanmayan işlemleri, diğer cevaplar tarafından değerlendirilmesine izin veriliyor gibi görünmektedir.


Güzel, düşündüm string u(string s)=>String.Join("",s.Distinct());ama biraz daha uzun.
germi

@germi Teşekkürler. Distinct()Zaten kullanarak bir cevap oldu , ancak silindi çünkü Distinct()bu zorlukla kabul edilmedi , çünkü benzersiz değerler bulmaya yönelik bir yöntem.
hvd

Ah doğru ... o bit gözardı;)
germi

s => string.Concat(s.Union(s))geçerli? Delegenin Func<string, string>bir argüman olarak kabul edileceği bu olurdu .
Tyler StandishMan

@TylerStandishMan Eğer bu geçerliyse, daha fazla insanın bunu kullanmasını beklerdim ve daha önce görmedim, bu yüzden sanmıyorum. Ama belki de geçerli olmalı - eğer ilgileniyorsanız Meta'ya bakmaya değer bir şey gibi görünüyor.
hvd

7

JavaScript ES6, 47 bayt

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

Aşağıdaki test tüm tarayıcılarda çalışır.

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>


<i?'':eParça ne yapar ?
DanTheMan,

1
Bu bir üçlü operatör. Bir karakterin ilk örneği egeçerli dizinden önce ise iboş bir dize döndürür, böylece karakterden kurtulursunuz. İlk örnek buysa, basitçe geri döner eve değişiklik yapılmaz.
NinjaBearMonkey 7:15

7

MATLAB, 23

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

Girilen dizgenin "set union" ını, dizilemeyen ve daha sonra yazdıran 'stabil' yöntemi kullanarak yapar.

Bunun nedeni unionbirleştirme işleminden sonra yalnızca yinelenmeyen değerleri döndürmesidir. Bu nedenle, esasen uniondizgiyi kendiniz kullanırsanız , ilk önce bunun gibi bir dize üretir Type unique chars!Type unique chars!ve ardından tüm kopyaları sıralamadan kaldırır.

Gerek yok unique:)


uniqueizin yok, üzgünüm! Bu meydan okuma tanımında
Luis Mendo

Bunu kaçırdım, boşver.
Tom Carpenter,

Sp3000'in cevabını takiben setdiff, 'stable'seçeneği ile önerebilir miyim ?
Luis Mendo

1
Güzel! Ve evet, kaldırabilirsiniz dispçünkü o zaman izin verilen bir dizgeyi döndüren bir işleve sahipsiniz
Luis Mendo

1
Ayrıca kullanabilirsiniz intersectile 'stable'çok aynı etkiyi elde etmek için. Bunu yazacaktım, ama bu cevabı verdiğimde, artık orijinal lol değil.
rayryeng - Monica, 4:15

7

> <> , 16 bayt

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

> <> dizeleri yok, bu yüzden kod kutusunu kullanıyoruz. > <> 'In toroidal yapısından dolayı aşağıdakiler bir döngü halinde çalışır:

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

Bunun, girişin yalnızca yazdırılabilir ASCII içerdiğini, ASCII 0 olması durumunda işe yaramayacağının kullanıldığını unutmayın.


1
....... bu harika. Keşke bunu düşünebilseydim. Cevabımda bunun bir Befunge sürümünü ekleyeceğim, ancak birincil olarak değil. EDIT: İkinci düşüncede, bu işe yaramaz çünkü Befunge'in sonsuz bir kod alanı yoktur. Dangit!
El'endia Starman

@ El'endiaStarman Beam cevabının da aynı şeyi yaptığını düşünüyorum, bu yüzden ne yazık ki ilk olduğumu söyleyemem: P
Sp3000

Evet, bence haklısın. Açıklaman daha net.
El'endia Starman


5

Öğe , 22 19 18 bayt

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

Örnek giriş / çıkış: hello world->helo wrd

Bu, karakter dizisini bir kerede yalnızca bir karakter işleyerek ve daha önce gördüklerini takip ederek çalışır.

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

Çıktı dizesi rkarakterini karakterden coluşturur, girdideki karakter dahil ancak henüz görmemiş olsaydık.

Python 2 47 olacak, 4 karakter kaybediyor raw_inputve 1 para cezasına ihtiyaç duyulmuyor print.


Şimdi fikir birliği inputPython 2'de kullanabileceğiniz gibi görünüyor , bu yüzden sizinkini bir bayt daha kısaltabilirsiniz.
mbomb007

4

APL, 3

∊∪/

Bu, vektörün her elemanı arasında birleşme (∪) uygulayarak, kopyaları çıkarma etkisine sahip bir yineleme elde eder.

Tryapl.org'da test edin

Eski olan:

~⍨\

Bu, argümanın her öğesi arasında uygulanan ~ (arg kullanarak, argümanlarla birlikte) kullanır. Sonuçta, her öğe için, zaten listede varsa, silinir.


Nitpicking: "Girdi ve çıktı dizge olmalı" diyor Luis. "Sendika azaltma" bir dize değil iç içe bir dizi döndürür. O :-)
lstefano

Haklısın, düzeltmek için başında bir a ekleyerek.
Moris Zucca

3

Perl, 54 27 bayt

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

Ölçek:

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

1
print exists($h{$_})?"":$_$h{$_}||print
manat işi

SO içine bir unicode → karakter ekletti mi?
steve

1
Bir ifade değiştirici kullanmak size bazı baytları kazandıracak, @ manatwork'ün önerisi ile birlikte kullanacağınız $h{$_}||=printve kullanmaya başlamanız da biraz daha tasarruf sağlayacaktır <>=~/./g!
Dom Hastings,

1
Hayır, “değiştir” in anlamı ile ekledim.
Manatwork

1
İçin değiştirilmesi mapde tasarruf artıracak: map{$h{$_}||=print}<>=~/./g
manatwork

3

PHP, 72 Bayt 84 Bayt

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

Karakterleri ilişkisel bir dizi için anahtar olarak kullanır, sonra anahtarları yazdırır. Dizi elemanlarının sırası her zaman ekleme sırasıdır.

str_splitÖneri için teşekkürler Ismael Miguel .


1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));Daha kısa ve aynı şeyi yapar.
Ismael Miguel,

Daha kısa bir döngü Bulunan: while($c=$argv[1][$i++*1]). Bu bütünün yerine geçer foreach. Geri kalan her şey aynı
Ismael Miguel

Önce benzer bir şey denedim, ama ondan uzak durdum çünkü “yanlış” olan bir karakter üzerinde duracaktı, yani "0". Giriş olarak "abc0def" yi deneyin.
Fabian Schmengler,

Haklısın. Surelly bunun için 2 bayttan fazlaya mal olmadığı bir çözüm var.
Ismael Miguel,

3

Pyth, 7 bayt

soxzN{z

pseudocode:

z = giriş

z dizisinin z cinsinden z dizininin toplamı.


3

Julia, 45 42 bayt

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

Eski versiyon:

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

Kod, üzerine yeni karakterler ekleyerek yeni dizgiyi oluşturur, ardından joinsonunda uygun bir dizgeyle bir araya getirir. Yeni sürüm dizi anlama yoluyla yineleyerek bazı karakterleri kaydeder. Ayrıca ( ?:yerine ||atamadaki parantez gereksinimini ortadan kaldırır) yerine bir bayt kullanır .

Alternatif çözüm, özyineleme ve regex kullanarak, 45 bayt:

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

Julia, 17 bayt

(Alternatif sürüm)

s->join(union(s))

Bu uniontemelde bir ikame olarak kullanır unique- bunu "gerçek" cevabı olarak kabul etmiyorum, " uniquedemek için kullanmıyorum " anlamına geldiğini yorumluyorum , benzersiz olanı döndürme etkisi olan tek bir yerleşik işlev kullanma elementler".


Benzer bir fikrim vardı ama özlü değildi. İyi iş!
Alex A.

3

Java, 78 bayt

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

Zaten var olan karakterlerin çıkışını kontrol ederken basit bir döngü. Girdiyi a olarak kabul eder char[].


3

C, 96 bayt

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

Bu, ASCII karakter numarasına göre indekslenmiş bir tamsayı dizisi kullanır. Karakterler yalnızca dizideki o yer FALSE olarak ayarlanmışsa yazdırılır. Her yeni karakter bulunduktan sonra dizideki o yer DOĞRU olarak ayarlanır. Bu, standart girdiden yeni bir satırla sonlanan bir metin satırı alır. ASCII olmayan karakterleri yok sayar.


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

@Hvd ve @AShelly'ye bir sürü karakter kaydettiğiniz için teşekkür ederiz. Orijinalden çok daha kısa yapmak için önerilen birçok yol vardı:

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

Yerinde değişiklik görebileceğiniz gibi en kısa gibi görünüyor (şimdiye kadar!) Test programı kullanarak uyarılar olmadan derler 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
}

Tüm yardımların için teşekkürler. Kısaltmak için verilen tüm tavsiyeleri takdir ediyorum!


Eh kodunuz zaten sadece yumuşak C derleyicileri tarafından kabul edilmeyen geçerli C olduğundan,: Eğer ilan edebilir rşekilde int(ve ihmal int) bazı bayt kaydetmek için: f(s,r)char*s;{...}. Ancak kodunuzu char*, aynı boyutta olan platformlarla intve tabii ki derleyicilerin de sizinkiyle aynı derecede esnek olduğu platformlarla sınırlar .
HVD

@hvd Bu kötü! Döndürme değerini varsayılan olarak kullanmak istiyordum çünkü kullanmıyorum. Ama bu olmak istediğimden biraz daha tehlikeli. Sanırım o kadar ileri gitmek yerine onu uyumlu hale getirmeyi tercih ederim! Işık tarafına geri getirdiğin için teşekkürler.
Jerry Jeremiah

Sen değiştirerek tek bir karakter kaydedebilirsiniz if(x)yilex?y:0
ugoren

İşte bir dizi parametresi yerine stdout'a yazan 60 karakterlik bir fonksiyon:f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly

Koşulsuzca kopyalayabilir *qve yalnızca qkarakter daha önce göründüğünde artabilir, biraz birlikte daha fazla doldurmaya izin verir: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}( strchr(r,*s++)<qHer zaman iyi tanımlanmış olduğunu unutmayın , orada UB yoktur, çünkü bu sürümde strchrgeri dönemez NULL.) İade türü hariç, @ AShelly'nin versiyonundan bile daha kısa.
HVD

2

Yakut, 30 24 karakter

(23 karakter kod + 1 karakter komut satırı seçeneği.)

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

Örnek çalışma:

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

2

CJam, 9

Lq{1$-+}/

Bu, dizgiyi kümeye dönüştürmez, ancak karakterin dizgide bulunup bulunmadığını belirlemek için bir çeşit küme fark gerçekleştirir. Çevrimiçi deneyin

Açıklama:

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

Başka bir sürüm, 13 bayt:

Lq{_2$#)!*+}/

Bu setlerle ilgili hiçbir şey yapmaz. Çevrimiçi deneyin

Açıklama:

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 bayt

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

Denklem değişkenleri nadiren faydalıdır, çünkü depolamak için 5 bayt alırlar, ancak Y₁burada X3 bayt tasarruf ederek dizgenin th karakteri olarak kullanışlıdırlar . TI-BASIC'te boş dizgilere ekleyemediğimiz için dizgiyi Str1'in ilk karakteriyle başlattıktan sonra dizginin geri kalanını geçip, henüz karşılaşılmayan tüm karakterleri ekliyoruz.

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

2

Matlab, 46 bayt

Girdi ve çıktı olarak işlev değişkenleriyle birlikte anonim bir işlev kullanır:

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

(Bunun bir Octave çevrimiçi tercümanında çalışmasını sağlayamadım.)

Örnek kullanım:

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

bunu da :) benim fikir olurdu - Gerek duymadığınız ,1ile anybtw.
Jonas

@Jonas Teşekkürler! O parantez dağınıklığını görmek zor olsa da, 1bunun için triu (köşegeni kaldırmam gerekiyor)any
Luis Mendo

2

Befunge -93, 124 bayt

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

Bu çevrimiçi tercümanda test edin .


Bu beklediğimden daha zordu. Biri beni isterse yarın daha ayrıntılı bir açıklama göndereceğim, ancak kodumun yaptığıma genel bir bakış.

  • Şimdiye kadar görülen benzersiz karakterler ilk satırda, 2,0sağdan başlayarak ve sağa doğru ilerler. Bu, geçerli karakterin kopya olup olmadığını görmek için kontrol edilir.
  • Şimdiye kadar görülen benzersiz karakterlerin sayısı saklanır 0,0ve yinelenen check-in döngü sayacı içine kaydedilir 1,0.
  • Benzersiz bir karakter göründüğünde, ilk sıraya kaydedilir, yazdırılır ve sayaç girişi 0,0artırılır.
  • Mevcut boşluklarda okuma ile ilgili problemleri önlemek için (ASCII 32), bir sonraki benzersiz karakter için bir sonraki yuvaya -1 (gerçekten, 65536) değerine karşılık gelen karakteri koydum.

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

@ Fschmengler'in yanıtınıarray_flip iki kez kullanarak - ikinci sürüm değişken yöntemini kullanır ve dizgeyi gerçeğe dönüştürmeye, yanlış olarak reddetmeye, sonra da ilk argümandaki boş dizgeye geri döndürmeye, ikincisinde birkaç bayt tasarruf etmeye dayanır. Ucuz!


2

Haskell , 29 bayt

Değiştirilebilir, değişkensiz isim tek astar:

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

Aynı sayı, füst seviye bildirim olarak adlandırılan bir işleve kaydedildi :

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

Ben güzelliği ruhu içinde yapmadım hile biraz optimizasyon olduğunu unutmayın: teknik olarak hala bir dize için farklı bir giriş ve çıkış kodlaması kullanmak bu meydan okuma kuralları tarafından izin verilir. stringKısmen uygulanmış Kilise kodlamasıyla \f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](işlev tarafından sağlanan ($ (:))önyüklemenin diğer tarafı ile) herhangi birini temsil etmek suretiyle, bu işlem ($ \x->(x:).filter(x/=))sadece 24 karaktere indirgenir .

24 karakterlik cevabı resmi olarak yayınlamaktan foldr(\x->(x:).filter(x/=))[]"Type unique chars!"kaçındım çünkü yukarıdaki çözüm yukarıdaki tercüman üzerinde denenebiliyordu ;

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

daha çılgına dönecek olan tam anlamıyla beyan için bir kestirme olarak:

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

Ancak, saf fonksiyonlar olarak gösterilen veri yapısının kusursuz bir versiyonu. (Tabii ki, siz de kullanabilirsiniz \f -> foldr f [] "Type unique chars!", ancak verileri gerçekten depolamak için listeler kullandığından muhtemelen yasadışıdır, bu nedenle katlanmış kısmı daha sonra 24 karakterden daha fazla karaktere yol açan "cevap" işlevinde oluşturulmalıdır.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.