Golfed + C'de hızlı sıralama


11

[ Son güncelleme: kıyaslama programı ve ön sonuçlar mevcut, aşağıya bakınız]

Bu yüzden hız / karmaşıklık dengesini klasik bir uygulama ile test etmek istiyorum: sıralama.

Kayan nokta sayı dizisini artan sırada sıralayan bir ANSI C işlevi yazın .

Hiçbir kitaplığı, sistem çağrısını, çoklu iş parçacığını veya satır içi ASM'yi kullanamazsınız .

Girişler iki bileşene göre değerlendirilir: kod uzunluğu ve performans. Aşağıdaki gibi puanlama: girişler uzunluğa (boşluk içermeyen # karakterlerin günlüğü, böylece bazı biçimlendirmeyi koruyabilmeniz için) ve performansa (bir kıyaslama üzerinde # saniyenin günlüğü) göre ve her aralıkta [en iyi, en kötü] doğrusal olarak [ 0,1]. Bir programın toplam puanı, normalleştirilmiş iki puanın ortalaması olacaktır. En düşük puan kazanır. Kullanıcı başına bir giriş.

Sıralama (sonuçta) yerinde olmalıdır (yani, giriş dizisinin dönüş zamanında sıralı değerler içermesi gerekir) ve adlar dahil olmak üzere aşağıdaki imzayı kullanmanız gerekir:

void sort(float* v, int n) {

}

Sayılacak karakterler: sortfonksiyondakiler, imza dahil artı çağrılan ek fonksiyonlar (fakat test kodu dahil değil).

Program float, 2 ^ 20'ye kadar olan herhangi bir sayısal değeri ve uzunluk = = 0 dizilerini işlemelidir.

Ben fiş edeceğiz sortve bağımlılıkları bir test programına ve GCC (hiçbir fantezi seçenekleri) üzerine derlemek. Bir dizi diziyi içine aktaracağım, sonuçların doğruluğunu ve toplam çalışma süresini doğrulayacağım. Testler Ubuntu 13 altında bir Intel Core i7 740QM (Clarksfield) üzerinde
yapılacaktır . Dizi uzunlukları, daha yüksek kısa dizi yoğunluğu ile izin verilen tüm aralığı kapsayacaktır. Değerler, yağ kuyruğu dağılımıyla (hem pozitif hem de negatif aralıklarda) rastgele olacaktır. Bazı testlere yinelenen öğeler dahil edilecektir.
Test programına buradan ulaşabilirsiniz: https://gist.github.com/anonymous/82386fa028f6534af263
Gönderimi olarak içe aktarır user.c. TEST_COUNTGerçek kıyaslamadaki test senaryolarının ( ) sayısı 3000 olacaktır. Lütfen soru yorumlarında herhangi bir geri bildirim sağlayın.

Son teslim tarihi: 3 hafta (7 Nisan 2014, 16:00 GMT). Benchmark 2 hafta içinde ilan edeceğim.
Kodunuzu rakiplere vermekten kaçınmak için son başvuru tarihine yakın bir süre göndermeniz tavsiye edilebilir.

Kıyaslama yayını itibariyle ön sonuçlar:
İşte bazı sonuçlar. Son sütun skoru yüzde olarak gösterir, ne kadar yüksek olursa Johnny Cage ilk sırada yer alır. Diğerlerinden daha yavaş büyüklük sırası olan algoritmalar bir test alt kümesinde yürütüldü ve zaman tahmin edildi. C'nin kendi qsortkarşılaştırma için dahil (Johnny's daha hızlı!). Kapanış saatinde son bir karşılaştırma yapacağım.

resim açıklamasını buraya girin


3
Benchmark sağlayabilir misiniz? Farklı sıralama işlevleri verinin doğasına bağlı olarak farklı performans gösterir. Kabarcık sıralaması, küçük diziler için stdlib quicksort'tan daha hızlıdır. Karşılaştırmanız için optimize etmek isteyebiliriz.
Claudiu

@Claudiu Bir keresinde, her öğenin farklı olduğu verilerde olduğu gibi diğerlerinin yanı sıra quicksort'un güzel bir kısa versiyonunu gördüm. Ancak bazı unsurlar aynı olsaydı, mutlak bir salyangoz hızında koştu. Sıralı / kısmen sıralı dizilerde pivotun kötü seçiminin bilinen sorunu hakkında konuşmuyorum. Test verilerim tamamen rastgele karıştırıldı. Bu özel sürüm kopyaları beğenmedi. Tuhaf, ama gerçek.
Level River St

