เติมช่องว่างโดยเติมช่องว่าง


10

เขียนฟังก์ชัน (เช่นplaceAt) ที่ใช้อาร์เรย์ของจำนวนเต็มไม่เป็นลบและดัชนีที่เป็นจำนวนเต็มลบ ควรวาง 1 ที่ดัชนีที่กำหนดอาจเปลี่ยนรายการอื่น ๆ โดยจุดเดียวเพื่อย้ายจุดนั้นโดยที่ 0 ยืนสำหรับจุดที่ว่างเปล่า

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

รายการมีการจัดทำดัชนี 0 ชื่อฟังก์ชั่นสามารถเป็นอะไรก็ได้ที่คุณต้องการ

ตัวอย่าง:

(ตัวอักษรหมายถึงค่าจำนวนเต็มบวกใด ๆ )

[a, b, 0, c, d, 0] placeAt 2    // output [a, b, 1, c, d, 0]    place 2 is 0, just fill
[a, b, 0, c, d, 0] placeAt 3    // output [a, b, c, 1, d, 0]    place 3 is filled, shift items left
[a, b, 0, c, d, 0] placeAt 0    // output [1, a, b, c, d, 0]    place 0 is filled, can't shift left, shift items right
[a, b, 0, c, d, 0] placeAt 1    // output [a, 1, b, c, d, 0]    place 1 is filled, can't shift left, shift items right
[0, a, b, 0, c, d, 0] placeAt 2 // output [a, b, 1, 0, c, d, 0] place 2 is filled, shift items left
[0, a, b, 0, c, d, 0] placeAt 4 // output [0, a, b, c, 1, d, 0] place 4 is filled, shift items left (notice you keep shifting up until a 0)
[0, 2, 0, 2] placeAt 3          // output [0, 2, 2, 1]          place 3 is filled, shift items left

นี่คือความท้าทายของรหัสกอล์ฟ ผลงานที่สั้นที่สุดในตอนท้ายของ 9 วันชนะ


4
คุณจะรู้ได้อย่างไรว่าจะเลื่อนไปทางซ้ายหรือขวาเมื่อเป็นไปได้ทั้งสองอย่าง? นอกจากนี้จะเกิดอะไรขึ้นถ้าไม่มี0?
xnor

สำหรับ[0, 2, 0, 2] placeAt 3, มันถูกกฎหมาย[2, 0, 2, 1]หรือไม่? จำเป็นต้องใช้รหัสในการเรียกใช้ฟังก์ชันจริงplaceAtหรือไม่ โปรดทราบว่าบางภาษาไม่มีฟังก์ชั่นแน่นอน "โยนข้อยกเว้น" อาจไม่มีผลกับบางภาษา ฉันขอแนะนำให้อนุญาตให้แสดงผลลัพธ์ข้อผิดพลาด
xnor

อาร์เรย์สามารถมีค่าลบได้หรือไม่?
Kade

ฉันแน่ใจว่า 99% ฉันเข้าใจความตั้งใจของ OP ด้วยกฎของการท้าทายนี้ดังนั้นฉันจึงจัดระเบียบโพสต์ใหม่ (อยู่ในคิวตอนนี้) และฉันจะพยายามตอบคำถาม เช่นคุณสามารถแก้ไขคำตอบของฉันได้ถ้าต้องการ
ETHproductions

@ xnor การเลื่อนไปทางซ้ายจะเป็นที่นิยมมากกว่าการเลื่อนขวา หากไม่มี 0 ให้คืนค่าอาร์เรย์เดิม นอกจากนี้ยัง[2, 0, 2, 1]ไม่ได้เป็นผลลัพธ์ทางกฎหมายตามที่คุณควรเปลี่ยนองค์ประกอบน้อยที่สุดเท่าที่จะทำได้และคุณสามารถตั้งชื่อฟังก์ชั่นสิ่งที่คุณต้องการ
ETHproductions

คำตอบ:


4

JavaScript (ES6), 85

ทดสอบการเรียกใช้ตัวอย่างข้อมูลบนเบราว์เซอร์ที่สอดคล้องกับ EcmaScript 6 (ไม่ใช่ Chrome ไม่ใช่ MSIE โดยเฉพาะฉันทดสอบบน Firefox, Safari 9 แล้ว)

