Füllen Sie leere Stellen, indem Sie leere Lücken füllen

10

Schreiben Sie eine Funktion (z. B. placeAt), die ein Array nicht negativer Ganzzahlen und einen Index, der eine nicht negative Ganzzahl ist, verwendet. Es sollte eine 1 am angegebenen Index platzieren und möglicherweise andere Einträge um einen Punkt verschieben, um diesen Punkt zu räumen, wobei Nullen für leere Punkte stehen.

  • Wenn der Eintrag am gewünschten Index 0 ist, füllen Sie ihn mit einer 1.
  • Suchen Sie andernfalls nach der nächsten 0 links vom Index. Verschieben Sie die Einträge um eine Stelle nach links in diese 0, um Platz zu schaffen, und füllen Sie dann den Index mit einer 1.
  • Wenn links keine 0 steht, gehen Sie genauso nach rechts.
  • Wenn beides nicht möglich ist (dh wenn es keine 0 gibt), geben Sie das Array unverändert zurück.

Die Elemente sind 0-indiziert. Der Funktionsname kann beliebig sein.

Beispiele:

(Buchstaben stehen für positive ganzzahlige Werte.)

[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

Dies ist eine Code-Golf-Herausforderung. Der kürzeste Eintrag am Ende von 9 Tagen gewinnt.

eguneys
quelle
4
Woher wissen Sie, ob Sie nach links oder rechts verschieben sollen, wenn beide möglich sind? Was ist auch, wenn es keine gibt 0?
xnor
Denn [0, 2, 0, 2] placeAt 3ist es legal ausgeben [2, 0, 2, 1]? Muss der Code tatsächlich eine aufgerufene Funktion sein placeAt? Beachten Sie, dass einige Sprachen nicht genau Funktionen haben. "Ausnahme auslösen" gilt möglicherweise auch nicht für einige Sprachen. Ich würde vorschlagen, eine Ausgabe zuzulassen, die auf einen Fehler hinweist.
xnor
Kann das Array negative Werte haben?
Kade
Ich bin mir zu 99% sicher, dass ich die Absichten des OP mit den Regeln dieser Herausforderung verstehe. Daher habe ich den Beitrag neu organisiert (er befindet sich derzeit in der Warteschlange) und werde versuchen, Fragen zu beantworten. eguneys, du kannst bei Bedarf jede meiner Antworten korrigieren.
ETHproductions
@xnor Das Verschieben nach links hat immer Vorrang vor dem Verschieben nach rechts. Wenn es keine 0 gibt, geben Sie einfach das ursprüngliche Array zurück. Dies [2, 0, 2, 1]ist auch keine legale Ausgabe, da Sie immer so wenige Elemente wie möglich verschieben sollten und die Funktion beliebig benennen können.
ETHproductions

Antworten:

4

JavaScript (ES6), 85

Testen Sie das Ausführen des Snippets in einem EcmaScript 6-kompatiblen Browser (insbesondere nicht in Chrome, nicht in MSIE. Ich habe in Firefox getestet, Safari 9 könnte funktionieren).

(Ich habe dies gefunden, ohne auf eine der anderen Antworten zu achten. Jetzt sehe ich, dass es der von Eisbahnen sehr ähnlich ist. Dennoch ziemlich kürzer. Wahrscheinlich bekomme ich für diese Antwort nicht viele positive Stimmen.)

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
quelle
+1, weil ich gerade etwas über den Komma-Operator gelernt habe und weil ich mich geschlagen habe
rink.attendant.6
@ rink.attendant.6 aber deine Verwendung von &&, um dem beizutreten, spliceist besser als mein Komma
edc65
3

Julia, 122 Bytes

Nur eine naive Implementierung der Spezifikation, um die Dinge in Gang zu bringen.

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

JavaScript (ES6), 98 Byte

Ziemlich der gleiche Ansatz wie meine CoffeeScript-Antwort, aber ich schließe bis zum Äußersten kurz, um eine zu speichernreturn Aussage :

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

Erläuterung

Zur einfacheren Erklärung habe ich meinen Code etwas neu angeordnet:

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

Hier sind einige Informationen zur JS-Kurzschlussbewertung.

Demo

Derzeit funktioniert diese Demo aufgrund der Verwendung von ES6 nur in Firefox und Edge:

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
quelle
Wie funktioniert das? Kannst du bitte erklären.
Eguneys
@eguneys Erklärung hinzugefügt
rink.attendant.6
es funktioniert nicht fürf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys
@eguneys behoben. Ich habe vergessen, dass CoffeeScript bei Verwendung der Kurzschrift automatisch eine hinzufügt [a..b].
rink.attendant.6
funktioniert nicht fürf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys
1

Ruby, 208 Bytes

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
Handrechen
quelle
Willkommen bei PPCG! Einige einfache Golftipps für Ruby: Sie brauchen keine Einkerbung, damit Sie alle Räume loswerden können. Dann brauchen Sie auch keine Semikolons, da eine einzelne Zeile die gleiche Anzahl von Bytes hat. Methodenaufrufe am Ende einer Anweisung benötigen keine Klammern, sodass Sie beispielsweise .rindex 0jedes Mal ein Byte speichern können. Sie können auch einige Bytes speichern, indem Sie einen Proc anstelle einer Methode verwenden, die nicht einmal benannt werden muss : ->a,i{...}. Das if / elsif / elsif kann wahrscheinlich mit einem verschachtelten ternären Operator gekürzt werden ...?...:...?...:....
Martin Ender
Vielen Dank für den freundlichen Rat. Ich werde es mir ansehen und sehen, was ich tun kann.
Handlauf
1

Haskell, 119 Bytes

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

Anwendungsbeispiel:

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

So funktioniert es: Teilen Sie die Eingabeliste an der angegebenen Position in den linken Teil a, das Element an der Position selbst xund den rechten Teil b. Wenn es ein 0In gibt a++x, machen Sie Platz bis zum ersten 0in der Rückseite von a++x. Wenn es ein 0in x++b, macht es Raum. Wenn überhaupt keine vorhanden sind 0, kombinieren Sie alle Teile unverändert, um die ursprüngliche Liste erneut zu erhalten.

Nimi
quelle
0

CoffeeScript, 96 Bytes

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
quelle
0

Python 2, 102 Bytes

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

Berechnet den Index der zu entfernenden Null, indem die bis zum Einfügeindex umgekehrte Liste mit dem Teil nach dem Index in normaler Reihenfolge verkettet und dann der Index der ersten Null ermittelt wird. Am Ende wird eine Null hinzugefügt, um ValueErrorAusnahmen zu vermeiden, wenn keine Null gefunden wird. Dann einfach löschen, einfügen und zurückgeben.

Samgak
quelle
0

R, 87 Bytes

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

Erläuterung

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

Tests

> 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
quelle
0

C #, 265 Bytes

Golf (265 Zeichen)

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

Mit Leerzeichen und Einkerbungen

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

Ganzes Programm

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

    }

}

