Riempi gli spazi vuoti riempiendo gli spazi vuoti


10

Scrivi una funzione (come placeAt) che accetta un array di numeri interi non negativi e un indice che è un numero intero non negativo. Dovrebbe posizionare un 1 sull'indice dato, eventualmente spostando altre voci di un punto per liberare quel punto, con gli 0 che stanno per i punti vuoti.

  • Se la voce nell'indice desiderato è 0, riempila con un 1.
  • Altrimenti, cerca lo 0 più vicino a sinistra dell'indice. Sposta le voci di un punto a sinistra in quello 0 per fare spazio, quindi riempi l'indice con un 1.
  • Se non c'è 0 a sinistra, fai lo stesso andando a destra.
  • Se nessuno dei due è possibile (ovvero se non è presente 0), restituisce l'array invariato.

Gli articoli sono indicizzati 0. Il nome della funzione può essere quello che vuoi.

Esempi:

(Le lettere indicano qualsiasi valore intero positivo.)

[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

Questa è una sfida del codice golf. Vince l'ingresso più breve alla fine di 9 giorni.


4
Come fai a sapere se spostare a sinistra oa destra quando entrambi sono possibili? Inoltre, se non ci fosse 0?
xnor

Perché [0, 2, 0, 2] placeAt 3è legale produrre [2, 0, 2, 1]? Il codice deve essere effettivamente una funzione chiamata placeAt? Nota che alcune lingue non hanno esattamente funzioni. "Lancia un'eccezione" potrebbe anche non essere applicabile ad alcune lingue; Suggerirei di consentire un output che indica un errore.
xnor

L'array può avere valori negativi?
Kade,

Sono sicuro al 99% di comprendere le intenzioni del PO con le regole di questa sfida, quindi ho riorganizzato il post (è in coda in questo momento) e cercherò di rispondere alle domande. eguneys, puoi correggere una qualsiasi delle mie risposte se necessario.
ETHproductions

@xnor Lo spostamento a sinistra ha sempre la preferenza sullo spostamento a destra. Se non c'è 0, basta restituire l'array originale. Inoltre, [2, 0, 2, 1]non è un output legale, poiché dovresti sempre spostare il minor numero possibile di elementi e puoi nominare la funzione come preferisci.
ETHproductions

Risposte:


4

JavaScript (ES6), 85

Prova a eseguire lo snippet su qualsiasi browser compatibile con EcmaScript 6 (in particolare Chrome non MSIE. Ho testato su Firefox, Safari 9 potrebbe andare)

(L'ho trovato senza guardare nessuna delle altre risposte, ora vedo che è molto simile a quello della pista. Eppure piuttosto breve. Probabilmente non otterrò molti voti per questo)

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 perché ho appena saputo dell'operatore virgola e per avermi picchiato
rink.attendant.6

@ rink.attendant.6 ma il tuo uso di && per unirti a spliceè migliore della mia virgola
edc65

3

Julia, 122 byte

Solo un'implementazione ingenua delle specifiche per iniziare le cose.

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 byte

Praticamente lo stesso approccio della mia risposta CoffeeScript ma sto cortocircuitando all'estremo per salvare una returndichiarazione:

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

Spiegazione

Per una spiegazione più semplice, ho riordinato un po 'il mio codice:

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

Ecco alcune informazioni sulla valutazione del corto circuito JS.

dimostrazione

Al momento questa demo funziona solo su Firefox e Edge grazie all'uso di 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>


Come può spiegare questo lavoro, per favore.
eguneys,

@eguneys Spiegazione aggiunta
rink.attendant.6

non funziona perf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys Risolto. Ho dimenticato che CoffeeScript ne aggiunge automaticamente uno quando si usa la loro scorciatoia [a..b].
rink.attendant.6

non funziona perf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys

1

Rubino, 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

Benvenuti in PPCG! Alcuni semplici consigli sul golf per Ruby: non hai bisogno di alcun rientro, quindi puoi liberarti di tutti gli spazi. Quindi anche i punti e virgola non sono necessari, poiché una nuova riga è lo stesso numero di byte. Le chiamate di metodo alla fine di un'istruzione non richiedono parentesi, quindi è possibile, ad esempio .rindex 0, salvare un byte ogni volta. È inoltre possibile salvare alcuni byte utilizzando un proc invece di un metodo, che non ha nemmeno di essere chiamato: ->a,i{...}. Probabilmente if / elsif / elsif può essere abbreviato con un operatore ternario annidato ...?...:...?...:....
Martin Ender,

Grazie mille per il gentile consiglio. Lo guarderò e vedrò cosa posso fare.
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

Esempio di utilizzo:

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

Come funziona: dividere l'elenco di input nella posizione data nella parte sinistra a, l'elemento nella posizione stessa xe la parte destra b. Se c'è un 0in a++x, fai spazio per primo 0al contrario di a++x. Se c'è un 0ingresso x++b, fai spazio lì. In caso 0contrario, combinare tutte le parti invariate per ottenere nuovamente l'elenco originale.


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

Calcola l'indice dello zero da rimuovere concatenando l'elenco invertito fino all'indice di inserzione con la parte dopo l'indice in ordine normale, quindi trovando l'indice del primo zero. Uno zero viene aggiunto alla fine per evitare ValueErroreccezioni quando non viene trovato alcun zero. Quindi elimina, inserisci e ritorna.


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

Spiegazione

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

test

> 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

Golfed (265 Personaggi)

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

Con spazi bianchi e rientranze

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

Intero programma

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

    }

}

Casi test inserisci qui la descrizione dell'immagine


1
questo non funziona per([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

1
È possibile salvare alcuni caratteri, rimuovendo tutti gli spazi inutili, per esempio String[] Q, int Pa String[]Q,int P.
Programma FOX

Ciao @eguneys, grazie per averlo sottolineato. Ho modificato la logica e quindi funziona per tutti i casi di test. Ho anche aggiornato l'immagine dei casi di test. Il posizionamento viene eseguito correttamente, tuttavia i risultati di spostamento sono diversi.
Merin Nakarmi,

Ciao @ProgramFOX, grazie per il tuo prezioso commento. Ho salvato circa 10 caratteri.
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;}}}

Passa i casi di test indicati, a è il puntatore all'array, l è la lunghezza dell'array (spero che questo non rompa il brief), i è l'indice per l'inserto ec viene utilizzato internamente. Potrebbe forse essere migliorato combinando la ricerca sinistra e destra per i loop.

Esempio

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

Ungolfed

Semplice, e in realtà nessun trucco oltre la dichiarazione di stile 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;
            }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.