C에서 골프 + 빠른 정렬


11

[ 최신 업데이트 : 벤치 마크 프로그램 및 예비 자료 제공, 아래 참조]

따라서 고전적인 응용 프로그램 인 정렬과 함께 속도 / 복잡성 트레이드 오프를 테스트하고 싶습니다.

부동 소수점 숫자의 배열을 오름차순으로 정렬하는 ANSI C 함수를 작성하십시오 .

당신이 사용할 수 있는 라이브러리, 시스템 호출, 멀티 스레딩 또는 인라인 ASM을.

출품작은 코드 길이 성능 이라는 두 가지 구성 요소로 판단됩니다 . 다음과 같이 점수가 매겨집니다. 항목은 길이 (공백이없는 # 문자 로그이므로 일부 서식을 유지할 수 있음) 및 성능 (벤치 마크에서 # 초 로그) 및 각 간격 [최고, 최악]에 따라 선형으로 [ 0,1]. 프로그램의 총점은 정규화 된 두 점수의 평균입니다. 최저 점수가 이깁니다. 사용자 당 하나의 항목.

정렬은 (결과적으로) 제자리에 있어야하며 (즉, 입력 배열은 반환 시간에 정렬 된 값을 포함해야 함) 이름을 포함하여 다음 서명을 사용해야합니다.

void sort(float* v, int n) {

}

계산할 문자 : sort함수의 문자 , 서명 포함 및 추가 함수 (테스트 코드는 포함되지 않음)

프로그램은 float2 ^ 20까지의 길이가 0보다 큰 숫자 값 과 배열을 처리해야합니다 .

sort테스트 프로그램에 플러그인 과 그 의존성을 연결 하고 GCC를 컴파일합니다 (공상 옵션 없음). 여기에 여러 배열을 공급하고 결과의 정확성과 총 런타임을 확인합니다. 테스트는 Ubuntu 13에서 Intel Core i7 740QM (Clarksfield)에서 실행됩니다.
어레이 길이는 허용되는 전체 범위에 걸쳐 있으며 밀도가 높은 짧은 어레이입니다. 팻 테일 분포 (양수 및 음수 범위 모두)로 값이 임의적입니다. 일부 요소에는 중복 요소가 포함됩니다.
테스트 프로그램은 여기 ( https://gist.github.com/anonymous/82386fa028f6534af263 )에서 제공
됩니다 user.c. TEST_COUNT실제 벤치 마크에서 테스트 사례 수 ( )는 3000입니다. 질문 의견에 의견을 보내주십시오.

마감일 : 3 주 (2014 년 4 월 7 일 16:00 GMT). 2 주 후에 벤치 마크를 게시하겠습니다.
경쟁 업체에 코드를 제공하지 않으려면 마감일 가까이에 게시하는 것이 좋습니다.

벤치 마크 게시 시점의 예비 결과 :
다음과 같은 결과가 있습니다. 마지막 열에는 점수가 백분율로 표시되며, Johnny Cage가 우선 순위가 높아질수록 좋습니다. 나머지보다 훨씬 느린 알고리즘은 테스트의 하위 세트에서 실행되었고 시간은 외삽되었습니다. C는 자신의 qsort비교를 위해 포함되었습니다 (Johnny는 빠릅니다!). 마감 시간에 최종 비교를 수행하겠습니다.

여기에 이미지 설명을 입력하십시오


3
벤치 마크를 제공 할 수 있습니까? 다른 정렬 기능은 데이터의 특성에 따라 다르게 수행됩니다. 예를 들어 기포 정렬은 작은 배열의 stdlib 퀵 정렬보다 빠릅니다. 벤치 마크에 맞게 최적화하고 싶습니다.
Claudiu

@Claudiu 나는 한때 모든 요소가 다른 데이터에서 다른 것과 마찬가지로 실행되는 퀵 정렬의 멋진 짧은 버전을 보았습니다. 그러나 일부 요소가 동일하면 절대 달팽이 속도로 실행됩니다. 정렬 / 부분 정렬 배열에서 잘못된 피벗 선택의 알려진 문제에 대해 이야기하고 있지 않습니다. 내 테스트 데이터가 완전히 무작위로 섞였습니다. 이 특정 버전은 복제본을 좋아하지 않았습니다. 이상하지만 사실입니다.
Level River St

3
PPCG에 오신 것을 환영합니다! 언어 별 문제를 금지하지는 않지만 가능한 한 언어에 구애받지 않는 방식으로 질문을 작성하는 것이 좋습니다. 다음 질문으로 생각하고 재미있게 보내십시오!
Jonathan Van Matre

1
@ steveverrill : 나는 따르지 않습니다. 어쨌든 0에서 1로 크기를 조정하기 때문에 단위가 무엇인지는 중요하지 않습니다. 최소가 1 시간이고 최대가 3 시간 인 경우 1.5 시간은 60 분, 최대 180 분, 90 분과 상관없이 0.25가됩니다.
Claudiu

1
OP는 단지 인라인 어셈블리가 없다고 말했다. 그는 내장 함수에 대해서는 아무 말도하지 않았다.
Paul R

답변:


6

150 자

퀵 정렬.

/* 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
     }
}

압축.

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

경주를 이끌다!
Mau

3

150 자 (공백 제외)

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

대단한 첫 입장!
Mau

SSE로 답을 게시 해 주시면 점수 판에 기재 하겠지만 도전에 대한 '휴대용'솔루션에 관심이 있습니다.
Mau

if(*w<*v) { t=v[++l]; v[l]=*w; *w=t; }할 수 있습니다if(*w<*v) t=v[++l], v[l]=*w, *w=t;
ASKASK

3

67 70 69 자

전혀 빠르지는 않지만 엄청나게 작습니다. 선택 정렬과 거품 정렬 알고리즘 사이의 하이브리드입니다. 실제로이 내용을 읽으려고하는 ++i-v-n경우와 동일 하다는 것을 알아야합니다 ++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:0문자를 저장합니다.
ugoren

글쎄, 물론 조건부 ++i-v-n와 동일 ++i != v+n합니다.
wchargin

@ugoren 나는 당신이 그 답을 오답에 게시했다고 생각합니다
ASKASK

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

우선 순위가 어떻게 작동하는지 확신하십니까?
ASKASK

2

123 자 (+3 줄 바꿈)

압축 된 표준 셸 정렬입니다.

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

추신 : 여전히 퀵 정렬보다 10 배 느립니다. 이 항목을 무시해도됩니다.


격차의 선택이 더 나을 수 있습니다. 아마도 이것이 퀵 정렬보다 훨씬 느린 이유 일 것입니다. en.wikipedia.org/wiki/Shellsort#Gap_sequences
FDinoff

갭 시퀀스가 ​​속도에 얼마나 영향을 미치는지 알게되어 놀랐습니다. 좋은 순서로 퀵 정렬에 가까워 지지만 경험상 느리게 유지됩니다.
Florian F

너무 열심히하지 마십시오. 당신은 3 위에 있습니다.
Kevin

2

395 자

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++;}}}

포맷되었습니다.

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

기수가 한 번에 8 비트를 정렬합니다. 멋진 비트 핵을 사용하여 음수 부동 소수점을 올바르게 정렬합니다 ( http://stereopsis.com/radix.html 에서 도난 당함 ). 그렇게 컴팩트하지는 않지만 실제로 빠릅니다 (가장 빠른 예비 엔트리보다 ~ 8 배 빠름). 코드 크기가 빠른 코드 크기를 기대하고 있습니다 ...

#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 문자

기수 정렬

업데이트 : 더 작은 어레이 크기에 대해 삽입 정렬로 전환합니다 (벤치 마크 성능이 4.0 배 증가).

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

포맷되었습니다.

/* 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]);
}

좋은! 원래 답변을 신고하십시오.
Mau

@Mau : 감사합니다. 벤치마킹 코드에서 오류를 언급하고 싶었습니다. 에 캐스트 void*에서 qsort(라인 88)는 포인터 연산 떨어져 던지고있다.
MojoJojoBojoHojo

1

121 개 114 111 문자

재귀와 함께 빠르고 더러운 거품 정렬. 아마 매우 효율적이지 않습니다.

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

또는 긴 버전

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

따로, 여기 정말 흥미로운 알고리즘을 찾았습니다 : rosettacode.org/wiki/Sorting_algorithms/Pancake_sort#C 그러나 나는 114를 이길 정도로 압축 할 수는 없습니다 :)
CompuChip

어떤 경우에는 프로그램이 완료되지 않고 다른 경우에는 경계를 벗어난 것으로 보입니다.
Mau

@Mau 수동으로 일부 입력을 테스트하고 정상적으로 작동하는 것처럼 보였지만 시간 부족으로 인해 매우 엄격하게 테스트하지 않았으므로 어딘가에 나쁜 행동이 있는지 확신합니다. 문제가 발생한 테스트 사례를 게시 해 주시겠습니까?
CompuChip

위에서 이용 가능한 테스트 프로그램 :)
Mau

흠, 그것을 시도해 보았습니다. 정리 부분에 munmap_chunk () : invalid pointer` 오류가 발생하지만 테스트에 대해서는 아무것도 없습니다. 그러나 당신은 하나 하나의 오류가 있다는 것이 옳습니다. 그리고 일부 시퀀싱 문제가있는 것 같습니다 (쉼표로 구분 된 명령문 목록은 내가 기대하는 것을 수행하지 않습니다). 나는 그것을 고치려고 노력할 것이다.
CompuChip

1

221 193 172 자

힙 정렬-가장 작지는 않지만 O (n * log (n)) 동작을 보장합니다.

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

압축.

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)
}

공백을 빼서 일부 문자를 저장할 수 있습니다. 그리고 필수 함수 서명일 수도 있지만, 질문을했는지 여부를 명확하게 해달라고 요청한 항목이 있으므로 계산해야합니다.
Jonathan Van Matre

@ user19425 : TEST_COUNT= 3000으로 테스트 프로그램을 실행하면 하나 이상의 테스트에 실패한 것 같습니다.
Mau

1

154 개 166 문자

여기 더 길지만 빠른 퀵 정렬이 있습니다.

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

다음은 정렬 된 입력을 유지하기위한 수정 사항입니다. 공백이 포함되지 않으므로 형식이 지정됩니다.

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

이 버전은 어떤 경우에는 범위를 벗어나는 것으로 보이지만 다른 경우에는 끝나지 않습니다.
Mau

추신 : 좋아, 정렬 된 세트에서는 매우 느립니다. 그러나 문제 설명에 따르면 입력은 무작위입니다.
Florian F

값은 임의입니다. 나는 그들이 어떤 순서인지에 대해 아무 말도하지 않았다. 그러나 네, 모든 값의 약 10 %를 오름차순으로 정렬하고 다른 10 %는 내림차순으로 정렬하는 청크가 있습니다.
Mau

1
그럴 수 있지. 그리고 sort ()는 정렬 된 입력에서 작동해야합니다. 제출 한 내용을 업데이트하겠습니다.
Florian F

1

150 자

쉘 소트 (Knuth gap).

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

포맷되었습니다.

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 (골프)

#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];}
}

설명 : 공백 배열은 연속 된 각 최소 숫자를 저장하는 데 사용됩니다. int 배열은 숫자가 아직 복사되지 않았 음을 나타내는 0의 마스크입니다. 최소값을 얻은 후 mask = 1은 이미 사용 된 숫자를 건너 뜁니다. 그런 다음 배열이 원래대로 다시 복사됩니다.

라이브러리 함수를 사용하지 않도록 코드를 변경했습니다.


0

144

나는 뻔뻔스럽게 Johnny의 코드를 가져 와서 작은 최적화를 추가하고 매우 더러운 방식으로 코드를 압축했습니다. 더 짧고 빨라야합니다.

컴파일러에 따라 sort (q, v + n-++ q)는 sort (++ q, v + nq)로 바꿔야합니다.

#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;
    }
}

글쎄, 실제로 코드를 작성하여 최적화했지만 Johnny는 이미 올바른 선택을 한 것 같습니다. 그래서 나는 그의 코드를 거의 완성했습니다. 나는 goto 트릭을 생각하지 않았지만없이 할 수있었습니다.


0

228 자

기수.

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;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.