Przyciąganie magnetyczne w szyku

20

tło

Mam między nimi rząd silnych magnesów i wiązkę metalowych przedmiotów. Gdzie przyciągną ich magnesy?

Wejście

Twoje dane wejściowe to tablica nieujemnych liczb całkowitych, która będzie zawierać co najmniej jedną 1. Możesz użyć dowolnego rozsądnego formatu.

Do 0S w tablicy oznaczają pustą przestrzeń, a 1y stanowią magnesy stałe. Wszystkie pozostałe liczby są metalowymi przedmiotami ciągniętymi przez magnesy. Każdy obiekt jest przyciągany w kierunku najbliższego magnesu (jeśli jest krawat, obiekt jest ciągnięty w prawo) i porusza się w tym kierunku, dopóki nie trafi w magnes lub inny przedmiot. W końcu wszystkie obiekty skupiły się wokół magnesów. Kolejność obiektów zostaje zachowana.

Wynik

Twój wynik to tablica, w której każdy obiekt został przyciągnięty tak blisko najbliższego magnesu, jak to możliwe. Powinien mieć ten sam format co dane wejściowe.

Przykład

Rozważ tablicę

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

Najbardziej wysunięty w lewo 2ciągnie się w kierunku pierwszej pary magnesów, podobnie jak druga 2. 3Posiada magnes czterech kroków w obu kierunkach, tak robi pociągnął w prawo. 5Również dostaje zjechał na prawo i przechodzi pomiędzy 3i magnesu. Prawidłowe wyjście to

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

Zasady i punktacja

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Przypadki testowe

[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]
Zgarb
źródło

Odpowiedzi:

7

Pyth 28 20

[email protected]?bhaDk_x1QkQ~hZQ

Dzięki @ThomasKwa za grę w golfa 6 bajtów!

Nadużywa to stabilnego sortowania, przypisując wszystkim wartościom 1 lub wyższym na liście indeks najbliższej 1 (więzy złamane do skrajnej prawej 1), a następnie sortując listę według tych wartości. Zerowe otrzymują własny indeks jako wartość sortowania.

Pakiet testowy

Pakiet weryfikacyjny

Wyjaśnienie:

[email protected]?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

Przykład:

Weźmy [1,0,3,0,1,0,3,0,1]na przykład przypadek testowy . Kiedy zastosujemy wyliczenie, wszystkie zera otrzymają własny indeks jako wartość sortowania, więc pominę je i zrobię jeden i trzy.

Na pierwszym z nich możemy uzyskać indeksy te: [0, 4, 8]. Następnie odwróć i posortuj według wartości bezwzględnej indeksów minus indeks jednego, który tutaj jest równy zero. Więc rozumiemy[0, 4, 8] wracamy ponownie. Pierwsza wartość jest 0taka, że ​​wykorzystujemy to.

W przypadku trzech otrzymujemy odwrócone indeksy i dokonujemy tego samego sortowania, ale używamy dwóch jako indeksu trzech, więc zarówno 0i , jak i 4ta sama wartość dla absolutnej różnicy, więc otrzymujemy: [4, 0, 8]i bierzemy4 .

Wtedy końcowa tablica „wartości sortowania” będzie [0, 1, 4, 3, 4, 5, 8, 7, 8]. Dzięki stabilnemu sortowaniu więzi są przerywane według kolejności, w której wartości pierwotnie się pojawiły, więc otrzymujemy ostateczną tablicę, jakiej chcemy.

FryAmTheEggman
źródło
Sortowanie według indeksu najbliższego 1to fajny pomysł!
Zgarb
4

Retina , 97 72 bajtów

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

Dane wejściowe powinny być oddzieloną przecinkami listą jednych liczb całkowitych (wiodące i końcowe ograniczniki, takie jak [...]działa dobrze).

Tutaj uruchom wszystkie przypadki testowe. (Dla wygody powoduje to automatyczną konwersję zi na dziesiętne).

Oto zupełnie inny pomysł, który pozwala uniknąć kosztownych grup równoważących poprzez zastosowanie wielu etapów. Obecnie jest 6 bajtów dłużej, ale może być bardziej golfowy:

,1\b
>1
\b1,
1<
(T`,`<`<1*,
)T`,`>`,1*>
+`(1+>)>
>$1
+`<(<1+\b)(?!>)
$1<
<|>
,
Martin Ender
źródło
Gdy tylko zobaczyłem to wyzwanie, pomyślałem, że Retina będzie dobrze pasować (+1)
Michael Klein
@MichaelKlein Dzięki, ale tak naprawdę nie sądzę, że tak jest. Dziwi mnie, że nawet pokonuje JavaScript, ale jestem prawie pewien, że nie będzie miał szans w żadnym z języków golfowych.
Martin Ender
Dobre dopasowanie, ponieważ od razu zacząłem myśleć o rozwiązaniu w Retina
Michael Klein
3

JavaScript (ES6), 108 bajtów

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

Wyjaśnienie

Iteruje nad każdą komórką i jeśli zawiera metal, sprawdza, czy następna komórka w kierunku najbliższego magnesu jest pusta, a jeśli tak, to tam ją przenosi. Proces ten powtarza się wiele razy, aż cały metal przesunął się tak daleko, jak to możliwe.

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>

użytkownik 81655
źródło
2

PHP, 337 znaków

<?$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";?>

Tak, to jest bardzo długie, ponieważ PHP nie jest tak naprawdę językiem do gry w golfa, ale działa, a Miałem ZABAWĘ, więc jest dla mnie w porządku. Oczywiście jestem otwarty na możliwe zwarcia.

Jest też mała funkcja błędu, która myśli, więc na przykład tutaj:

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

wygląda na to, że 12 magicznie znalazło się przed 3, ale to nieprawda!

3 szanuje większą liczbę i pozwala zbliżyć się do magety!

timmyRS
źródło