3
PPCG'ye Hoşgeldiniz! Dile özgü zorlukları yasaklamasak da, soruları mümkün olduğunca dile agnostik bir şekilde formüle etmeyi kuvvetle teşvik ediyoruz. Bir sonraki sorunuz için düşünün ve bununla eğlenin!
Jonathan Van Matre

1
@steveverrill: Takip etmiyorum. Ünitenizin ne olduğu önemli değil, çünkü yine de 0'dan 1'e ölçeklendiriyorsunuz. Min 1 saat ve max 3 saat ise, 1,5 saat süren bir şey, min'in 60 dakika, maks 180 dakika olup olmadığına bakılmaksızın 0,25 olur ve 90 dakika sürer
Claudiu

1
OP sadece satır içi montaj olmadığını söyledi - içsel hakkında hiçbir şey söylemedi.
Paul R

Yanıtlar:


6

150 karakter

Hızlı sıralama.

/* 146 character.
 * sizeup 1.000; speedup 1.000; */
#define REC_SIZE    \
    sort(l, v+n-l); \
    n = l-v;

/* 150 character.
 * sizeup 1.027; speedup 1.038; */
#define REC_FAST  \
    sort(v, l-v); \
    n = v+n-l;    \
    v = l;

void sort(float* v, int n)
{
    while ( n > 1 )
     {
       float* l = v-1, * r = v+n, x = v[n/2], t;
L:
       while ( *++l < x );
       while ( x < (t = *--r) );

       if (l < r)
        {
          *r = *l; *l = t;
          goto L;
        }
       REC_FAST
     }
}

Sıkıştırılmış.

void sort(float* v, int n) {
while(n>1){float*l=v-1,*r=v+n,x=v[n/2],t;L:while(*++l<x);while(x<(t=*--r));if(l<r){*r=*l;*l=t;goto L;}sort(v,l-v);n=v+n-l;v=l;}
}

Yarışa liderlik!
Mau

3

150 karakter (boşluk olmadan)

void sort(float *v, int n) {
    int l=0;
    float t, *w=v, *z=v+(n-1)/2;

    if (n>0) {
      t=*v; *v=*z; *z=t;
      for(;++w<v+n;)
        if(*w<*v)
        {
          t=v[++l]; v[l]=*w; *w=t;
        }
      t=*v; *v=v[l]; v[l]=t;
      sort(v, l++);
      sort(v+l, n-l);
    }
}

Harika, ilk giriş!
Mau

SSE ile bir cevap göndermek için çekinmeyin ve ben meydan için 'taşınabilir' çözümleri ile ilgileniyorum rağmen ben, skorbord listeleyeceğim.
Mau

if(*w<*v) { t=v[++l]; v[l]=*w; *w=t; }olabilirif(*w<*v) t=v[++l], v[l]=*w, *w=t;
ASKASK

3

67 70 69 karakter

Hiç hızlı değil, ama inanılmaz derecede küçük. Sanırım bir seçim sıralama ve kabarcık sıralama algoritması arasında bir melez. Bunu gerçekten okumaya çalışıyorsanız, bununla ++i-v-naynı olduğunu bilmelisiniz ++i != v+n.

void sort(float*v,int n){
    while(n--){
        float*i=v-1,t;
        while(++i-v-n)
            *i>v[n]?t=*i,*i=v[n],v[n]=t:0;
    }
}

if(a)b-> a?b:0karakter kaydeder.
ugoren

Tabii ki, sadece şartlı ++i-v-nolanla aynı ++i != v+n.
wchargin

@ugoren sanırım yanlış cevaba yorum
yazdınız

@ASKASK, if(*i>v[n])...->*i>v[n]?...:0
ugoren

Başkanlığın böyle çalıştığından emin misin?
ASKASK

2

123 karakter (+3 yeni satır)

Standart bir Shell türü, sıkıştırılmış.

d,i,j;float t;
void sort(float*v,int n){
for(d=1<<20;i=d/=2;)for(;i<n;v[j]=t)for(t=v[j=i++];j>=d&&v[j-d]>t;j-=d)v[j]=v[j-d];
}  

Not: hala hızlı sıralamadan 10 kat daha yavaş olduğunu keşfetti. Bu girişi de göz ardı edebilirsiniz.


