Магнитное притяжение в массиве


20

Фон

У меня есть ряд мощных магнитов и куча металлических предметов между ними. Куда магниты их потянут?

вход

Ваш ввод представляет собой массив неотрицательных целых чисел, который будет содержать хотя бы одно 1. Вы можете использовать любой разумный формат.

В 0s массива представляет собой пустое пространство, и 1s представляют собой фиксированные магниты. Все остальные числа представляют собой металлические предметы, которые притягиваются магнитами. Каждый объект притягивается к ближайшему магниту (если есть галстук, объект тянется вправо), и он движется в этом направлении, пока не столкнется с магнитом или другим объектом. В конце концов, все объекты сгруппировались вокруг магнитов. Порядок объектов сохраняется.

Выход

Ваш вывод - это массив, в котором каждый объект находится как можно ближе к ближайшему магниту. Он должен иметь тот же формат, что и входные данные.

пример

Рассмотрим массив

[0,0,2,0,1,1,0,2,0,3,0,5,0,1,0]

Крайняя левая 2сторона притягивается к первой паре магнитов, как и вторая 2. 3Имеет магнит четыре шагов в обоих направлениях, поэтому он получает потянули вправо. Он 5также вытягивается вправо и проходит между 3магнитом и. Правильный вывод

[0,0,0,2,1,1,2,0,0,0,0,3,5,1,0]

Правила и оценки

Вы можете написать полную программу или функцию. Побеждает меньшее количество байтов, и стандартные лазейки запрещены.

Контрольные примеры

[0,1,0] -> [0,1,0]
[1,0,2,0,0,1,0] -> [1,2,0,0,0,1,0]
[7,0,5,0,0,1,0] -> [0,0,0,7,5,1,0]
[1,0,3,0,1,0,3,0,1] -> [1,0,0,3,1,0,0,3,1]
[1,0,0,0,0,0,0,7,3] -> [1,7,3,0,0,0,0,0,0]
[1,2,3,4,5,6,7,8,9,10,11,0,0,0,1] -> [1,2,3,4,5,6,7,0,0,0,8,9,10,11,1]
[12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1] -> [0,0,12,3,1,0,1,3,6,0,0,0,0,0,12,1]

Ответы:


7

Pyth, 28 20

o@.e?bhaDk_x1QkQ~hZQ

Спасибо @ThomasKwa за игру в гольф 6 байтов!

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

Тестирование

Набор верификации

Объяснение:

o@.e?bhaDk_x1QkQ~hZQ  ##  implicit: Q = eval(input())
o                  Q  ##  Sort Q using the values of the lambda below
 @              ~hZ   ##  select the value from the matching index of the enumerate
  .e           Q      ##  enumerate with b = value, k = index
    ?b                ##  ternary on b
      haDk_x1Q        ##  if true, this thing
              k       ##  otherwise use the index as the sort weight
          _x1Q        ##  the indices of 1 in Q, given in reverse order 
                      ##  (the reverse makes it sort to the right because of stable sorts)
       aDk            ##  sort those indices by |index - k|
      h               ##  take the first value

Пример:

Взять [1,0,3,0,1,0,3,0,1], к примеру, контрольный пример. Когда мы применяем перечисление, все нули получат свой собственный индекс в качестве значения сортировки, поэтому я пропущу их и сделаю один и три.

Для первого, мы получим индексы них: [0, 4, 8]. Затем переверните его и отсортируйте по абсолютному значению индексов минус индекс одного, который здесь равен нулю. Итак, мы [0, 4, 8]вернемся снова. Первое значение, 0поэтому мы используем это.

Для трех мы получаем обратные индексы и выполняем ту же сортировку, но используя два в качестве индекса трех, так что и the 0и the 4дают одинаковое значение для абсолютной разницы, поэтому мы получаем: [4, 0, 8]и мы берем 4.

Тогда будет окончательный массив «значений сортировки» [0, 1, 4, 3, 4, 5, 8, 7, 8]. Благодаря стабильной сортировке связи нарушаются в порядке появления значений, поэтому мы получаем конечный массив, который нам нужен.


