Tek bir yineleme ile bir dizi negatif, sıfır ve pozitif tamsayı sipariş etme


9

Negatif sayılar, pozitif sayılar ve sıfırlar içeren bir tamsayı dizisi alın. Grup bunu bir yineleme ile ve yerinde pozitif sayıların tüm izledi sıfırların tüm izledi negatif sayıların hepsi önce gelir böyle,.

Misal:

Input:  5, 3, 0, -6, 2, 0, 5
Output: -6, 0, 0, 3, 2, 5, 5

Sayıların tam olarak sıralanması gerekmediğini unutmayın: sadece işarete göre sıralanır.

Böylece, son dizi şöyle görünecektir: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

kurallar

  • Yalnızca giriş dizisini ve sabit miktarda ek belleği kullanabilirsiniz (yani başka diziler oluşturamayabilirsiniz)
  • Dizinin uzunluğu kadar fazla yürütülebilen yalnızca bir döngü kullanabilirsiniz. Herhangi bir döngüyü gizleyen yerleşik işlevleri kullanamazsınız. Bu, yerleşik sıralama işlevlerini içerir.
  • Sonuç tarif ettiğim formatta olmalı

Kazanan, ilk diziyi doğru bir biçime (yukarıda açıklandığı gibi) değiştiren en kısa kodu (bayt cinsinden sayılır) gönderecek olan kişi olacaktır.



@PeterTaylor Thx, şimdi görevin ne olduğunu anlıyorum!
randomra

Tam olarak bu codegolf.stackexchange.com/questions/504/… 1 yineleme ve 1 dizi sınırı kullanın.
Doktor

Yerleşik sıralama işlevlerine izin verilmez, değil mi?
KSFT

1
@KSFT Arama sort(...)muhtemelen birden fazla yineleme yaptığı için iyi değildir.
Ionică Bizău

Yanıtlar:


3

C, 92

Bu muhtemelen en az 10 bayt azaltılabilir; boşa gidecek birçok ifade var.

İlk argüman dizinin başlangıcını göstermelidir; ikincisi dizinin sonundan sonra işaret etmelidir.

*x;f(b,e)int*b,*e;{for(x=b;x<e;x++)*x>0&&--e-x?*x--^=*e^=*x^=*e:*x<0?b-x?*x^=*b=*x:0,b++:0;}

Rastgele test jeneratörü ile yönlendirilmemiş:

*x;
f(b,e)int*b,*e;{
    for(x=b;x<e;x++) {
        if(*x<0) {
            if(b == x)
                b++;
            else
                *b++ = *x, *x=0;
        } else if(*x>0 && x != --e) {
            *x^=*e^=*x^=*e;
            x--;
        }
    }
}

int main()
{
    int a[999];
    srand(time(0));
    int n = rand() % 50;
    int i;
    for(i = 0; i < n; i++) printf("%d ", a[i] = rand() % 9 - 4);
    f(a, a+n);
    puts("");
    for(i = 0; i < n; i++) printf("%d ", a[i]);
    return 0;
}