Boşluk seçiminiz daha iyi olabilir. Bu muhtemelen bu çabuk sıralamadan çok daha yavaştır. en.wikipedia.org/wiki/Shellsort#Gap_sequences
FDinoff

Boşluk dizisinin hızı ne kadar etkilediğini görmek beni şaşırttı. İyi bir dizi ile çabuk sıralama yakın geliyor ama benim deneyimimde daha yavaş kalır.
Florian F

Kendiniz için çok zor olma. Üçüncü sıradasınız.
Kevin

2

395 karakter

Mergesort.

void sort(float* v,int n){static float t[16384];float*l,*r,*p,*q,*a=v,*b=v+n/2,
*c=v+n,x;if(n>1){sort(v,n/2);sort(v+n/2,n-n/2);while(a!=b&&b!=c)if(b-a<=c-b&&b-
a<=16384){for(p=t,q=a;q!=b;)*p++=*q++;for(p=t,q=t+(b-a);p!=q&&b!=c;)*a++=(*p<=
*b)?*p++:*b++;while(p!=q)*a++=*p++;}else{for(l=a,r=b,p=t,q=t+16384;l!=b&&r!=c&&
p!=q;)*p++=(*l<=*r)?*l++:*r++;for(q=b,b=r;l!=q;)*--r=*--q;for(q=t;p!=q;)*a++=
*q++;}}}

Biçimlendirilmiş.

static float* copy(const float* a, const float* b, float* out)
{   while ( a != b ) *out++ = *a++; return out;
}
static float* copy_backward(const float* a, const float* b, float* out)
{   while ( a != b ) *--out = *--b; return out;
}

static void ip_merge(float* a, float* b, float* c)
{
    /* 64K (the more memory, the better this performs). */
#define BSIZE (1024*64/sizeof(float))
    static float t[BSIZE];

    while ( a != b && b != c )
     {
       int n1 = b - a;
       int n2 = c - b;

       if (n1 <= n2 && n1 <= BSIZE)
        {
          float* p = t, * q = t + n1;
          /* copy [a,b] sequence. */
          copy(a, b, t);
          /* merge. */
          while ( p != q && b != c )
             *a++ = (*p <= *b) ? *p++ : *b++;
          /* copy remaining. */
          a = copy(p, q, a);
        }
       /* backward merge omitted. */
       else
        {
          /* there are slicker ways to do this; all require more support
           * code. */
          float* l = a, * r = b, * p = t, * q = t + BSIZE;
          /* merge until sequence end or buffer end is reached. */
          while ( l != b  && r != c && p != q )
             *p++ = (*l <= *r) ? *l++ : *r++;
          /* compact remaining. */
          copy_backward(l, b, r);
          /* copy buffer. */
          a = copy(t, p, a);
          b = r;
        }
     }
}

void sort(float* v, int n)
{
    if (n > 1)
     {
       int h = n/2;
       sort(v, h); sort(v+h, n-h); ip_merge(v, v+h, v+n);
     }
}

2

331 326 327 312 karakter