Testfälle Geben Sie hier die Bildbeschreibung ein

Merin Nakarmi
quelle
1
das funktioniert nicht für([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys
1
Sie können einige Zeichen speichern , indem Sie alle unnötigen Leerzeichen zu entfernen, zum Beispiel String[] Q, int Pzu String[]Q,int P.
ProgramFOX
Hallo @eguneys, danke, dass du darauf hingewiesen hast. Ich habe die Logik geändert und arbeite daher für alle Ihre Testfälle. Ich habe auch das Testfallbild aktualisiert. Die Platzierung erfolgt korrekt, die Verschiebungsergebnisse sind jedoch unterschiedlich.
Merin Nakarmi
Hallo @ProgramFOX, danke für deinen wertvollen Kommentar. Ich habe ungefähr 10 Zeichen gespeichert.
Merin Nakarmi
0

C 154 Bytes

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

Besteht die angegebenen Testfälle, a ist der Zeiger auf das Array, l ist die Länge des Arrays (ich hoffe, dies bricht den Auftrag nicht), i ist der Index für die Einfügung und c wird intern verwendet. Könnte möglicherweise durch Kombinieren der linken und rechten Suche nach Schleifen verbessert werden.

Beispiel

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

Ungolfed

Einfach und keine Tricks, die über die Deklaration des K & R-Stils hinausgehen.

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
quelle