(ฉันพบสิ่งนี้โดยไม่ได้ดูคำตอบอื่นใดตอนนี้ฉันเห็นว่ามันคล้ายกับลานสเก็ตมาก แต่ก็ค่อนข้างสั้นกว่าฉันอาจจะไม่ได้ upvotes มากมายสำหรับอันนี้)

F=(a,p,q=~a.lastIndexOf(0,p)||~a.indexOf(0))=>(q&&(a.splice(~q,1),a.splice(p,0,1)),a)

// Ungolfed
U=(a,p)=>{
  q = a.lastIndexOf(0, p)
  if (q < 0) q = a.indexOf(0)
  if (q >= 0) {
    a.splice(q, 1)
    a.splice(p, 0, 1)
  }
  return a
}  

// TEST
out=x=>O.innerHTML+=x+'\n';

[ [['a', 'b', 0, 'c', 'd', 0], 2, ['a', 'b', 1, 'c', 'd', 0]] // place 2 is 0, just fill
, [['a', 'b', 0, 'c', 'd', 0], 3, ['a', 'b', 'c', 1, 'd', 0]] // place 3 is filled, shift items left
, [['a', 'b', 0, 'c', 'd', 0], 0, [1, 'a', 'b', 'c', 'd', 0]] // place 0 is filled, can't shift left, shift items right
, [['a', 'b', 0, 'c', 'd', 0], 1, ['a', 1, 'b', 'c', 'd', 0]] // place 1 is filled, can't shift left, shift items right
, [[0, 'a', 'b', 0, 'c', 'd', 0], 2, ['a', 'b', 1, 0, 'c', 'd', 0]] // place 2 is filled, shift items left
, [[0, 'a', 'b', 0, 'c', 'd', 0], 4, [0, 'a', 'b', 'c', 1, 'd', 0]] // place 4 is filled, shift items left (notice you keep shifting up until a 0)
, [['a', 'b', 'c', 'd'], 2, ['a', 'b', 'c', 'd']] // impossible
, [[0, 2, 0, 2], 3, [0, 2, 2, 1]]] // place 3 is filled, shift items left
.forEach(t=>{
  i=t[0]+''
  r=F(t[0],t[1])+''
  k=t[2]+''
  out('Test ' + (r==k?'OK':'Fail') +'\nInput: '+i+' '+t[1]+'\nResult:'+r+'\nCheck: '+k+'\n')
})
<pre id=O></pre>


+1 เพราะฉันเพิ่งเรียนรู้เกี่ยวกับตัวดำเนินการคอมม่าและการตีฉัน
rink.attendant.6

@ rink.attendant.6 แต่การใช้ && เพื่อเข้าร่วมspliceนั้นดีกว่าเครื่องหมายจุลภาคของฉัน
edc65

3

Julia, 122 ไบต์

เพียงการใช้ข้อมูลจำเพาะอย่างไร้เดียงสาเพื่อเริ่มต้นสิ่งต่าง ๆ

f(x,i)=(i+=1;x[i]==0?(x[i]=1):i>2&&x[i-1]==0?(x[i-1]=x[i];x[i]=1):i<length(x)-1&&x[i+1]==0?(x[i+1]=x[i];x[i]=1):error();x)

Ungolfed:

function placeAt(x::Array, i::Int)
    # Make i 1-indexed
    i += 1

    # Shift and modify the array as necessary
    if x[i] == 0
        x[i] = 1
    elseif i > 2 && x[i-1] == 0
        x[i-1], x[i] = x[i], 1
    elseif i < length(x)-1 && x[i+1] == 0
        x[i+1], x[i] = x[i], 1
    else
        error()
    end

    # Return the modified array
    x
end

1

JavaScript (ES6), 98 ไบต์

วิธีการเดียวกันกับคำตอบ CoffeeScript ของฉันค่อนข้างมากแต่ฉันกำลังลัดเลาะไปสู่จุดสูงสุดเพื่อบันทึกreturnคำสั่ง:

