Ordinare una serie di numeri interi negativi, zero e positivi con una iterazione


9

Prendi una matrice di numeri interi che contengono numeri negativi, numeri positivi e zeri. Raggruppalo con una iterazione e posiziona in modo tale che tutti i numeri negativi vengano prima, seguiti da tutti gli zeri, seguiti da tutti i numeri positivi.

Esempio:

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

Nota che non è necessario che i numeri siano completamente ordinati: basta ordinare per segno.

Quindi, l'array finale sarà simile al seguente: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

Regole

  • È possibile utilizzare solo l'array di input e una quantità costante di memoria aggiuntiva (ovvero non è possibile creare altri array)
  • È possibile utilizzare solo un loop, che può essere eseguito solo tante volte quanto la lunghezza dell'array. Non è possibile utilizzare le funzioni integrate che nascondono alcun tipo di loop. Ciò include le funzioni di ordinamento integrate.
  • Il risultato dovrebbe essere nel formato che ho descritto

Il vincitore sarà la persona che invierà il codice più breve (conteggiato in byte) che modifica l'array iniziale in un formato corretto (come descritto sopra).



@PeterTaylor Thx, ora capisco qual è il compito!
randomra,

Esattamente questo codegolf.stackexchange.com/questions/504/… diverso dall'uso 1 iterazione e 1 limite dell'array.
Ottimizzatore

Le funzioni di ordinamento integrate non sono consentite, giusto?
KSFT,

1
@KSFT Le chiamate sort(...)non vanno bene poiché probabilmente fanno più di una iterazione.
Ionică Bizău,

Risposte:


3

C, 92

Questo potrebbe probabilmente essere ridotto di almeno 10 byte; ci sono molte espressioni che andranno sprecate.

Il primo argomento dovrebbe puntare all'inizio dell'array; il secondo dovrebbe puntare dopo la fine dell'array.

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

Non golfato con generatore di test casuale:

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

Ho provato questo in Code Blocks e non si compila, ci sono 3 errori. Con cosa hai compilato? x * non è definito e hai creato variabili prima di {.
bacchusbeale,

@bacchusbeale Puoi compilarlo con gcc nella modalità predefinita (C89). CodeBlocks non è un compilatore quindi non posso dire quale compilatore stai usando, ma funziona con gcc. Il motivo per cui potrebbe non funzionare con tutti i compilatori sono le dichiarazioni in stile K & R, che non sono conformi allo standard ANSI.
feersum

1

STATA 242

Segue esattamente la pagina di Wikipedia. Grazie @PeterTaylor

Accetta input come set di numeri separati da spazio da std in e output come tali da 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
}

1

Python 2: 116 byte

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

Questa è una traduzione golfistica di Python dello pseudo-codice della bandiera nazionale olandese.

Possibili 112 byte

Non sono sicuro, se questo è permesso. Crea un secondo array di dimensioni 3 (quantità costante di memoria aggiuntiva!).

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

Implementazione semplice dell'algoritmo nell'articolo di Wikipedia per il commento di Peter Taylor sulla domanda.

Si aspetta di trovare i dati in un array chiamato acome l'altra risposta C. n, pE zsono puntatori per l'inserimento di negativi e numeri positivi e zeri. ne psono presi come argomenti che puntano al primo e all'ultimo elemento dei dati.

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 byte

Prende i numeri come set separati da spazio o virgola da una finestra di dialogo di prompt e restituisce il risultato con una finestra di avviso.

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

La sintassi variabile relativamente dettagliata di PHP è un po 'dolorosa qui ...


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

Questo è un porto diretto dello pseudocodice wikipedia della bandiera nazionale olandese. Di seguito è come appare ungolf:

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

Esempio di utilizzo:

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

NB. Rebol matrici (blocchi) non usano virgole -[5 3 0 -6 2 0 5]

E se il suo OK lo avvolge in una funzione che prende un array e lo modifica in posizione, possiamo farlo scendere a 128 caratteri:

>> 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 effetti, se non fosse necessario restituire l'array (ad es. Solo modificare), è possibile radere un altro carattere.


0

C ++

Soluzione senza golf: n conta i negativi aggiunti al fronte dell'array. Per ogni elemento se scambio negativo con elemento in n, se scambio zero con elemento in n + 1, scambiare con l'ultimo elemento.

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

Ingresso: [5 3 4 0 -6 2 0 5]
Uscita:[-6 0 0 4 2 3 5 5]

Provalo su http://cjam.aditsu.net/

Spiegazione:

Questa è un'altra implementazione dell'algoritmo da Wikipedia, usando Tfor ie Ufor j(entrambi inizializzati automaticamente su 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.