การสั่งซื้ออาร์เรย์เชิงลบจำนวนเต็มศูนย์และบวกด้วยการวนซ้ำหนึ่งครั้ง


9

ใช้อาร์เรย์ของจำนวนเต็มที่มีจำนวนลบจำนวนบวกและเลขศูนย์ จัดกลุ่มมันด้วยการวนซ้ำหนึ่งครั้งและอยู่ในตำแหน่งที่จำนวนลบทั้งหมดมาก่อนตามด้วยศูนย์ทั้งหมดตามด้วยตัวเลขบวกทั้งหมด

ตัวอย่าง:

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

โปรดทราบว่าตัวเลขไม่จำเป็นต้องถูกจัดเรียงอย่างสมบูรณ์เพียงแค่เรียงตามเครื่องหมาย

ดังนั้นอาร์เรย์สุดท้ายจะมีลักษณะดังนี้: -, -, ..., -, -, 0, 0, ..., 0, 0, +, +, ..., +, +

กฎระเบียบ

  • คุณสามารถใช้อาร์เรย์อินพุตและหน่วยความจำเพิ่มเติมจำนวนคงที่เท่านั้น (เช่นคุณไม่สามารถสร้างอาร์เรย์ได้อีก)
  • คุณสามารถใช้หนึ่งวงเท่านั้นซึ่งอาจดำเนินการได้หลายครั้งตามความยาวของอาร์เรย์ คุณไม่สามารถใช้ฟังก์ชั่นในตัวที่ปิดบังการวนลูปได้ทุกชนิด ซึ่งรวมถึงฟังก์ชั่นการเรียงลำดับในตัว
  • ผลลัพธ์ควรอยู่ในรูปแบบที่ฉันอธิบาย

ผู้ชนะจะเป็นคนที่จะส่งรหัสที่สั้นที่สุด (นับเป็นไบต์) ที่เปลี่ยนอาร์เรย์เริ่มต้นเป็นรูปแบบที่ถูกต้อง (เช่นที่อธิบายข้างต้น)


6
อาคาปัญหาธงชาติดัตช์
ปีเตอร์เทย์เลอร์

@ PeterTaylor ขอบคุณตอนนี้ฉันเข้าใจว่างานคืออะไร!
randomra

codegolf.stackexchange.com/questions/504/…นี้นอกเหนือจากการใช้ซ้ำ 1 ครั้งและ 1 อาเรย์ จำกัด
เครื่องมือเพิ่มประสิทธิภาพ

ไม่อนุญาตให้ใช้ฟังก์ชั่นการเรียงลำดับในตัวใช่ไหม?
KSFT

1
@KSFT การโทรsort(...)ไม่ถูกต้องเนื่องจากอาจทำซ้ำได้มากกว่าหนึ่งครั้ง
IonicăBizău

คำตอบ:


3

C, 92

อาจลดลงอย่างน้อย 10 ไบต์ มีการแสดงออกมากมายที่จะทำให้เสีย

อาร์กิวเมนต์แรกควรชี้ไปที่จุดเริ่มต้นของอาร์เรย์ ที่สองควรชี้ไปหลังจากจุดสิ้นสุดของอาร์เรย์

*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 กับเครื่องกำเนิดไฟฟ้าทดสอบแบบสุ่ม:

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

ฉันลองสิ่งนี้ใน Code Blocks และมันไม่ได้คอมไพล์มีข้อผิดพลาด 3 ข้อ สิ่งที่คุณคอมไพล์ด้วย? x * ไม่ได้กำหนดไว้และคุณสร้างตัวแปรก่อนหน้า {.
bacchusbeale

@bacchusbeale คุณสามารถรวบรวมกับ gcc ในโหมดเริ่มต้น (C89) CodeBlocks ไม่ใช่คอมไพเลอร์ดังนั้นฉันจึงไม่สามารถบอกได้ว่าคอมไพเลอร์ตัวใดที่คุณใช้ แต่มันใช้ได้กับ gcc เหตุผลที่อาจใช้ไม่ได้กับคอมไพเลอร์ทั้งหมดคือการประกาศ K & R-style ซึ่งไม่สอดคล้องกับมาตรฐาน ANSI
feersum

1

สถานะ 242

ติดตามหน้าวิกิพีเดียทุกประการ ขอบคุณ @PeterTaylor

ใช้อินพุตเป็นช่องว่างคั่นจำนวนของตัวเลขจาก std in และ output เช่นเดียวกับ 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 ของ golfed ของรหัสหลอกธงชาติดัตช์

เป็นไปได้ 112 ไบต์

ไม่แน่ใจหากได้รับอนุญาต มันสร้างอาร์เรย์ขนาดที่สอง 3 (จำนวนหน่วยความจำเพิ่มเติมคงที่!)

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 อื่น ๆ n, pและ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 ค่อนข้างละเอียด verbose ค่อนข้างเจ็บปวดที่นี่ ...


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

นี่คือพอร์ตโดยตรงของ pseudocode วิกิพีเดียธงชาติดัตช์ ด้านล่างนี้เป็นรูปลักษณ์ที่ไม่สวยงาม

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]

และถ้ามันมีโอเคห่อสิ่งนี้เข้าไปในฟังก์ชั่นซึ่งรับอาเรย์แล้วดัดแปลงมันให้เข้าที่เราจะได้มันลงไปที่ 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/

คำอธิบาย:

นี่คือการใช้อัลกอริทึมอื่นจากวิกิพีเดียโดยใช้TสำหรับiและUเพื่อ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.