Isi ruang kosong dengan mengisi ruang kosong

10

Tulis fungsi (seperti placeAt) yang mengambil larik integer non-negatif dan indeks yang merupakan integer non-negatif. Itu harus menempatkan 1 pada indeks yang diberikan, mungkin menggeser entri lain dengan satu tempat untuk mengosongkan tempat itu, dengan 0 berdiri untuk tempat kosong.

  • Jika entri pada indeks yang diinginkan adalah 0, isilah dengan 1.
  • Jika tidak, cari 0 terdekat di sebelah kiri indeks. Geser entri satu tempat tersisa ke 0 untuk memberi ruang, lalu isi indeks dengan 1.
  • Jika tidak ada 0 ke kiri, lakukan hal yang sama ke kanan.
  • Jika tidak ada yang mungkin (yaitu jika tidak ada 0), kembalikan array tidak berubah.

Item ini diindeks 0. Nama fungsi bisa apa saja yang Anda inginkan.

Contoh:

(Surat mewakili nilai integer positif.)

[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

Ini adalah tantangan kode golf. Entri terpendek pada akhir 9 hari menang.

eguney
sumber
4
Bagaimana Anda tahu apakah akan bergeser ke kiri atau ke kanan saat keduanya memungkinkan? Juga, bagaimana jika tidak ada 0?
xnor
Karena [0, 2, 0, 2] placeAt 3, apakah itu legal untuk diproduksi [2, 0, 2, 1]? Apakah kode yang diperlukan untuk benar-benar menjadi fungsi yang disebut placeAt? Perhatikan bahwa beberapa bahasa tidak memiliki fungsi. "Melempar pengecualian" mungkin juga tidak berlaku untuk beberapa bahasa; Saya sarankan mengizinkan output yang menunjukkan kesalahan.
xnor
Bisakah array memiliki nilai negatif?
Kade
Saya 99% yakin saya memahami niat OP dengan aturan tantangan ini, jadi saya telah mengatur ulang posnya (saat ini sedang dalam antrian) dan saya akan berusaha menjawab pertanyaan. eguneys, Anda dapat memperbaiki jawaban saya jika perlu.
ETHproduksi
@ xnatau Menggeser ke kiri selalu lebih disukai daripada menggeser ke kanan. Jika tidak ada 0, cukup kembalikan array asli. Selain itu, [2, 0, 2, 1]ini bukan keluaran legal, karena Anda harus selalu menggeser elemen sesedikit mungkin, dan Anda dapat memberi nama fungsi apa pun yang Anda inginkan.
ETHproduksi

Jawaban:

4

JavaScript (ES6), 85

Tes menjalankan cuplikan pada peramban apa pun yang mendukung EcmaScript 6 (terutama bukan Chrome, bukan MSIE. Saya menguji pada Firefox, Safari 9 dapat berjalan)

(Saya menemukan ini tanpa melihat jawaban lain, sekarang saya melihat ini sangat mirip dengan rink. Namun cukup pendek. Mungkin saya tidak akan mendapatkan banyak upvotes untuk yang satu ini)

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>

edc65
sumber
+1 karena saya baru tahu tentang operator koma, dan karena telah mengalahkan saya
rink.attendant.6
@ rink.attendant.6 tetapi penggunaan && untuk bergabung dengan Anda splicelebih baik daripada koma saya
edc65
3

Julia, 122 byte

Hanya implementasi spesifikasi yang naif untuk memulai sesuatu.

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)

Tidak Disatukan:

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
Alex A.
sumber
1

JavaScript (ES6), 98 byte

Cukup banyak pendekatan yang sama dengan jawaban CoffeeScript saya, tetapi saya melakukan hubungan arus pendek ke ekstrim untuk menyimpan returnpernyataan:

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

Penjelasan

Untuk lebih mudah dijelaskan, saya telah mengatur ulang kode saya sedikit:

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

Berikut ini beberapa informasi tentang evaluasi hubung singkat JS.

Demo

Saat ini demo ini hanya berfungsi di Firefox dan Edge karena penggunaan 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>