Bu kod blokları denedim ve derlemez, 3 hata vardır. Ne derledin? x * tanımlanmamış ve {.
bacchusbeale

@bacchusbeale Varsayılan (C89) modunda gcc ile derleyebilirsiniz. CodeBlocks bir derleyici değildir, bu yüzden hangi derleyiciyi kullandığınızı söyleyemem, ancak gcc ile çalışır. Tüm derleyicilerle çalışmamasının nedeni, ANSI standardına uymayan K & R tarzı bildirimlerdir.
feersum

1

STATA 242

Vikipedi sayfasını tam olarak takip eder. Teşekkürler @PeterTaylor

Girişi std girişinden boşlukla ayrılmış bir sayı kümesi olarak alır ve std çıkışı gibi çıktılar da alır.

di _r(a)
token $a//converts to array (kind of)
loc i=0
loc j=0
loc q=wordcount($a)
loc n=`q'-1
while `j'<=`n' {
loc t=``j''
if `t'<0{
loc `j'=``i''
loc `i'=`t'
loc ++i
loc ++j
}
else if `t'>0{
loc `j'=``n''
loc `n'=`t'
loc --n
}
else
loc ++j
}
//used only to output
forv x=1/`q'{
di ``x'' _c
}

1

Python 2: 116 bayt

a=input();i=j=0;n=len(a)
while j<n:b=a[j];r,s=b<0,b>0;c=i*r+n*s-s+j*(b==0);a[c],a[j]=b,a[c];i+=r;n-=s;j+=b<1
print a

Bu, Hollanda ulusal bayrağı sahte kodunun golf edilmiş bir Python çevirisidir.

Olası 112 bayt

Buna izin verilirse emin değilim. İkinci bir boyut 3 dizisi oluşturur (sabit miktarda ek bellek!).

a=input();i=j=0;n=len(a)-1
while j<=n:b=a[j];k=(i,j,n)[cmp(b,0)+1];a[k],a[j]=b,a[k];i+=b<0;n-=b>0;j+=b<1
print a

1

Cı-90

Peter Taylor'ın soru hakkındaki yorumuna göre wikipedia makalesinde algoritmanın doğrudan uygulanması.

aDiğer C yanıtı gibi adlandırılan bir dizideki verileri bulmayı bekler . n, pVe znegatif ve pozitif sayılar ve sıfır yerleştirilmesi için noktalar şunlardır. nve pverilerin ilk ve son öğelerine işaret eden argümanlar olarak alınır.

f(n,p){int t,z;for(z=n;p-z;z++)(t=a[z])?a[z]>0?a[z]=a[p],a[p--]=t:(a[z]=a[n],a[n++]=t):0;}

1

ECMAScript 157 Bayt

Sayıları bilgi istemi iletişim kutusundan boşlukla ayrılmış veya virgülle ayrılmış olarak alır ve sonucu bir uyarı iletişim kutusuyla döndürür.

for(v=prompt().split(/,?\s+/),s=function(j,n){t=v[j],v[j]=v[n],v[n]=t},i=j=0,n=v.length-1;j<=n;)
!(~~v[j]<0&&!s(i++,j++)||~~v[j]>0&&!s(j,n--))&&j++;alert(v);

0

PHP (146)

function f($s){for($i=0,$n=count($s)-1;$j++<=$n;)if($k=$s[$j]){$l=$k>0?n:i;$x=$s[$$l];$s[$$l]=$k;$s[$j]=$x;$k>0?$n--|$j--:$i++;}echo print_r($s);}

http://3v4l.org/ivRX5

PHP'nin nispeten değişken değişken sözdizimi burada biraz acı verici ...


0

Rebol'un - 149 142 140

a: to-block input i: j: 1 n: length? a while[j <= n][case[a/:j < 0[swap at a ++ i at a ++ j]a/:j > 0[swap at a j at a -- n]on[++ j]]]print a

Bu Hollanda ulusal bayrağı wikipedia sözde kodu doğrudan bir bağlantı noktasıdır. Aşağıda ungolfed görünüyor:

a: to-block input
i: j: 1
n: length? a

while [j <= n] [
    case [
        a/:j < 0 [swap at a ++ i at a ++ j]
        a/:j > 0 [swap at a j at a -- n]
        on       [++ j]
    ]
]

print a

Kullanım örneği:

rebol dutch-flag.reb <<< "5 3 0 -6 2 0 5"
-6 0 0 2 3 5 5

NB. Rebol dizileri (bloklar) virgül kullanmaz -[5 3 0 -6 2 0 5]

Ve eğer Tamam ise bunu bir dizi alan ve yerinde değiştiren bir işleve sarıyorsa, 128 karaktere kadar alabiliriz:

>> f: func[a][i: j: 1 n: length? a while[j <= n][case[a/:j < 0[swap at a ++ i at a ++ j]a/:j > 0[swap at a j at a -- n]on[++ j]]]n]

>> array: [5 3 0 -6 2 0 5]
== [5 3 0 -6 2 0 5]

>> print f array
-6 0 0 2 3 5 5

>> ;; and just to show that it as modified array

>> array
== [-6 0 0 2 3 5 5]

Aslında dizi (yani sadece değiştirmek) dönmek gerek yoktu, o zaman 1 char daha tıraş olabilir.


0

C ++

Golfsiz çözüm: n, dizinin önüne eklenen negatifleri sayar. Her eleman için n öğesinde negatif takas, n + 1 öğesinde sıfır takas, son eleman ile takas.

void p(int* k,int n)
{
for(int i=0;i<n;i++)
{
cout<<*(k+i)<<' ';
}
cout<<endl;
}

void s(int *x,int i,int j)
{
int t=*(x+j);
*(x+j)=*(x+i);
*(x+i)=t;
}
void f(int *x,int L)
{
int n=0;
int k;
for(int i=1;i<L;i++)
{
k=*(x+i);
if(k<0)
{
s(x,i,n);
n++;
}
else if(k==0)
{
s(x,i,n+1);
}
else if(k>0)
{
s(x,i,L-1);
}
}
}

int main()
{
int x[]={5,2,-1,0,-2,4,0,3};
f(x,8);
p(x,8);
return 0;
}

0

CJam - 72 67

q~_,(:N;{_U=:B0>{U1$N=tNBtN(:N;}{B{U1$T=tTBtT):T;}{}?U):U;}?UN>!}gp

Giriş: [5 3 4 0 -6 2 0 5]
Çıkış:[-6 0 0 4 2 3 5 5]

Http://cjam.aditsu.net/ adresinde deneyin.

Açıklama:

Bu kullanılarak Vikikaynağın algoritmanın başka bir uygulamasıdır Tiçin ive Uiçin j(her ikisi de otomatik olarak 0 başlatılır).

q~                    read and evaluate the array (let's call it "A")
_,(:N;                keep A on the stack and set N ← size of A - 1  
{                     do...  
    _U=:B             keep A on the stack and set B ← A[U] (also leaving B on the stack)  
    0>{               if B > 0
        U1$N=t        A[U] ← A[N]
        NBt           A[N] ← B
        N(:N;         N ← N - 1
    }{                else
        B{            if B ≠ 0
            U1$T=t    A[U] ← A[T]
            TBt       A[T] ← B
            T):T;     T ← T + 1
        }{            else (do nothing)
        }?            end if
        U):U;         U ← U + 1
    }?                end if
UN>!}g                ...while not (U > N)
p                     print representation of A
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.