Wypełnij puste miejsca, wypełniając puste pola

10

Napisz funkcję (taką jak placeAt), która pobiera tablicę nieujemnych liczb całkowitych i indeks, który jest nieujemną liczbą całkowitą. Powinien umieścić 1 przy danym indeksie, prawdopodobnie przesuwając inne wpisy o jedno miejsce, aby opuścić to miejsce, przy czym 0 oznacza puste miejsca.

  • Jeśli wpis o pożądanym indeksie to 0, wypełnij go 1.
  • W przeciwnym razie poszukaj najbliższego 0 po lewej stronie indeksu. Przesuwaj wpisy o jedno miejsce w lewo na 0, aby zrobić miejsce, a następnie wypełnij indeks 1.
  • Jeśli po lewej nie ma 0, zrób to samo w prawo.
  • Jeśli żadna z nich nie jest możliwa (tzn. Jeśli nie ma wartości 0), zwróć tablicę bez zmian.

Pozycje są indeksowane według 0. Nazwa funkcji może być dowolna.

Przykłady:

(Litery oznaczają dowolne dodatnie wartości całkowite.)

[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

To wyzwanie dla golfa. Wygrywa najkrótszy wpis na koniec 9 dni.

eguneys
źródło
4
Skąd wiesz, czy przesunąć w lewo, czy w prawo, gdy oba są możliwe? A co jeśli nie ma 0?
xnor
Bo [0, 2, 0, 2] placeAt 3czy produkcja jest legalna [2, 0, 2, 1]? Czy kod musi być faktycznie wywoływaną funkcją placeAt? Pamiętaj, że niektóre języki nie mają dokładnie takich funkcji. „Zgłaszanie wyjątku” może również nie dotyczyć niektórych języków; Sugeruję zezwolenie na wyjście wskazujące na błąd.
xnor
Czy tablica może mieć wartości ujemne?
Kade
Jestem w 99% pewien, że rozumiem intencje PO z regułami tego wyzwania, więc zreorganizowałem post (teraz jest w kolejce) i spróbuję odpowiedzieć na pytania. eguneys, w razie potrzeby możesz poprawić dowolną z moich odpowiedzi.
ETHprodukcje
@ xnor Przesunięcie w lewo zawsze ma pierwszeństwo przed przesunięciem w prawo. Jeśli nie ma 0, po prostu zwróć oryginalną tablicę. Ponadto, [2, 0, 2, 1]nie jest to legalne wyjście, ponieważ zawsze powinieneś przesunąć jak najmniej elementów i możesz nazwać funkcję, jak chcesz.
ETHprodukcje

Odpowiedzi:

4

JavaScript (ES6), 85

Przetestuj uruchomienie fragmentu kodu w dowolnej przeglądarce zgodnej z EcmaScript 6 (zwłaszcza Chrome nie MSIE. Testowałem na Firefoxie, Safari 9 może przejść)

(Znalazłem to, nie patrząc na żadną z pozostałych odpowiedzi, teraz widzę, że jest bardzo podobny do lodowiska. Ale dość krótszy. Prawdopodobnie nie otrzymam wielu pozytywnych opinii na ten temat)

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
źródło
+1, ponieważ właśnie dowiedziałem się o przecinku, a za bicie mnie
rink.attendant. 6
@ rink.attendant.6, ale twoje użycie && do przyłączenia się splicejest lepsze niż mój przecinek
edc65
3

Julia, 122 bajty

Po prostu naiwna implementacja specyfikacji, aby zacząć.

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)

Nie golfowany:

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.
źródło
1

JavaScript (ES6), 98 bajtów

Prawie takie samo podejście, jak w mojej odpowiedzi CoffeeScript, ale jestem bardzo zwarty w celu zapisania returninstrukcji:

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

Wyjaśnienie

Aby ułatwić wyjaśnienie, nieco zmieniłem kod:

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

Oto kilka informacji na temat oceny zwarcia JS.

Próbny

W tej chwili ta wersja demonstracyjna działa tylko w Firefoksie i Edge dzięki zastosowaniu 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>

