Lấp đầy khoảng trống bằng cách điền vào chỗ trống


10

Viết hàm (chẳng hạn placeAt) lấy một mảng các số nguyên không âm và một chỉ mục là một số nguyên không âm. Nó nên đặt 1 tại chỉ mục đã cho, có thể dịch chuyển các mục khác theo một vị trí để bỏ trống vị trí đó, với 0 đứng cho các điểm trống.

  • Nếu mục nhập tại chỉ mục mong muốn là 0, hãy điền nó bằng 1.
  • Nếu không, hãy tìm 0 gần nhất bên trái của chỉ mục. Thay đổi các mục nhập một điểm còn lại vào 0 đó để tạo khoảng trống, sau đó điền chỉ mục bằng 1.
  • Nếu không có 0 ở bên trái, hãy làm tương tự bên phải.
  • Nếu không thể (nghĩa là nếu không có 0), trả về mảng không đổi.

Các mục được lập chỉ mục 0. Tên chức năng có thể là bất cứ điều gì bạn muốn.

Ví dụ:

(Chữ cái viết tắt cho bất kỳ giá trị nguyên dương nào.)

[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

Đây là một thử thách golf mã. Bài viết ngắn nhất vào cuối 9 ngày sẽ thắng.


4
Làm thế nào để bạn biết nên chuyển sang trái hay phải khi cả hai đều có thể? Ngoài ra, nếu không có thì 0sao?
xnor

Đối với [0, 2, 0, 2] placeAt 3, nó là hợp pháp để đầu ra [2, 0, 2, 1]? Là mã cần thiết để thực sự là một chức năng được gọi là placeAt? Lưu ý rằng một số ngôn ngữ không chính xác có chức năng. "Ném một ngoại lệ" cũng có thể không áp dụng cho một số ngôn ngữ; Tôi đề nghị cho phép một đầu ra chỉ ra lỗi.
xnor

Mảng có thể có giá trị âm?
Kade

Tôi chắc chắn 99% tôi hiểu ý định của OP với các quy tắc của thử thách này, vì vậy tôi đã sắp xếp lại bài đăng (nó đang trong hàng đợi ngay bây giờ) và tôi sẽ cố gắng trả lời các câu hỏi. eguneys, bạn có thể sửa bất kỳ câu trả lời nào của tôi nếu cần.
Sản phẩm ETH

@xnor Dịch chuyển sang trái luôn được ưu tiên hơn dịch chuyển sang phải. Nếu không có 0, chỉ cần trả về mảng ban đầu. Ngoài ra, [2, 0, 2, 1]không phải là một đầu ra hợp pháp, vì bạn phải luôn thay đổi càng ít yếu tố càng tốt và bạn có thể đặt tên cho hàm theo bất cứ điều gì bạn muốn.
Sản phẩm ETH

Câu trả lời:


4

JavaScript (ES6), 85

Thử nghiệm chạy đoạn mã trên bất kỳ trình duyệt tuân thủ EcmaScript 6 nào (đáng chú ý không phải Chrome không phải MSIE. Tôi đã thử nghiệm trên Firefox, Safari 9 có thể đi)

(Tôi đã tìm thấy điều này mà không cần xem bất kỳ câu trả lời nào khác, bây giờ tôi thấy nó rất giống với câu trả lời. Tuy nhiên, khá ngắn. Có lẽ tôi sẽ không nhận được nhiều lời khen ngợi cho câu trả lời này)

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 vì tôi mới biết về toán tử dấu phẩy và vì đã đánh bại tôi
rink.attguard.6

@ rink.attguard.6 nhưng việc bạn sử dụng && để tham gia splicetốt hơn dấu phẩy của tôi
edc65

3

Julia, 122 byte

Chỉ là một triển khai ngây thơ của thông số kỹ thuật để bắt đầu mọi thứ.

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)

Ung dung:

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 byte

Cách tiếp cận khá giống với câu trả lời CoffeeScript của tôi nhưng tôi bị đoản mạch đến mức cực đoan để lưu một returntuyên bố:

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

Giải trình

Để dễ giải thích hơn, tôi đã sắp xếp lại mã của mình một chút:

// 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
}

Dưới đây là một số thông tin về đánh giá ngắn mạch của JS.

Bản giới thiệu

Hiện tại bản demo này chỉ hoạt động trong Firefox và Edge do sử dụng 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>