f=(a,x)=>(~($=a.lastIndexOf(0,x))||~(_=a.indexOf(0,x)))&&a.splice(~$?$:_,1)&&a.splice(x,0,1)&&a||a

คำอธิบาย

เพื่ออธิบายได้ง่ายขึ้นฉันได้จัดเรียงโค้ดของฉันใหม่:

// Declare function f with two arguments: array and position
f = (a, x) => {
    // Take the part of the array from beginning to x and find the last 0
    $ = a.lastIndexOf(0, x)

    // Find the first 0 after position x
    _ = a.indexOf(0, x);

    // indexOf returns -1 if they aren't found
    // ~1 == 0 so I am checking if either $ or _ is truthy (zeros were found)
    if (~$ || ~_)
       // If zeros were found in the left, use that.
       // Otherwise use the found zero in the right.
       // Delete it from the array
       // Array.prototype.splice will return an array which evaluates to truthy
       // and continues execution with the &&
       // Insert value 1 at position x, deleting 0 elements
       // The last value is returned
       return a.splice(~$ ? $ : _, 1) && a.splice(x, 0, 1) && a
    else
       // No zeros were found so just return the original
       // In the golfed code the if would have evaluated to false to cut into the || part
       return a
}

นี่คือข้อมูลบางอย่างเกี่ยวกับการประเมินการลัดวงจรของ JS

การสาธิต

ในขณะนี้การสาธิตนี้ใช้ได้เฉพาะใน Firefox และ Edge เนื่องจากการใช้ ES6:

f=(a,x)=>(~($=a.lastIndexOf(0,x))||~(_=a.indexOf(0,x)))&&a.splice(~$?$:_,1)&&a.splice(x,0,1)&&a||a

// Snippet stuff
console.log = x => O.innerHTML += x + '\n';

console.log(f(['a', 'b', 0, 'c', 'd', 0], 2))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 3))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 0))
console.log(f([0, 'a', 'b', 0, 'c', 'd', 0], 2))
console.log(f([0, 'a', 'b', 0, 'c', 'd', 0], 4))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 2))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 1))
<pre id=O></pre>


คุณอธิบายได้อย่างไร
eguneys

@eguneys เพิ่มคำอธิบาย
rink.attendant.6