rink.attendant.6
sumber
Bagaimana cara kerjanya, tolong jelaskan.
eguneys
@eguneys Penjelasan ditambahkan
rink.attendant.6
tidak berfungsi untukf(['a', 'b', 0, 'c', 'd', 0], 2)
eguney
@eguneys Diperbaiki. Saya lupa bahwa CoffeeScript secara otomatis menambahkan satu ketika menggunakan irisan steno mereka [a..b].
rink.attendant.6
tidak berfungsi untukf(['a', 'b', 0, 'c', 'd', 0], 1)
eguney
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
tangan
sumber
Selamat datang di PPCG! Beberapa tip golf sederhana untuk Ruby: Anda tidak perlu lekukan apa pun, sehingga Anda dapat menyingkirkan semua ruang. Maka Anda juga tidak perlu titik koma, karena satu baris baru adalah jumlah byte yang sama. Metode panggilan di akhir pernyataan tidak perlu tanda kurung, jadi Anda bisa melakukannya, misalnya .rindex 0, menghemat satu byte setiap kali. Anda dapat juga menyimpan beberapa byte dengan menggunakan proc bukannya metode, yang bahkan tidak harus bernama: ->a,i{...}. If / elsif / elsif mungkin dapat dipersingkat dengan operator ternary bersarang ...?...:...?...:....
Martin Ender
Terima kasih banyak atas sarannya. Saya akan memeriksanya dan melihat apa yang bisa saya lakukan.
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

Contoh penggunaan:

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

Cara kerjanya: Membagi daftar input pada posisi yang diberikan ke bagian kiri a, elemen pada posisi itu sendiri xdan bagian kanan b. Jika ada di 0dalam a++x, buat ruang hingga pertama 0di kebalikan dari a++x. Jika ada di 0dalam x++b, buatlah ruang di sana. Jika tidak ada 0sama sekali, gabungkan semua bagian tidak berubah untuk mendapatkan daftar asli lagi.

nimi
sumber
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
rink.attendant.6
sumber
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

Hitung indeks nol yang akan dihapus dengan merangkai daftar terbalik hingga indeks penyisipan dengan bagian setelah indeks dalam urutan normal, kemudian temukan indeks nol pertama. Nol ditambahkan ke akhir untuk menghindari ValueErrorpengecualian ketika tidak ada nol yang ditemukan. Kemudian cukup hapus, masukkan dan kembali.

samgak
sumber
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

Penjelasan

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

Tes

> 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
> 
MickyT
sumber
0

C #, 265 byte

Golf (265 Karakter)

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

Dengan spasi putih dan lekukan

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

Seluruh Program

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

    }

}

Uji Kasus masukkan deskripsi gambar di sini

Merin Nakarmi
sumber
1
ini tidak berfungsi untuk([0, 'a', 'b', 0, 'c', 'd'], 2)
eguney
1
Anda dapat menyimpan beberapa karakter dengan menghapus semua spasi yang tidak perlu, misalnya String[] Q, int Puntuk String[]Q,int P.
ProgramFOX
Hai @ aguneys, terima kasih sudah menunjukkannya. Saya telah memodifikasi logika dan dengan demikian berfungsi untuk semua kasus pengujian Anda. Saya juga memperbarui gambar kasus uji. Penempatan dilakukan dengan benar, namun hasil pergeserannya berbeda.
Merin Nakarmi
Hai @ProgramFOX, terima kasih atas komentar Anda yang berharga. Saya menyimpan sekitar 10 karakter.
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;}}}

Lulus kasus uji yang diberikan, a adalah pointer ke array, l adalah panjang array (saya harap ini tidak memecahkan brief), i adalah indeks untuk memasukkan dan c digunakan secara internal. Mungkin dapat ditingkatkan dengan menggabungkan pencarian loop kiri dan kanan.

Contoh

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

Tidak disatukan

Terus terang, dan bukan trik apa pun selain deklarasi gaya 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;
            }
    }
}
David Wotherspoon
sumber