Boş alanları doldurarak boş alanları doldurun


10

placeAtNegatif olmayan bir tamsayı dizisi ve negatif olmayan bir tamsayı olan bir dizin alan bir işlev (örneğin ) yazın . Verilen indekse 1 koymalı, muhtemelen o noktayı boşaltmak için diğer girişleri bir noktaya kaydırmalı, 0'lar boş noktalar için duruyor.

  • İstenen dizindeki giriş 0 ise, 1 ile doldurun.
  • Aksi takdirde, dizinin solunda en yakın 0 değerini bulun. Yer açmak için girişleri bir nokta sola 0 kaydırın, ardından dizini 1 ile doldurun.
  • Solda 0 yoksa, aynı işlemi sağa doğru yapın.
  • İkisi de mümkün değilse (yani 0 yoksa), diziyi değiştirmeden döndürün.

Öğeler 0 dizinlidir. İşlev adı istediğiniz herhangi bir şey olabilir.

Örnekler:

(Harfler pozitif tamsayı değerlerini ifade eder.)

[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

Bu bir kod golf meydan okumadır. 9 günün sonunda en kısa katılım kazanır.


4
Her ikisi de mümkün olduğunda sola mı yoksa sağa mı kaydıracağınızı nasıl anlarsınız? Ayrıca, ya yok ise 0?
xnor

Çünkü [0, 2, 0, 2] placeAt 3çıktı almak yasal [2, 0, 2, 1]mı? Kodun aslında bir işlev olması için gerekli placeAtmi? Bazı dillerin tam olarak işlevleri olmadığını unutmayın. "Bir istisna atın" bazı diller için geçerli olmayabilir; Hata gösteren bir çıktıya izin vermenizi öneririm.
xnor

Dizinin negatif değerleri olabilir mi?
Kade

OP'nin bu zorluğun kurallarıyla niyetlerini anladığımdan% 99 eminim, bu yüzden yazıyı yeniden düzenledim (şu anda kuyrukta) ve soruları cevaplamaya çalışacağım. eguneys, gerekirse cevaplarımı düzeltebilirsiniz.
ETHproductions 15:06

@xnor Sola kaydırma her zaman sağa kaydırma tercihini tercih eder. 0 yoksa, orijinal diziyi döndürmeniz yeterlidir. Ayrıca, [2, 0, 2, 1]yasal bir çıktı değildir, çünkü her zaman mümkün olduğunca az sayıda öğeyi kaydırmanız gerekir ve işlevi istediğiniz gibi adlandırabilirsiniz.
ETHproductions 15:07

Yanıtlar:


4

JavaScript (ES6), 85

Parçacığı herhangi bir EcmaScript 6 uyumlu tarayıcıda çalıştırmayı test edin (özellikle Chrome MSIE değil. Firefox'ta test ettim, Safari 9 gidebilir)

(Bunu diğer cevapların hiçbirine bakmadan buldum, şimdi pistlere çok benzediğini görüyorum. Yine de daha kısa. Muhtemelen bunun için çok fazla oy almam)

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 çünkü virgül operatörünü yeni öğrendim ve beni
dövdüğüm

@ rink.attendant.6 ama katılmak için && kullanmanız virgülümden splicedaha iyidir
edc65

3

Julia, 122 bayt

Sadece şeyleri başlatmak için özel bir uygulama.

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 bayt

CoffeeScript yanıtımla hemen hemen aynı yaklaşım ama bir returnifadeyi kaydetmek için uç noktaya kısa devre yapıyorum :

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

açıklama

Daha kolay açıklamak için, kodumu biraz yeniden düzenledim:

// 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 kısa devre değerlendirmesi hakkında bazı bilgiler .

gösteri

Şu anda bu demo sadece ES6 kullanımı nedeniyle Firefox ve Edge'de çalışıyor:

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>


Bu işi nasıl açıklayabilirsin lütfen.
eguneys

@eguneys Açıklama eklendi
rink.attendant.6

işe yaramazf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys Düzeltildi. CoffeeScript'in stenografi dilimlerini kullanırken otomatik olarak bir tane eklediğini unuttum [a..b].
rink.attendant.6

için çalışmıyorf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys

1

Yakut, 208 bayt

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'ye Hoşgeldiniz! Ruby için bazı basit golf ipuçları: herhangi bir girinti gerekmez, böylece tüm alanlardan kurtulabilirsiniz. Ayrıca noktalı virgüllere de ihtiyacınız yoktur, çünkü tek bir satırsonu aynı sayıda bayttır. Bir ifadenin sonundaki yöntem çağrıları parantez gerektirmez, böylece .rindex 0her seferinde bir bayt kaydetme yapabilirsiniz . Ayrıca, adlandırılması bile gerekmeyen bir yöntem yerine bir proc kullanarak bazı baytlar kaydedebilirsiniz ->a,i{...}. İf / elsif / elsif muhtemelen iç içe bir üçlü operatörle kısaltılabilir ...?...:...?...:....
Martin Ender

Nazik tavsiye için çok teşekkürler. Buna bakacağım ve ne yapabileceğimi göreceğim.
freni

1

Haskell, 119 bayt

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

Kullanım örneği:

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

Nasıl çalışır: Belirtilen konumdaki giriş listesini sol kısma a, eleman konumun kendisi xve sağ kısma ayırın b. Bir varsa 0yılında a++xbirinciye, makyaj odası kadar 0tersten a++x. Bir varsa 0içinde x++bvar, markası odası. Hiç yoksa 0, orijinal listeyi tekrar almak için değiştirilmemiş tüm parçaları birleştirin.


0

CoffeeScript, 96 bayt

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 bayt

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

Ekleme dizinine geri döndürülen listeyi, dizinden sonraki bölümle normal sırada birleştirerek ve ardından ilk sıfırın dizinini bularak kaldırılacak sıfırın dizinini hesaplar. Sıfır ValueErrorbulunmadığında istisnaları önlemek için sonuna sıfır eklenir . Sonra silin, ekleyin ve geri dönün.


0

R, 87 bayt

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

açıklama

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

Testler

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

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

Beyaz boşluklar ve girintiler ile

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

Tüm 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);

    }

}

Test Durumları resim açıklamasını buraya girin


1
bu işe yaramaz([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

1
Örneğin, tüm gereksiz boşluk kaldırarak bazı karakter kaydedebilirsiniz String[] Q, int Piçin String[]Q,int P.
ProgramFOX

Merhaba @eguneys, bunu belirttiğin için teşekkürler. Mantığı değiştirdim ve bu nedenle tüm test vakalarınız için çalışıyor. Test senaryoları görüntüsünü de güncelledim. Yerleştirme doğru yapılır, ancak vites değiştirme sonuçları farklıdır.
Merin Nakarmi

Merhaba @ProgramFOX, değerli yorumunuz için teşekkürler. 10 karakter kaydettim.
Merin Nakarmi

0

C, 154 bayt

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

Verilen test senaryolarını geçer, a diziye işaretçi, l dizinin uzunluğudur (umarım bu kısa kesmez), i ekleme endeksidir ve c dahili olarak kullanılır. Döngüler için sol ve sağ aramaları birleştirerek geliştirilebilir.

Misal

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

Ungolfed

Düz ileri, ve gerçekten K & R tarzı beyanı ötesinde hileler değil.

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;
            }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.