Preencha espaços vazios preenchendo espaços em branco vazios


10

Escreva uma função (como placeAt) que use uma matriz de números inteiros não negativos e um índice que seja um número inteiro não negativo. Ele deve colocar um 1 no índice fornecido, possivelmente alterando outras entradas por um ponto para desocupar esse ponto, com 0s para lugares vazios.

  • Se a entrada no índice desejado for 0, preencha-a com 1.
  • Caso contrário, procure o 0 mais próximo à esquerda do índice. Desloque as entradas um ponto à esquerda nesse 0 para liberar espaço e preencha o índice com 1.
  • Se não houver 0 à esquerda, faça o mesmo indo para a direita.
  • Se nenhum dos dois for possível (por exemplo, se não houver 0), retorne a matriz inalterada.

Os itens são indexados em 0. O nome da função pode ser o que você quiser.

Exemplos:

(As letras representam quaisquer valores inteiros positivos.)

[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

Este é um desafio de código de golfe. A entrada mais curta no final de 9 dias vence.


4
Como você sabe se desloca para a esquerda ou para a direita quando ambos são possíveis? Além disso, e se não houver 0?
Xnor

Pois [0, 2, 0, 2] placeAt 3, é legal produzir [2, 0, 2, 1]? O código é necessário para realmente ser uma função chamada placeAt? Observe que alguns idiomas não possuem exatamente funções. "Lançar uma exceção" também pode não se aplicar a alguns idiomas; Eu sugiro permitir uma saída indicando um erro.
Xnor

A matriz pode ter valores negativos?
Kade

Tenho 99% de certeza de que entendo as intenções do OP com as regras deste desafio, por isso reorganizei a postagem (está na fila agora) e tentarei responder a perguntas. eguneys, você pode corrigir qualquer uma das minhas respostas, se necessário.
ETHproductions

@xnor Mudar para a esquerda sempre tem preferência sobre mudar para a direita. Se não houver 0, basta retornar a matriz original. Além disso, [2, 0, 2, 1]não é uma saída legal, pois você sempre deve mudar o menor número possível de elementos e pode nomear a função como desejar.
ETHproductions

Respostas:


4

JavaScript (ES6), 85

Teste a execução do snippet em qualquer navegador compatível com EcmaScript 6 (principalmente o Chrome, não o MSIE. Eu testei no Firefox, o Safari 9 poderia ir)

(Encontrei isso sem olhar para nenhuma das outras respostas, agora vejo que é muito parecido com o da pista. Ainda bem mais curto. Provavelmente não vou receber muitos votos positivos por essa)

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 porque eu aprendi sobre o operador de vírgula e por me vencer
rink.attendant

@ rink.attendant.6 mas o seu uso de && para se juntar ao spliceé melhor do que a minha vírgula
edc65

3

Julia, 122 bytes

Apenas uma implementação ingênua das especificações para começar.

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 bytes

Praticamente a mesma abordagem da minha resposta do CoffeeScript, mas estou em curto-circuito ao extremo para salvar uma returndeclaração:

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

Explicação

Para facilitar a explicação, reorganizei meu código um pouco:

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

Aqui estão algumas informações sobre a avaliação de curto-circuito do JS.

Demo

No momento, esta demonstração só funciona no Firefox e Edge devido ao uso do 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>


Como isso funciona, você pode explicar por favor.
precisa saber é o seguinte

@eguneys Explanation added
rink.attendant.

não funciona paraf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys Fixed. Esqueci que o CoffeeScript adiciona automaticamente um ao usar a fatia abreviada [a..b].
usar o seguinte código

não funciona paraf(['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

Bem-vindo ao PPCG! Algumas dicas simples de golfe para Ruby: você não precisa de nenhum recuo, para poder se livrar de todos os espaços. Então você também não precisa de ponto e vírgula, porque uma única nova linha é o mesmo número de bytes. As chamadas de método no final de uma instrução não precisam de parênteses, portanto você pode, por exemplo .rindex 0, salvar um byte de cada vez. Você pode também poupar alguns bytes usando uma proc em vez de um método, que não tem sequer a ser nomeado: ->a,i{...}. O if / elsif / elsif provavelmente pode ser reduzido com um operador ternário aninhado ...?...:...?...:....
Martin Ender

Muito obrigado pelo gentil conselho. Vou dar uma olhada e ver o que posso fazer.
handrake

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

Exemplo de uso:

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

Como funciona: divida a lista de entrada na posição especificada na parte esquerda a, o elemento na própria posição xe a parte direita b. Se há um 0no a++xquarto, completar o primeiro 0no reverso a++x. Se há um 0no x++b, dar espaço lá. Se não houver 0, combine todas as partes inalteradas para obter a lista original novamente.


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

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

Calcula o índice do zero a ser removido concatenando a lista revertida até o índice de inserção com a parte após o índice na ordem normal e localizando o índice do primeiro zero. Um zero é adicionado ao final para evitar ValueErrorexceções quando nenhum zero é encontrado. Em seguida, basta excluir, inserir e retornar.


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

Explicação

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

Testes

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

Golfe (265 caracteres)

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

Com espaços em branco e recuos

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

Programa completo

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

    }

}

Casos de teste insira a descrição da imagem aqui


11
isto não funciona([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

11
Você pode salvar alguns caracteres removendo todo o espaço em branco desnecessário, por exemplo, String[] Q, int Ppara String[]Q,int P.
ProgramFOX

Oi @eguneys, obrigado por apontar isso. Modifiquei a lógica e, portanto, funciona para todos os seus casos de teste. Também atualizei a imagem dos casos de teste. A colocação é feita corretamente, porém os resultados das mudanças são diferentes.
Merin Nakarmi 17/08/2015

Olá @ProgramFOX, obrigado pelo seu valioso comentário. Eu salvei cerca de 10 caracteres.
Merin Nakarmi 17/08/2015

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

Passa nos casos de teste fornecidos, a é o ponteiro para a matriz, l é o comprimento da matriz (espero que isso não seja um resumo), i é o índice da inserção ec é usado internamente. Pode ser melhorado combinando a pesquisa esquerda e direita por loops.

Exemplo

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

Ungolfed

Simples e sem truques além da declaração do estilo 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;
            }
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.