Ordnen eines Arrays von Negativ-, Null- und Positiv-Ganzzahlen mit einer Iteration

9

Nehmen Sie ein Array von ganzen Zahlen, die negative Zahlen, positive Zahlen und Nullen enthalten. Gruppieren Sie es mit einer Iteration und an Ort und Stelle , sodass alle negativen Zahlen an erster Stelle stehen, gefolgt von allen Nullen, gefolgt von allen positiven Zahlen.

Beispiel:

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

Beachten Sie, dass die Zahlen nicht vollständig sortiert werden müssen: nur nach Vorzeichen sortiert.

Das endgültige Array sieht also folgendermaßen aus: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

Regeln

  • Sie dürfen nur das Eingabearray und eine konstante Menge zusätzlichen Speichers verwenden (dh Sie dürfen keine weiteren Arrays erstellen).
  • Sie dürfen nur eine Schleife verwenden, die möglicherweise nur so oft ausgeführt wird wie die Länge des Arrays. Sie dürfen keine integrierten Funktionen verwenden, die Schleifen jeglicher Art verbergen. Dies beinhaltet integrierte Sortierfunktionen.
  • Das Ergebnis sollte das von mir beschriebene Format haben

Der Gewinner ist die Person, die den kürzesten Code (in Bytes gezählt) übermittelt, der das ursprüngliche Array in ein korrektes Format ändert (wie oben beschrieben).

Ionică Bizău
quelle
6
Aka das niederländische Nationalflaggenproblem .
Peter Taylor
@ PeterTaylor Thx, jetzt verstehe ich was die Aufgabe ist!
Randomra
Genau dieses codegolf.stackexchange.com/questions/504/… außer der Verwendung von 1 Iteration und 1 Array-Limit.
Optimierer
Eingebaute Sortierfunktionen sind nicht erlaubt, oder?
KSFT
1
@KSFT Das Aufrufen sort(...)ist nicht in Ordnung, da es wahrscheinlich mehr als eine Iteration ausführt .
Ionică Bizău

Antworten:

3

C 92

Dies könnte wahrscheinlich um mindestens 10 Bytes reduziert werden; Es gibt viele Ausdrücke, die verschwendet werden.

Das erste Argument sollte auf den Anfang des Arrays verweisen. Die zweite sollte nach dem Ende des Arrays zeigen.

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

Ungolfed mit Zufallstestgenerator:

*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
quelle
Ich habe dies in Codeblöcken versucht und es wird nicht kompiliert, es gibt 3 Fehler. Womit hast du kompiliert? x * ist nicht definiert und Sie haben Variablen vor {erstellt.
Bacchusbeale
@bacchusbeale Sie können es mit gcc im Standardmodus (C89) kompilieren. CodeBlocks ist kein Compiler, daher kann ich nicht sagen, welchen Compiler Sie verwenden, aber er funktioniert mit gcc. Der Grund, warum es möglicherweise nicht mit allen Compilern funktioniert, sind Deklarationen im K & R-Stil, die nicht dem ANSI-Standard entsprechen.
Feersum
1

STATA 242

Folgt genau der Wikipedia-Seite. Danke @PeterTaylor

Nimmt die Eingabe als durch Leerzeichen getrennte Menge von Zahlen von std in und Ausgaben als solche auch als std out.

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
}
bmarks
quelle
1

Python 2: 116 Bytes

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

Dies ist eine Golf-Python-Übersetzung des Pseudocodes der niederländischen Nationalflagge.

Mögliche 112 Bytes

Ich bin mir nicht sicher, ob dies erlaubt ist. Es wird ein zweites Array der Größe 3 erstellt (konstante Menge an zusätzlichem Speicher!).

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
quelle
1

C 90

Einfache Implementierung des Algorithmus im Wikipedia-Artikel gemäß Peter Taylors Kommentar zur Frage.

Erwartet, die Daten in einem Array zu finden, das awie die andere C-Antwort aufgerufen wird . n, pUnd zsind Zeiger für die Insertion von negativen und positiven Zahlen und Nullen. nund pwerden als Argumente verwendet, die auf das erste und das letzte Element der Daten verweisen.

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.
quelle
1

ECMAScript 157 Bytes

Nimmt die Zahlen als durch Leerzeichen oder Kommas getrennte Menge aus einem Eingabeaufforderungsdialog und gibt das Ergebnis mit einem Warnungsdialog zurück.

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

Die relativ ausführliche Variablensyntax von PHP ist hier etwas schmerzhaft ...

Stephen
quelle
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

Dies ist ein direkter Hafen des Wikipedia-Pseudocodes der niederländischen Nationalflagge. Unten ist, wie es ungolfed aussieht:

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

Anwendungsbeispiel:

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

NB. Rebol-Arrays (Blöcke) verwenden keine Kommas -[5 3 0 -6 2 0 5]

Und wenn es in Ordnung ist, dies in eine Funktion zu packen, die ein Array übernimmt und es an Ort und Stelle ändert, können wir es auf 128 Zeichen reduzieren:

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

In der Tat, wenn Sie kein Array zurückgeben müssen (dh nur ändern), können Sie 1 weiteres Zeichen rasieren.

draegtun
quelle
0

C ++

Nicht-Golf-Lösung: n zählt die Negative, die vor dem Array hinzugefügt wurden. Für jedes Element, wenn negativ mit Element bei n tauschen, wenn Null mit Element bei n + 1 tauschen, sonst mit letztem Element tauschen.

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
quelle
0

CJam - 72 67

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

Eingabe: [5 3 4 0 -6 2 0 5]
Ausgabe:[-6 0 0 4 2 3 5 5]

Probieren Sie es unter http://cjam.aditsu.net/ aus.

Erläuterung:

Dies ist eine weitere Implementierung des Algorithmus aus Wikipedia, der Tfor iund Ufor verwendet j(beide werden automatisch auf 0 initialisiert).

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 beenden, weil SE böse ist
quelle