Zamawianie tablicy liczb całkowitych ujemnych, zerowych i dodatnich za pomocą jednej iteracji

9

Weź tablicę liczb całkowitych zawierających liczby ujemne, liczby dodatnie i zera. Zgrupuj go z jedną iteracją, tak aby wszystkie liczby ujemne były pierwsze, a następnie wszystkie zera, a następnie wszystkie liczby dodatnie.

Przykład:

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

Pamiętaj, że liczby nie muszą być w pełni posortowane: wystarczy posortować według znaku.

Tak więc końcowa tablica będzie wyglądać następująco: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

Zasady

  • Możesz używać tylko tablicy wejściowej i stałej ilości dodatkowej pamięci (tzn. Nie możesz już tworzyć więcej tablic)
  • Możesz użyć tylko jednej pętli, która może wykonać się tyle razy, ile wynosi długość tablicy. Nie możesz używać wbudowanych funkcji, które ukrywają jakąkolwiek pętlę. Obejmuje to wbudowane funkcje sortowania.
  • Wynik powinien być w formacie, który opisałem

Zwycięzcą zostanie osoba, która prześle najkrótszy kod (liczony w bajtach), który zmienia początkową tablicę na poprawny format (jak opisano powyżej).

Ionică Bizău
źródło
@PeterTaylor Thx, teraz rozumiem, jakie jest zadanie!
randomra
Dokładnie ten codegolf.stackexchange.com/questions/504/... inny niż użycie 1 iteracji i 1 limit tablicy.
Optymalizator
Wbudowane funkcje sortowania są niedozwolone, prawda?
KSFT,
1
@KSFT Połączenia sort(...)nie są w porządku, ponieważ prawdopodobnie wykonują więcej niż jedną iterację.
Ionică Bizău

Odpowiedzi:

3

C 92

Prawdopodobnie można to zmniejszyć o co najmniej 10 bajtów; wiele wyrażeń marnuje się.

Pierwszy argument powinien wskazywać na początek tablicy; drugi powinien wskazywać za końcem tablicy.

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

Niegolfowany z generatorem losowych testów:

*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;
}
feersum
źródło
Próbowałem tego w Code Blocks i nie można go skompilować, są 3 błędy. Z czym się skompilowałeś? x * nie jest zdefiniowany, a zmienne wykonano przed {.
bacchusbeale
@ bacchusbeale Możesz skompilować go za pomocą gcc w domyślnym trybie (C89). CodeBlocks nie jest kompilatorem, więc nie wiem, którego kompilatora używasz, ale działa z gcc. Powodem, dla którego może nie działać ze wszystkimi kompilatorami, są deklaracje w stylu K&R, które nie są zgodne ze standardem ANSI.
feersum
1

STATA 242

Śledzi dokładnie stronę wikipedii. Dzięki @PeterTaylor

Pobiera dane wejściowe jako oddzielony spacjami zestaw liczb od standardowego wejścia i wyjściowego jako takiego, a także do standardowego wyjścia.

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
}
znaczniki
źródło
1

Python 2: 116 bajtów

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

To jest golfowe tłumaczenie pseudo-kodu holenderskiej flagi narodowej w języku Python.

Możliwe 112 bajtów

Nie jestem pewien, czy jest to dozwolone. Tworzy drugą tablicę o rozmiarze 3 (stała ilość dodatkowej pamięci!).

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
Jakube
źródło
1

C, 90

Prosta implementacja algorytmu w artykule na Wikipedii zgodnie z komentarzem Petera Taylora do pytania.

Oczekuje znalezienia danych w tablicy o nazwie apodobnej do drugiej odpowiedzi C. n, pi zsą wskaźnikami do wstawiania liczb ujemnych i dodatnich oraz zer. ni psą traktowane jako argumenty wskazujące na pierwszy i ostatni element danych.

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;}
Level River St
źródło
1

ECMAScript 157 bajtów

Pobiera liczby jako rozdzielone spacjami lub oddzielone przecinkami z okna dialogowego monitu i zwraca wynik w oknie dialogowym alertu.

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);
fxdapokalypse
źródło
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

Stosunkowo pełna składnia zmiennych PHP jest tutaj trochę bolesna ...

Stephen
źródło
0

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

Jest to bezpośredni port pseudokodu wikipedia holenderskiej flagi narodowej. Poniżej wygląda na to, że nie jest golfem:

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

Przykład użycia:

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

NB Tablice Rebol (bloki) nie używają przecinków -[5 3 0 -6 2 0 5]

A jeśli będzie OK, zawiń to w funkcję, która pobiera tablicę i modyfikuje ją w miejscu, możemy sprowadzić ją do 128 znaków:

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

W rzeczywistości, jeśli nie trzeba było zwracać tablicy (tj. Po prostu modyfikować), możesz ogolić jeszcze 1 znak.

draegtun
źródło
0

C ++

Rozwiązanie bez gry w golfa: n zlicza negatywy dodane z przodu tablicy. Dla każdego elementu w przypadku zamiany ujemnej z elementem w punkcie n, w przypadku zamiany zera z elementem w punkcie n + 1, w przeciwnym przypadku z ostatnim elementem.

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;
}
Bacchusbeale
źródło
0

CJam - 72 67

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

Wejście: [5 3 4 0 -6 2 0 5]
Wyjście:[-6 0 0 4 2 3 5 5]

Wypróbuj na http://cjam.aditsu.net/

Wyjaśnienie:

Jest to kolejna implementacja algorytmu z wikipedii, wykorzystująca Tfor ii Ufor j(oba automatycznie inicjowane na 0).

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
aditsu przestało działać, ponieważ SE jest ZŁEM
źródło