Làm thế nào để làm việc này bạn có thể giải thích xin vui lòng.
eguneys

@eguneys Giải thích thêm
rink.attguard.6

nó không hoạt động chof(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys Đã sửa. Tôi quên rằng CoffeeScript tự động thêm một cái khi sử dụng lát cắt tốc ký của chúng [a..b].
rink.attguard.6

không hoạt động chof(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys

1

Ruby, 208 byte

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

Chào mừng đến với PPCG! Một số mẹo chơi gôn đơn giản cho Ruby: bạn không cần bất kỳ vết lõm nào, vì vậy bạn có thể thoát khỏi tất cả các khoảng trống. Sau đó, bạn cũng không cần dấu chấm phẩy, bởi vì một dòng mới có cùng số byte. Các cuộc gọi phương thức ở cuối câu lệnh không cần dấu ngoặc đơn, vì vậy bạn có thể thực hiện, ví dụ: .rindex 0lưu một byte mỗi lần. Bạn cũng có thể lưu một số byte bằng cách sử dụng Proc thay vì phương thức, thậm chí không phải đặt tên : ->a,i{...}. If / elsif / elsif có thể được rút ngắn với một toán tử ternary lồng nhau ...?...:...?...:....
Martin Ender

Cảm ơn rất nhiều cho lời khuyên tử tế. Tôi sẽ xem xét nó và xem những gì tôi có thể làm.
handrake

1

Haskell, 119 byte

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

Ví dụ sử dụng:

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

Cách thức hoạt động: Chia danh sách đầu vào tại vị trí đã cho thành phần bên trái a, phần tử tại vị trí xvà phần bên phải b. Nếu có một 0trong a++x, nhường chỗ lên đến đầu tiên 0trong sự đảo ngược của a++x. Nếu có một 0trong x++b, nhường chỗ đó. Nếu không có gì 0cả, hãy kết hợp tất cả các phần không thay đổi để lấy lại danh sách ban đầu.


0

CoffeeScript, 96 byte

f=(a,_)->a.splice((if~($=a.lastIndexOf 0,_)then $ else a.indexOf 0),1);a.splice(_,0,1)if 0in a;a

0

Python 2, 102 byte

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

Tính toán chỉ số của số 0 cần loại bỏ bằng cách ghép danh sách đảo ngược với chỉ số chèn với phần sau chỉ mục theo thứ tự bình thường, sau đó tìm chỉ số của số 0 đầu tiên. Số 0 được thêm vào cuối để tránh ValueErrortrường hợp ngoại lệ khi không tìm thấy số không. Sau đó chỉ cần xóa, chèn và trả lại.


0

R, 87 byte

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

Giải trình

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

Xét nghiệm

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

Chơi gôn (265 ký tự)

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+" ");}

Với khoảng trắng và vết lõm

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 + " ");
    }

Toàn bộ chương trình

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);

    }

}

Các trường hợp thử nghiệm nhập mô tả hình ảnh ở đây


1
điều này không hiệu quả với([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

1
Bạn có thể tiết kiệm một số ký tự bằng cách loại bỏ tất cả các khoảng trắng không cần thiết, ví dụ String[] Q, int Pđể String[]Q,int P.
Chương trìnhFOX

Xin chào @eguneys, cảm ơn bạn đã chỉ ra điều đó. Tôi đã sửa đổi logic và do đó hoạt động cho tất cả các trường hợp thử nghiệm của bạn. Tôi cũng đã cập nhật hình ảnh trường hợp thử nghiệm. Việc đặt được thực hiện chính xác, tuy nhiên kết quả thay đổi là khác nhau.
Merin Nakarmi

Xin chào @ProgramFOX, cảm ơn vì nhận xét có giá trị của bạn. Tôi đã lưu khoảng 10 ký tự.
Merin Nakarmi

0

C, 154 byte

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

Vượt qua các trường hợp kiểm tra đã cho, a là con trỏ tới mảng, l là chiều dài của mảng (tôi hy vọng điều này không phá vỡ tóm tắt), i là chỉ mục cho phần chèn và c được sử dụng bên trong. Có thể có thể được cải thiện bằng cách kết hợp tìm kiếm bên trái và bên phải cho các vòng lặp.

Thí dụ

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

Ung dung

Thẳng tiến, và không thực sự có bất kỳ thủ thuật nào ngoài tuyên bố kiểu 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;
            }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.