Bir dizide manyetik çekme


20

Arka fon

Bir dizi güçlü mıknatısım ve aralarında bir sürü metal objem var. Mıknatıslar onları nereye çekecek?

Giriş

Girişiniz, en az bir tane içeren negatif olmayan bir tamsayı dizisidir 1. Herhangi bir makul formatı kullanabilirsiniz.

Dizinin 0s değeri boş alanı ve 1s sabit mıknatısları temsil eder. Diğer tüm sayılar, mıknatıslar tarafından çekilen metal nesnelerdir. Her nesne en yakın mıknatısa doğru çekilir (bir kravat varsa, nesne sağa çekilir) ve mıknatısa veya başka bir nesneye çarpana kadar bu yönde hareket eder. Sonunda, tüm nesneler mıknatısların etrafında kümelenmiştir. Nesnelerin sırası korunur.

Çıktı

Çıktınız, her nesnenin mümkün olduğunca en yakın mıknatısa çekildiği dizidir. Girdi ile aynı biçime sahip olmalıdır.

Misal

Diziyi düşünün

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

En soldaki 2, ikinci mıknatıs gibi ilk mıknatıs çiftine doğru çekilir 2. Her 3iki yönde dört adım ötedeki bir mıknatıs vardır, bu yüzden sağa çekilir. 5Ayrıca sağa çekti ve aralarında gider alır 3ve mıknatıs. Doğru çıktı

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

Kurallar ve puanlama

Tam bir program veya işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test senaryoları

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

Yanıtlar:


7

Pyth, 28 20

o@.e?bhaDk_x1QkQ~hZQ

@ThomasKwa 6 bayt golf için teşekkürler!

Bu, listedeki tüm 1 veya daha büyük değerlere en yakın 1'in dizinini (en sağdaki 1'e kopan bağlar) atayarak ve listeyi bu değerlere göre sıralayarak kararlı sıralamayı kötüye kullanır. Sıfırlara sıralama değerleri olarak kendi dizinleri verilir.

Test odası

Doğrulama Paketi

Açıklama:

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

Örnek:

Örneğin, test senaryosunu ele [1,0,3,0,1,0,3,0,1]alalım. Numaralandırmayı uyguladığımızda, sıfırların tümü kendi dizinlerini bir sıralama değeri olarak alacaktır, bu yüzden bunları atlayacağım ve bir ve üç yapacağım.

İlki için, olanlardan endeks olsun: [0, 4, 8]. Sonra tersine çevirin ve burada sıfır olan endekslerin eksi indeksinin mutlak değerine göre sıralayın. Bu yüzden [0, 4, 8]tekrar geri dönüyoruz. İlk değer, 0bunu kullanıyoruz.

Üçlü için, ters indeksleri alıyoruz ve aynı sıralamayı yapıyoruz, ancak üçünün indeksi olarak ikisini kullanıyoruz, bu yüzden hem 0ve hem 4mutlak fark için aynı değeri veriyoruz, böylece elde ediyoruz: [4, 0, 8]ve 4.

Sonra son "sıralama değerleri" dizisi olacaktır [0, 1, 4, 3, 4, 5, 8, 7, 8]. Kararlı sıralama sayesinde, bağlar, değerlerin başlangıçta göründüğü sıraya göre kesilir, bu yüzden istediğimiz son diziyi alırız.


En yakın endekse göre sıralama 1iyi bir fikirdir!
Zgarb

4

Retina , 97 72 bayt

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

Girdinin tekli tamsayıların virgülle ayrılmış bir listesi olması beklenir ( [...]iyi iş gibi önde gelen ve sondaki sınırlayıcılar ).

Tüm test senaryolarını burada çalıştırın. (Kolaylık olması için, otomatik olarak ondalık sayıya ve ondalık sayıya dönüştürme işlemi gerçekleştirilir.)

İşte çok farklı bir aşama kullanarak pahalı dengeleme gruplarından kaçınan tamamen farklı bir fikir. Şu anda 6 bayt daha uzun, ancak daha golf edilebilir olabilir:

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

Bu mücadeleyi görür görmez Retina'nın iyi olacağını düşündüm (+1)
Michael Klein

@MichaelKlein Teşekkürler, ama gerçekten olduğunu sanmıyorum. JavaScript'i bile yendiğine şaşırdım, ancak golf dillerinin hiçbirine karşı şansı olmayacağından eminim.
Martin Ender

İyi uyum, hemen Retina'da nasıl çözüleceğini düşünmeye başladım
Michael Klein

3

JavaScript (ES6), 108 bayt

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

açıklama

Her hücrenin üzerinde yinelenir ve metal içeriyorsa, en yakın mıknatıs yönünde sonraki hücrenin boş olup olmadığını kontrol eder ve eğer varsa, oraya taşır. Bu işlem, tüm metal gidebildiği kadar hareket edene kadar birçok kez tekrarlanır.

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 karakter

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

Evet bu çok uzun, çünkü PHP gerçekten golf için bir dil değil, ama çalışıyor ve benim için iyi olduğu için EĞLENCE yaptım. Tabii ki olası eksikliklere açıkım.

Ayrıca düşünen küçük bir hata özelliği var, bu yüzden örneğin burada:

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

Görünüşe göre 12 sihirli bir şekilde 3'ün önüne geçti, ama bu doğru değil!

3, daha büyük sayıya saygı duyuyor ve maget'e yaklaşmasını sağlıyor!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.