Сортировка по индексу ближайшего 1- хорошая идея!
Згарб

4

Сетчатка , 97 72 байта

+`(?<=\b1(,1*)*?)(\B,(11+)|,(11+))\b(?!(?<-1>,1*)*,1\b)|(11+),\B
$3,$4$5

Предполагается, что входными данными будет список унарных целых чисел, разделенных запятыми (начальные и конечные разделители, например, [...]работают отлично).

Запустите все тесты здесь. (Для удобства это обеспечивает преобразование из и в десятичное значение автоматически.)

Вот совершенно другая идея, которая позволяет избежать дорогостоящих уравновешивающих групп за счет использования нескольких этапов В настоящее время он на 6 байт длиннее, но может быть более пригодным для игры в гольф:

,1\b
>1
\b1,
1<
(T`,`<`<1*,
)T`,`>`,1*>
+`(1+>)>
>$1
+`<(<1+\b)(?!>)
$1<
<|>
,

Как только я увидела этот вызов, я подумала, что Retina подойдет (+1)
Майкл Кляйн

@MichaelKlein Спасибо, но я так не думаю. Я удивлен, что он даже превосходит JavaScript, но я уверен, что у него не будет шансов против любого из языков игры в гольф.
Мартин Эндер

Хорошо подходит, как в, я сразу начал думать, как решить в сетчатке
Майкл Кляйн

3

JavaScript (ES6), 108 байт

a=>a.map(_=>a.map((x,i)=>x>1?a[j=(n=a.indexOf(1,i))<0|n-i>i-p?i-1:i+1]?0:a[a[i]=0,j]=x:x<1?0:p=i,p=-1/0))&&a

объяснение

Перебирает каждую ячейку и, если она содержит металл, проверяет, пуста ли следующая ячейка в направлении ближайшего магнита, и, если она есть, перемещает ее туда. Этот процесс повторяется много раз, пока весь металл не продвинется так далеко, как только может.

var solution =

a=>
  a.map(_=>                  // loop a.length times to ensure completeness
    a.map((x,i)=>            // for each cell item x at index i
      x>1?                   // if the cell contains metal
        a[j=                 // j = index of cell to move to
          (n=a.indexOf(1,i)) // n = index of next magnet
          <0|n-i>i-p?i-1:i+1 // set j to previous or next cell based on closest magnet
        ]?0:                 // if cell j is empty
          a[a[i]=0,j]=x      // set it to x and set cell i to 0
      :x<1?0:                // else if the cell contains a magnet
        p=i,                 // set p to the index of this magnet
      p=-1/0                 // p = index of previous magnet, initialise to -Infinity
    )
  )
  &&a                        // return a
<input type="text" id="input" value="1,2,3,4,5,6,7,8,9,10,11,0,0,0,1" />
<button onclick="result.textContent=solution(input.value.split(',').map(n=>+n))">Go</button>
<pre id="result"></pre>


2

PHP, 337 символов

<?$i=explode(",",$argv[1]);$m=$n=[];foreach($i as$k=>$v)if($v>0)eval("array_push(\$".($v<2?"m":"n").",$k);");for($p=0;$p<count($i);$p++)foreach($i as$k=>$v)if($v>1){$i[$k]=0;$r=-1;foreach($m as$_)if($r<0||abs($k-$r)>abs($_-$k))$r=$_;while($i[$r]>0)$r+=($r<$k?1:-1);$i[$r]=$v;}$s="";foreach($i as$v)$s.=$v.",";echo substr($s,0,-1)."\n";?>

Да, это очень долго, потому что PHP на самом деле не является языком для игры в гольф, но он работает, и я сделал FUN, делая это так, что мне хорошо. Конечно, я открыт для возможных недостатков.

Также есть небольшая ошибка функция , которая думает, так, например , здесь:

root@raspberrypi:~/stack# php magnet.php 12,3,0,0,1,0,1,3,0,0,6,12,0,0,0,1
0,0,3,12,1,0,1,3,6,0,0,0,0,0,12,1

похоже, что 12 волшебным образом оказались перед 3, но это не так!

3 уважает большее число и позволяет ему приблизиться к магу!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.