Yarıçap bir seferde 8 bit sıralar mı? Negatif şamandıraları doğru şekilde sıralamak için süslü bir bithack kullanır ( http://stereopsis.com/radix.html adresinden çalınır ). Bu kadar kompakt değil, ama gerçekten hızlı (en hızlı prelim girişinden ~ 8 kat daha hızlı). Ben kod boyutu trumping hız umuyorum ...

#define I for(i=n-1;i>=0;i--)
#define J for(i=0;i<256;i++)
#define R for(r=0;r<4;r++)
#define F(p,q,k) I p[--c[k][q[i]>>8*k&255]]=q[i]

void sort(float *a, int n) {
  int *A = a,i,r,x,c[4][257],B[1<<20];
  R J c[r][i]=0;
  I {
    x=A[i]^=A[i]>>31|1<<31;
    R c[r][x>>8*r&255]++;
  }
  J R c[r][i+1]+=c[r][i];

  F(B,A,0);
  F(A,B,1);
  F(B,A,2);
  F(A,B,3)^(~B[i]>>31|1<<31);
}

2

511 424 karakter

Yerinde sayı tabanı

Güncelleme: Daha küçük dizi boyutları için ekleme sıralamasına geçer (karşılaştırma performansını 4,0 kat artırır).

#define H p[(x^(x>>31|1<<31))>>s&255]
#define L(m) for(i=0;i<m;i++)
void R(int*a,int n,int s){if(n<64){float*i,*j,x;for(i=a+1;i<a+n;i++){x=*i;for(
j=i;a<j&&x<j[-1];j--)*j=j[-1];*j=x;}}else{int p[513]={},*q=p+257,z=255,i,j,x,t
;L(n)x=a[i],H++;L(256)p[i+1]+=q[i]=p[i];for(z=255;(i=p[z]-1)>=0;){x=a[i];while
((j=--H)!=i)t=x,x=a[j],a[j]=t;a[i]=x;while(q[z-1]==p[z])z--;}if(s)L(256)R(a+p[
i],q[i]-p[i],s-8);}}void sort(float* v,int n){R(v,n,24);}

Biçimlendirilmiş.

/* XXX, BITS is a power of two. */
#define BITS 8
#define BINS (1U << BITS)
#define TINY 64

#define SWAP(type, a, b) \
    do { type t=(a);(a)=(b);(b)=t; } while (0)

static inline unsigned int floatbit_to_sortable_(const unsigned int x)
{   return x ^ ((0 - (x >> 31)) | 0x80000000);
}

static inline unsigned int sortable_to_floatbit_(const unsigned int x)
{   return x ^ (((x >> 31) - 1) | 0x80000000);
}

static void insertsort_(unsigned int* a, unsigned int* last)
{
    unsigned int* i;
    for ( i = a+1; i < last; i++ )
     {
       unsigned int* j, x = *i;
       for ( j = i; a < j && x < *(j-1); j-- )
          *j = *(j-1);
       *j = x;
     }
}

static void radixsort_lower_(unsigned int* a, const unsigned int size,
  const unsigned int shift)
{
    /* @note setup cost can be prohibitive for smaller arrays, switch to
     * something that performs better in these cases. */
    if (size < TINY)
     {
       insertsort_(a, a+size);
       return;
     }

    unsigned int h0[BINS*2+1] = {}, * h1 = h0+BINS+1;
    unsigned int i, next;

    /* generate histogram. */
    for ( i = 0; i < size; i++ )
       h0[(a[i] >> shift) % BINS]++;

    /* unsigned distribution.
     * @note h0[BINS] == h1[-1] == @p size; sentinal for bin advance. */
    for ( i = 0; i < BINS; i++ )
       h0[i+1] += (h1[i] = h0[i]);

    next = BINS-1;
    while ( (i = h0[next]-1) != (unsigned int) -1 )
     {
       unsigned int x = a[i];
       unsigned int j;
       while ( (j = --h0[(x >> shift) % BINS]) != i )
          SWAP(unsigned int, x, a[j]);
       a[i] = x;
       /* advance bins.
        * @note skip full bins (zero sized bins are full by default). */
       while ( h1[(int) next-1] == h0[next] )
          next--;
     }

    /* @note bins are sorted relative to one another at this point but
     * are not sorted internally. recurse on each bin using successive
     * radii as ordering criteria. */
    if (shift != 0)
       for ( i = 0; i < BINS; i++ )
          radixsort_lower_(a + h0[i], h1[i] - h0[i], shift-BITS);
}

void sort(float* v, int n)
{
    unsigned int* a = (unsigned int*) v;
    int i;

    for ( i = 0; i < n; i++ )
       a[i] = floatbit_to_sortable_(a[i]);

    radixsort_lower_(a, n, sizeof(int)*8-BITS);

    for ( i = 0; i < n; i++ )
       a[i] = sortable_to_floatbit_(a[i]);
}

Güzel! Orijinal yanıtı işaretlemeyi deneyin.
Mau

@Mau: Teşekkürler ve yapacağız. Kıyaslama kodunda bir hatadan bahsetmek istedim. Dökme void*olarak qsort(hat 88) işaretçi Aritmetik devre atıyor.
MojoJojoBojoHojo

1

121 114 111 karakter

Sadece hızlı ve kirli bir kabarcıklar, özyineleme ile. Muhtemelen çok verimli değil.

void sort(float*v,int n){int i=1;float t;for(;i<n;i++)v[i-1]>(t=v[i])&&(v[i]=v[i-1],v[i-1]=t);n--?sort(v,n):0;}

Veya uzun versiyon

void sort(float* values, int n) {
  int i=1;  // Start at 1, because we check v[i] vs v[i-1]
  float temp;
  for(; i < n; i++) {
    // If v[i-1] > v[i] is true (!= 0), then swap.
    // Note I am assigning values[i] to temp here. Below I want to use commas
    // so the whole thing fits into one statement, but if you assign temp there you will get sequencing issues (i.e unpredictable swap results)
    values[i - 1] > (temp = values[i]) && (
    // I tried the x=x+y,y=x-y,x=x-y trick, but using a temp
    // turns out to be shorter even if we have to declare the t variable.
      values[i] = values[i - 1], 
      values[i - 1] = temp);
  }

  // If n == 1, we are done. Otherwise, sort the first n - 1 elements recursively. 
  // The 0 is just because the third statement cannot be empty.
  n-- ? sort(values, n) : 0;
}

Bir yana, burada gerçekten ilginç bir algoritma buldum: rosettacode.org/wiki/Sorting_algorithms/Pancake_sort#C Ama 114 :)
CompuChip

programınız bazı durumlarda tamamlanamıyor ve diğer durumlarda sınırlar dışında kalıyor gibi görünüyor.
Mau

@Mau Ben bazı girişler üzerinde manuel olarak test ve Tamam gibi görünüyordu, ama zaman eksikliği nedeniyle ben çok thouroughly test etmedi bu yüzden bir yerde bazı kötü davranış olduğundan eminim. Bir sorunla karşılaştığınız bir test davası gönderebilir misiniz?
CompuChip

Test programı yukarıda mevcut :)
Mau

