負、ゼロ、正の整数の配列を1回の反復で順序付け


9

負の数、正の数、ゼロを含む整数の配列を取ります。1回の繰り返しでグループ化、すべての負の数値が最初に来て、その後にすべてのゼロが続き、その後にすべての正の数が続くようにします。

例:

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

数値は完全に並べ替える必要はないことに注意してください。符号で並べ替えるだけです。

したがって、最終的な配列は次のようになります。 -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

ルール

  • 入力配列と一定量の追加メモリのみを使用できます(つまり、これ以上配列を作成できません)
  • 使用できるループは1つだけで、配列の長さと同じ回数だけ実行できます。あらゆる種類のループを隠す組み込み関数を使用することはできません。これには、組み込みのソート関数が含まれます。
  • 結果は、私が説明した形式である必要があります

勝者は、最初の配列を正しい形式(上記のように)に変更する最短のコード(バイト単位)を送信する人です。



@PeterTaylor Thx、今私はタスクが何であるかを理解しています!
randomra

正確にこのcodegolf.stackexchange.com/questions/504/…は、1回の反復と1つの配列の制限の使用を除きます。
オプティマイザ

組み込みのソート関数は許可されていませんよね?
KSFT、2015年

1
@KSFT呼び出しsort(...)はおそらく複数回の反復を行うため、問題ありません。
IonicăBizău

回答:


3

C、92

これはおそらく少なくとも10バイト削減できます。無駄になる表現はたくさんあります。

最初の引数は配列の先頭を指す必要があります。2番目は、配列の末尾の後ろを指す必要があります。

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

ランダムテストジェネレーターでゴルフを楽しむ:

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

これをコードブロックで試しましたが、コンパイルされません。3つのエラーがあります。何をコンパイルしましたか?x *は定義されておらず、{の前に変数を作成しました。
bacchusbeale

@bacchusbealeデフォルト(C89)モードでgccを使用してコンパイルできます。CodeBlocksはコンパイラではないため、どのコンパイラを使用しているかわかりませんが、gccで動作します。すべてのコンパイラで機能しない可能性があるのは、ANSI標準に準拠していないK&Rスタイルの宣言だからです。
feersum

1

STATA 242

ウィキペディアのページを正確にたどります。ありがとう@PeterTaylor

入力をスペースで区切られた数値のセットとしてstd inから取得し、同様に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バイト

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

これは、オランダの国旗の疑似コードをPythonで翻訳したものです。

可能な112バイト

許可されているかどうかはわかりません。サイズ3の2番目の配列を作成します(一定量の追加メモリ!)。

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のコメントに従って、ウィキペディアの記事にあるアルゴリズムの簡単な実装。

a他のCの答えのように呼ばれる配列でデータを見つけることを期待しています。npおよびz負の数と正の数およびゼロを挿入するためのポインタです。nそしてp、データの最初と最後の要素を指している引数として取られています。

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バイト

プロンプトダイアログからスペース区切りまたはカンマ区切りのセットとして数値を取得し、アラートダイアログで結果を返します。

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の比較的冗長な変数構文は、ここでは少し苦痛です...


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

これは、オランダの国旗ウィキペディアの疑似コードの直接ポートです。以下は、それがゴルフのように見えない方法です:

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

使用例:

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

NB。Rebol配列(ブロック)はコンマを使用しません-[5 3 0 -6 2 0 5]

そして、そのOKがこれを、配列を取得して適切な場所に変更する関数にラップすると、128文字まで取得できます。

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

実際、配列を返す必要がない場合(つまり、変更するだけ)、あと1文字を削ることができます。


0

C ++

ゴルフではないソリューション:nは、アレイの前に追加されたネガをカウントします。各要素について、nの要素と負のスワップの場合、n + 1の要素とゼロのスワップの場合、最後の要素とスワップします。

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

入力:[5 3 4 0 -6 2 0 5]
出力:[-6 0 0 4 2 3 5 5]

http://cjam.aditsu.net/でお試しください

説明:

これは、wikipediaのアルゴリズムのもう1つの実装で、Tfor iUfor を使用していますj(両方とも自動的に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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.