lodowisko. dozorca 6
źródło
Jak możesz to wyjaśnić?
eguneys
@eguneys Wyjaśnienie zostało dodane
rink.attendant. 6
to nie działaf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys,
@eguneys Naprawiono. Zapomniałem, że CoffeeScript automatycznie dodaje jeden, gdy używa ich skróconego plastra [a..b].
rink.attendant. 6
nie działa dlaf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys
1

Rubinowy, 208 bajtów

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
handrake
źródło
Witamy w PPCG! Kilka prostych wskazówek golfowych dla Ruby: nie potrzebujesz żadnych wcięć, dzięki czemu możesz pozbyć się wszystkich przestrzeni. Wtedy nie potrzebujesz również średników, ponieważ pojedynczy znak nowej linii ma tę samą liczbę bajtów. Wywołania metod na końcu instrukcji nie wymagają nawiasów, więc możesz na przykład .rindex 0zaoszczędzić jeden bajt za każdym razem. Można również zaoszczędzić trochę bajtów przez zastosowanie proc zamiast metody, które nawet nie muszą być nazywany ->a,i{...}. If / elsif / elsif można prawdopodobnie skrócić za pomocą zagnieżdżonego operatora trójskładnikowego ...?...:...?...:....
Martin Ender
Wielkie dzięki za miłą radę. Zajrzę do tego i zobaczę, co mogę zrobić.
handrake
1

Haskell, 119 bajtów

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

Przykład użycia:

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

Jak to działa: Podziel listę danych wejściowych w danej pozycji na lewą część a, element na samej pozycji xi prawą część b. Jeśli istnieje 0w a++x, zrobić miejsce aż do pierwszego 0w odwrocie a++x. Jeśli istnieje 0w x++b, producent tam pokój. Jeśli nie ma 0wcale, połącz wszystkie części bez zmian, aby ponownie uzyskać oryginalną listę.

nimi
źródło
0

CoffeeScript, 96 bajtów

f=(a,_)->a.splice((if~($=a.lastIndexOf 0,_)then $ else a.indexOf 0),1);a.splice(_,0,1)if 0in a;a
lodowisko. dozorca 6
źródło
0

Python 2, 102 bajty

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

Oblicza indeks zera, który ma zostać usunięty, łącząc listę odwróconą do indeksu wstawiania z częścią po indeksie w normalnej kolejności, a następnie znajdując indeks pierwszego zera. Zero jest dodawane na końcu, aby uniknąć ValueErrorwyjątków, gdy nie zostanie znalezione zero. Następnie wystarczy usunąć, wstawić i zwrócić.

samgak
źródło
0

R, 87 bajtów

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

Wyjaśnienie

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

Testy

> 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
źródło
0

C #, 265 bajtów

Gra w golfa (265 znaków)

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

Z białymi spacjami i wcięciami

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

Cały 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);

    }

}

Przypadki testowe wprowadź opis zdjęcia tutaj

Merin Nakarmi
źródło
1
to nie działa([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys,
1
Możesz zapisać niektóre znaki, usuwając wszystkie niepotrzebne białe znaki, na przykład String[] Q, int Pdo String[]Q,int P.
ProgramFOX
Cześć @eguneys, dzięki za zwrócenie na to uwagi. Zmodyfikowałem logikę i dlatego działa dla wszystkich twoich przypadków testowych. Zaktualizowałem również obraz przypadków testowych. Umieszczanie odbywa się poprawnie, jednak wyniki przesunięcia są różne.
Merin Nakarmi,
Cześć @ProgramFOX, dziękuję za cenny komentarz. Uratowałem około 10 znaków.
Merin Nakarmi,
0

C, 154 bajtów

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

Przechodzi podane przypadki testowe, a jest wskaźnikiem do tablicy, l jest długością tablicy (mam nadzieję, że to nie psuje skrótu), i jest indeksem wstawki, a c jest używane wewnętrznie. Można to poprawić, łącząc lewe i prawe wyszukiwanie pętli.

Przykład

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

Nie golfił

Prosto i nie ma żadnych sztuczek poza deklaracją stylu 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
źródło