Заполните пустые места, заполнив пустые пробелы


10

Напишите функцию (например, placeAt), которая принимает массив неотрицательных целых чисел и индекс, который является неотрицательным целым числом. Он должен ставить 1 по данному индексу, возможно, сдвигая другие записи на одно место, чтобы освободить это место, а 0 означает пустые места.

  • Если запись с нужным индексом равна 0, заполните ее 1.
  • В противном случае ищите ближайший 0 слева от индекса. Сдвиньте записи на одну позицию слева в это 0, чтобы освободить место, затем заполните индекс 1.
  • Если слева нет 0, сделайте то же самое, двигаясь направо.
  • Если ни то, ни другое невозможно (т. Е. Если нет 0), вернуть массив без изменений.

Элементы с 0 индексами. Имя функции может быть чем угодно.

Примеры:

(Буквы обозначают любые положительные целые значения.)

[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

Это кодовый вызов для гольфа. Самый короткий вход в конце 9 дней побеждает.


4
Как вы знаете, сдвигаться ли влево или вправо, когда оба возможны? Кроме того, что, если нет 0?
xnor

Ибо [0, 2, 0, 2] placeAt 3законно ли выводить [2, 0, 2, 1]? Требуется ли код для вызова функции placeAt? Обратите внимание, что некоторые языки не имеют функций. «Брось исключение» также может не относиться к некоторым языкам; Я бы предложил разрешить вывод, указывающий на ошибку.
xnor

Может ли массив иметь отрицательные значения?
Каде

Я уверен на 99%, что понимаю намерения ОП с правилами этого конкурса, поэтому я реорганизовал пост (он сейчас в очереди) и постараюсь ответить на вопросы. eguneys, вы можете исправить любой из моих ответов, если это будет необходимо.
ETHпродукция

@xnor Сдвиг влево всегда предпочтительнее смещения вправо. Если нет 0, просто верните исходный массив. Кроме того, [2, 0, 2, 1]это недопустимый вывод, так как вы всегда должны сдвигать как можно меньше элементов, и вы можете называть функцию как хотите.
ETHпродукция

Ответы:


4

JavaScript (ES6), 85

Протестируйте выполнение сниппета в любом браузере, совместимом с EcmaScript 6 (в частности, не Chrome, не MSIE. Я тестировал на Firefox, Safari 9 мог пойти)

(Я нашел это, не глядя ни на один из других ответов, теперь я вижу, что он очень похож на ответ катка. И все же довольно короче. Вероятно, я не получу много голосов за этот)

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, потому что я только что узнал об операторе запятой и за то, что избил меня
rink.attendant.6

@ rink.attendant.6, но использование && для присоединения spliceлучше, чем моя запятая
edc65

3

Юлия, 122 байта

Просто наивная реализация спецификации для начала работы.

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 байт

Примерно такой же подход, как и в моем ответе CoffeeScript, но я закорачиваюсь до крайности, чтобы сохранить returnутверждение:

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

объяснение

Для простоты я немного перестроил свой код:

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

демонстрация

На данный момент эта демонстрация работает только в Firefox и Edge из-за использования 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>


Как это работает, вы можете объяснить, пожалуйста.
eguneys

@eguneys Объяснение добавлено
rink.attendant.6

это не работаетf(['a', 'b', 0, 'c', 'd', 0], 2)
eguneys

@eguneys Исправлено. Я забыл, что CoffeeScript автоматически добавляет один при использовании их сокращенного фрагмента [a..b].
rink.attendant.6

не работаетf(['a', 'b', 0, 'c', 'd', 0], 1)
eguneys

1

Рубин, 208 байт

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! Несколько простых советов по игре в гольф для Ruby: вам не нужны отступы, поэтому вы можете избавиться от всех пробелов. Тогда вам также не нужны точки с запятой, потому что одна новая строка - это то же количество байтов. Вызовы методов в конце оператора не нуждаются в круглых скобках, так что вы можете сделать, например .rindex 0, сохранить один байт каждый раз. Вы можете также сохранить некоторые байты , используя процедурный вместо метода, который даже не должны быть названы: ->a,i{...}. If / elsif / elsif может быть сокращен с помощью вложенного тернарного оператора ...?...:...?...:....
Мартин Эндер

Большое спасибо за добрый совет. Я посмотрю на это и посмотрю, что я могу сделать.
Handrake

1

Haskell, 119 байт

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

Пример использования:

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

Как это работает: Разделите список ввода в заданной позиции на левую часть a, элемент на самой позиции xи правую часть b. Если есть 0в a++x, делают помещение до первого 0в обратном a++x. Если есть 0в x++b, делают там место. Если их нет 0, объедините все части без изменений, чтобы снова получить исходный список.



0

Python 2, 102 байта

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

Вычисляет индекс нуля, подлежащего удалению, путем объединения списка, обращенного до индекса вставки, с частью после индекса в обычном порядке, а затем поиска индекса первого нуля. Ноль добавляется в конец, чтобы избежать ValueErrorисключений, когда ноль не найден. Затем просто удалите, вставьте и верните.


0

R, 87 байт

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

объяснение

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

тесты

> 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 байт

Гольф (265 персонажей)

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

Вся программа

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

    }

}

Тестовые случаи введите описание изображения здесь


1
это не работает([0, 'a', 'b', 0, 'c', 'd'], 2)
eguneys

1
Вы можете сохранить некоторые символы, удалив все ненужные пробелы, например, String[] Q, int Pдля String[]Q,int P.
ProgramFOX

Привет @eguneys, спасибо, что указал на это. Я изменил логику и, таким образом, работает для всех ваших тестов. Я также обновил изображение тестовых случаев. Размещение сделано правильно, однако результаты смещения отличаются.
Мерин Накарми

Привет @ProgramFOX, спасибо за ваш ценный комментарий. Я сохранил около 10 символов.
Мерин Накарми

0

C 154 байта

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

Передает данные тесты, a - указатель на массив, l - длина массива (надеюсь, это не нарушает краткость), i - индекс для вставки, а c используется внутри. Возможно, может быть улучшен путем объединения левого и правого поиска петель.

пример

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

Ungolfed

Прямо вперед, и на самом деле никаких трюков, кроме декларации стиля 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;
            }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.