Hmm çalıştırmayı denedim, temizleme bölümünde bazı `munmap_chunk (): geçersiz işaretçi` hataları alıyorum, ancak test başarısız oldu. Ancak bir off-by-one hata var haklısın ve bazı sıralama sorunları var gibi görünüyor (virgülle ayrılmış deyimler listesi ben beklediğim şeyi yapmaz). Düzeltmeye çalışacağım.
CompuChip

1

221 193 172 karakter

Yığın sıralaması - En küçük değil, yerinde ve O (n * log (n)) davranışını garanti eder.

static void sink(float* a, int i, int n, float t)
{
    float* b = a+i;

    for ( ; (i = i*2+2) <= n; b = a+i )
     {
       i -= (i == n || a[i] < a[i-1]) ? 1 : 0;

       if (t < a[i])
          *b = a[i];
       else
          break;
     }
    *b = t;
}

void sort(float* a, int n)
{
    int i;
    /* make. */
    for ( i = n/2-1; i >= 0; i-- )
       sink(a, i, n, a[i]);
    /* sort. */
    for ( i = n-1; i > 0; i-- )
     {
       float t = a[i]; a[i] = a[0];
       sink(a, 0, i, t);
     }
}

Sıkıştırılmış.

void sort(float* a,int n){
#define F(p,q,r,x,y) for(i=n/p;q>0;){t=a[i];r;for(j=x;(b=a+j,j=j*2+2)<=y&&(j-=(j==y||a[j]<a[j-1]),t<a[j]);*b=a[j]);*b=t;}
float*b,t;int i,j;F(2,i--,,i,n)F(1,--i,a[i]=*a,0,i)
}

Boşluğu çıkararak bazı karakterleri kaydedebilirsiniz. Muhtemelen zorunlu işlev imzası da var, ancak sayılan bazı girişler olduğundan, sorgulayıcıdan sayılması gerekip gerekmediğini netleştirmesini istedim.
Jonathan Van Matre

@ user19425: Test programını TEST_COUNT= 3000 ile çalıştırırsanız, en az bir testte başarısız gibi görünüyor.
Mau

1

154 166 karakter

Tamam, işte daha uzun ama daha hızlı bir çabuk sıralama.

void sort(float*v,int n){while(n>1){float*j=v,*k=v+n-1,t=*j;while(j<k){while(j<k&&*k>=t)k--;*j=*k;while(j<k&&*j<t)j++;*k=*j;}*k++=t;sort(k,v+n-k);n=j-v;}}

Sıralı girdilerden kurtulmak için bir düzeltme. Ve beyaz boşluk sayılmadığından biçimlendirilmiş.

void sort(float*v, int n){
    while(n>1){
        float*j=v, *k=j+n/2, t=*k;
        *k = *j;
        k = v+n-1;
        while(j<k){
            while(j<k && *k>=t) k--;
            *j=*k;
            while(j<k && *j<t) j++;
            *k=*j;
        }
        *k++ = t;
        sort(k,v+n-k);
        n = j-v;
    }
}