มันใช้งานไม่ได้f(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys แก้ไขแล้ว ฉันลืมที่จะเพิ่ม CoffeeScript [a..b]หนึ่งเมื่อมีการใช้ชิ้นจดชวเลขของพวกเขา
rink.attendant.6

ไม่ทำงานf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys

1

ทับทิม, 208 ไบต์

def f(a,i)
  x=a.take(i).rindex(0);y=a[i+1..-1].index(0)
  if a[i]==0
    a[i]=1
  elsif !x.nil?
    a.delete_at(x);a.insert(i,1)
  elsif !y.nil?
    a.delete_at(y+i+1);a.insert(i,1)
  end
  a
end

ยินดีต้อนรับสู่ PPCG! เคล็ดลับการตีกอล์ฟง่ายๆสำหรับ Ruby คุณไม่จำเป็นต้องมีการเยื้องเพื่อให้คุณสามารถกำจัดช่องว่างทั้งหมดได้ จากนั้นคุณไม่จำเป็นต้องใช้เครื่องหมายอัฒภาคเนื่องจากบรรทัดใหม่หนึ่งบรรทัดมีจำนวนไบต์เท่ากัน การเรียกเมธอดที่ท้ายคำสั่งไม่จำเป็นต้องใส่วงเล็บดังนั้นคุณสามารถทำได้เช่น.rindex 0บันทึกหนึ่งไบต์ในแต่ละครั้ง นอกจากนี้คุณยังสามารถบันทึกไบต์บางอย่างโดยใช้ proc ->a,i{...}แทนวิธีการซึ่งไม่ได้จะต้องมีการตั้งชื่อ: if / elsif / elsif อาจสั้นลงด้วยตัวดำเนินการประกอบ...?...:...?...:...หลายระดับ
Martin Ender

ขอบคุณมากสำหรับคำแนะนำที่ดี ฉันจะตรวจสอบและดูสิ่งที่ฉันสามารถทำได้
handrake

1

Haskell, 119 ไบต์

e=elem 0
r=reverse
f=(g.).splitAt
g(a,y@(x:b))|e(x:a)=r(h(x:r a)1)++b|e y=a++h y 1|1<2=a++y 
h(0:r)n=n:r
h(a:r)n=n:h r a

ตัวอย่างการใช้งาน:

*Main> mapM_ (print.uncurry f) [ 
                (2,[2,3,0,4,5,0]),
                (3,[2,3,0,4,5,0]),
                (0,[2,3,0,4,5,0]),
                (1,[2,3,0,4,5,0]),
                (2,[0,2,3,0,4,5,0]),
                (4,[0,2,3,0,4,5,0]),
                (3,[0,2,0,2]),
                (2,[2,3,4,5])  ]
[2,3,1,4,5,0]
[2,3,4,1,5,0]
[1,2,3,4,5,0]
[2,1,3,4,5,0]
[2,3,1,0,4,5,0]
[0,2,3,4,1,5,0]
[0,2,2,1]
[2,3,4,5]

วิธีการทำงาน: Split รายการป้อนข้อมูลในตำแหน่งที่กำหนดลงในส่วนด้านซ้ายaองค์ประกอบที่ตำแหน่งของตัวเองและเป็นส่วนหนึ่งที่เหมาะสมx bหากมีสิ่งใดสิ่งหนึ่ง0อยู่ภายใน a++xให้กลับไป0อยู่ด้านหลังa++xก่อน หากมีสิ่งใดสิ่งหนึ่ง0อยู่ภายในx++bให้จัดเตรียมที่นั่น หากไม่มี0เลยให้รวมทุกส่วนที่ไม่เปลี่ยนแปลงเพื่อรับรายการต้นฉบับอีกครั้ง



0

Python 2, 102 ไบต์

def f(a,i):
 x=(a[i-1::-1]+a[i:]+[0]).index(0)
 if x<len(a):del a[(x,i-x-1)[x<i]];a[i:i]=[1]
 return a

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


0

R, 87 ไบต์

f=function(a,i)if(0%in%a)append(a[-abs(min((b=which(a==0))*(1-(b<=i+1)*2)))],1,i)else a

คำอธิบาย

function(a,i)
if(0%in%a)                      # as long as a 0 exists
    append(                     # append 1 after i
        a[
          -abs(                 # remove absolute of min index
            min(                # minimum of adjusted index
              (b=which(a==0))*  # index of all 0's
              (1-(b<=i+1)*2)    # multiple -1 if <= i
              )
            )
        ]
        ,1
        ,i
    )
else                            # otherwise return untouched
    a

การทดสอบ

> f(c(2, 3, 0, 4, 5, 0) , 2)   
[1] 2 3 1 4 5 0
> f(c(2, 3, 0, 4, 5, 0) , 3)   
[1] 2 3 4 1 5 0
> f(c(2, 3, 0, 4, 5, 0) , 0)   
[1] 1 2 3 4 5 0
> f(c(2, 3, 0, 4, 5, 0) , 1)   
[1] 2 1 3 4 5 0
> f(c(0, 2, 3, 0, 4, 5, 0) , 2)
[1] 2 3 1 0 4 5 0
> f(c(0, 2, 3, 0, 4, 5, 0) , 4)
[1] 0 2 3 4 1 5 0
> f(c(0, 2, 0, 2) , 3)         
[1] 0 2 2 1
> 

0

C #, 265 ไบต์

Golfed (265 ตัวอักษร)

static void placeAt(String[]Q,int P){int I;if(Q[P]=="0"){Q[P]="1";}else{I=Array.IndexOf(Q,"0");if(I>=0){if(I<P){for(int i=I;i<=P;i++){Q[i]=(i==P)?"1":Q[i+1];}}else if(I>P){for(int i=I;i>=P;i--){Q[i]=(i==P)?"1":Q[i-1];}}}}foreach(String s in Q)Console.Write(s+" ");}

ด้วยช่องว่างสีขาวและเยื้อง

static void placeAt(String[] Q, int P)
    {
        int I;

        if(Q[P] == "0")
        {
            Q[P] = "1";
        }
        else
        {
            I = Array.IndexOf(Q, "0");
            if (I >= 0)
            {
                if (I < P)
                {
                    for (int i = I; i <= P; i++)
                    {
                        Q[i] = (i == P) ? "1" : Q[i + 1];
                    }
                }
                else if (I > P)
                {
                    for (int i = I; i >= P; i--)
                    {
                        Q[i] = (i == P) ? "1" : Q[i - 1];
                    }
                }
            }
        }

        foreach (String s in Q)
            Console.Write(s + " ");
    }

โปรแกรมทั้งหมด

using System;

class FillZero
{
    static void placeAt(String[] Q, int P)
    {
        int I;

        if(Q[P] == "0")
        {
            Q[P] = "1";
        }
        else
        {
            I = Array.IndexOf(Q, "0");
            if (I >= 0)
            {
                if (I < P)
                {
                    for (int i = I; i <= P; i++)
                    {
                        Q[i] = (i == P) ? "1" : Q[i + 1];
                    }
                }
                else if (I > P)
                {
                    for (int i = I; i >= P; i--)
                    {
                        Q[i] = (i == P) ? "1" : Q[i - 1];
                    }
                }
            }
        }

        foreach (String s in Q)
            Console.Write(s + " ");
    }

    static void Main()
    {
        String[] X = {"a", "b", "0", "c", "d", "0"};
        placeAt(X , 1);

    }

}

กรณีทดสอบ ป้อนคำอธิบายรูปภาพที่นี่


1
สิ่งนี้ใช้ไม่ได้([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

1
คุณสามารถบันทึกตัวอักษรบางส่วนโดยการลบช่องว่างที่ไม่จำเป็นทั้งหมดเช่นการString[] Q, int P String[]Q,int P
ProgramFOX

สวัสดี @eguneys ขอบคุณที่ชี้ให้เห็น ฉันได้แก้ไขตรรกะแล้วจึงเหมาะสำหรับกรณีทดสอบทั้งหมดของคุณ ฉันได้อัปเดตภาพกรณีทดสอบด้วย การวางทำได้อย่างถูกต้องอย่างไรก็ตามผลลัพธ์การเลื่อนจะแตกต่างกัน
Merin Nakarmi

สวัสดี @ProgramFOX ขอขอบคุณสำหรับความคิดเห็นที่มีค่าของคุณ ฉันบันทึกอักขระได้ 10 ตัว
Merin Nakarmi

0

C, 154 ไบต์

p(a,l,i,c)int*a;{for(c=i;c+1;c--){if(!a[c]){for(;c<i;c++)a[c]=a[c+1];return a[i]=1;}}for(c=i;c<l;c++){if(!a[c]){for(;c>i;c--)a[c]=a[c-1];return a[i]=1;}}}

ผ่านกรณีทดสอบที่กำหนดaคือตัวชี้ไปยังอาร์เรย์lคือความยาวของอาร์เรย์ (ฉันหวังว่านี่จะไม่ทำลายช่วงสั้น ๆ ) iคือดัชนีสำหรับส่วนแทรกและcถูกใช้ภายใน อาจปรับปรุงได้โดยรวมการค้นหาลูปซ้ายและขวาเข้าด้วยกัน

ตัวอย่าง

int main(int argc, char * argv[]) {
    int a[] = {0, 2, 0, 2};
    p(a, 4, 3);
}

Ungolfed

ตรงไปข้างหน้าและไม่ได้มีเทคนิคใด ๆ เลยนอกจากการประกาศสไตล์ K&R

p(a,l,i,c) int *a; {
    /* Search left from i (also handles a[i] == 0) */
    for (c=i;c+1;c--) {
            if (!a[c]) {
                    /* Shift items left until i */ 
                    for (;c<i;c++) a[c]=a[c+1];
                    return a[i]=1;
            }
    }
    /* Search right from i */
    for (c=i;c<l;c++) {
            if(!a[c]) {
                    /* Shift items right until i */
                    for(;c>i;c--) a[c]=a[c-1]; 
                    return a[i]=1;
            }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.