Bu sürüm bazı durumlarda sınırların dışında kalıyor, diğerlerinde sonlandırmıyor gibi görünüyor.
Mau

PS: Tamam, sıralanmış bir sette çok yavaş. Ancak sorun ifadesi girdinin rastgele olduğunu söylüyor.
Florian F

Değerler rastgele. Ben hangi sırayla olacakları hakkında hiçbir şey söylemedim :-) Ama evet, artan sırayla sıralanmış tüm değerlerin yaklaşık% 10'unu ve azalan sırada başka bir% 10'u kapsayan parçalar var.
Mau

1
Yeterince adil. Ve bir sort () sıralı girdi üzerinde çalışmalıdır. Gönderimi güncelleyeceğim, o zaman ...
Florian F

1

150 karakter

Shellsort (Knuth boşluğu ile).

void sort(float* v, int n) {
float*p,x;int i,h=0;while(2*(i=h*3+1)<=n)h=i;for(;h>0;h/=3)for(i=h;i<n;i++){x=v[i];for(p=v+i-h;p>=v&&x<*p;p-=h)p[h]=*p;p[h]=x;}
}

Biçimlendirilmiş.

static void hsort(float* v, const int h, const int n)
{
    int i;
    for (i = h; i < n; i++) {
        float* p, x = v[i];
        for (p = v + i-h; p >= v && x < *p; p -= h)
            p[h] = *p;
        p[h] = x;
    }
}

void sort(float* v, int n)
{
    int i, h = 0;
    while (2*(i = h*3+1) <= n)
        h = i;
    for (; h > 0; h /= 3)
        hsort(v, h, n);
}

1

C 270 (golf sahasında)

#define N 1048576
void sort(float*v,int n)
{
float f[N],g;
int m[N],i,j,k,x;
g=v[0];k=0;
for(i=0;i<n;i++){for(j=0;j<n;j++){if(m[j]==1)continue;if(v[j]<g){g=v[j];k=j;}}f[i]=g;m[k]=1;for(x=0;x<n;x++){if(m[x]==0){g=v[x];k=x;break;}}}
for(i=0;i<n;i++){v[i]=f[i];}
}

Açıklama: Birbirini izleyen her minimum sayıyı depolamak için boş bir dizi kullanılır. İnt dizisi, 0'ın sayının henüz kopyalanmadığını gösteren bir maskesidir. Minimum değeri aldıktan sonra bir maske = 1 önceden kullanılmış sayıları atlar. Sonra dizi orijinaline geri kopyalanır.

Kütüphane fonksiyonlarının kullanımını ortadan kaldırmak için kodu değiştirdim.


0

144

Utanmadan Johnny'nin kodunu aldım, küçük bir optimizasyon ekledim ve kodu çok kirli bir şekilde sıkıştırdım. Daha kısa ve daha hızlı olmalıdır.

Derleyicinize bağlı olarak, sıralama (q, v + n- ++ q), sıralama (++ q, v + nq) ile değiştirilmelidir.

#define w ;while(
void sort(float*v, int n){
    w n>1){
        float *p=v-1, *q=v+n, x=v[n/2], t
        w p<q){
            w *++p<x )
            w *--q>x );
            if( p<q ) t=*p, *p=*q, *q=t;
        }
        sort(q,v+n- ++q);
        n = p-v;
    }
}

Aslında, kodumu oluşturmaya ve optimize etmeye başladım, ancak Johnny zaten tüm doğru seçimleri yapmış gibi görünüyor. Bu yüzden kodunu yarıya indirdim. Goto hilesini düşünmedim, ama onsuz yapabilirdim.


0

228 karakter

Basamağa göre sıralama.

void sort(float* v, int n) {
#define A(x,y,z) for(x=y;x<z;x++)
#define B h[(a[i]^(a[i]>>31|1<<31))>>j*8&255]
    int m[1<<20],*a=v,*b=m,*t,i,j;
    A(j,0,4) {
        int h[256] = {};
        A(i,0,n) B++;
        A(i,1,256) h[i] += h[i-1];
        for (i = n-1; i >= 0; i--)
            b[--B] = a[i];
        t = a, a = b, b = t;
    }
}
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.