Tirage magnétique dans un tableau


20

Contexte

J'ai une rangée d'aimants puissants et un tas d'objets métalliques entre eux. Où les aimants les tireront-ils?

Contribution

Votre entrée est un tableau d'entiers non négatifs, qui en contiendra au moins un 1. Vous pouvez utiliser n'importe quel format raisonnable.

Les 0s du tableau représentent des espaces vides et les 1s des aimants fixes. Tous les autres nombres sont des objets métalliques tirés par les aimants. Chaque objet est tiré vers l'aimant le plus proche (s'il y a une cravate, l'objet est tiré vers la droite), et il se déplace dans cette direction jusqu'à ce qu'il touche l'aimant ou un autre objet. Au final, tous les objets se sont regroupés autour des aimants. L'ordre des objets est préservé.

Production

Votre sortie est le tableau où chaque objet a été tiré le plus près possible de l'aimant le plus proche. Il doit avoir le même format que l'entrée.

Exemple

Considérez le tableau

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

Le plus à gauche 2est tiré vers la première paire d'aimants, tout comme le second 2. Le 3a un aimant à quatre pas dans les deux sens, il est donc tiré vers la droite. Le est 5également tiré vers la droite et se place entre 3l'aimant et l'aimant. La sortie correcte est

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

Règles et notation

Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.

Cas de test

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

Réponses:


7

Pyth, 28 20

o@.e?bhaDk_x1QkQ~hZQ

Merci @ThomasKwa pour avoir joué au golf 6 octets!

Cela abuse du tri stable en affectant à toutes les valeurs 1 ou plus dans la liste l'index du 1 le plus proche (liens rompus au 1 le plus à droite), puis en triant la liste par ces valeurs. Les zéros reçoivent leur propre index comme valeur de tri.

Suite de tests

Suite de vérification

Explication:

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

Exemple:

Prenez le cas de test [1,0,3,0,1,0,3,0,1], par exemple. Lorsque nous appliquons l'énumération, les zéros obtiendront tous leur propre index en tant que valeur de tri, je vais donc les ignorer et en faire un et trois.

Pour la première, nous obtenons les indices de ceux: [0, 4, 8]. Ensuite, inversez-le et triez en fonction de la valeur absolue des indices moins l'indice de l'un, qui se trouve être nul ici. Nous [0, 4, 8]revenons donc à nouveau. La première valeur est 0donc que nous utilisons cela.

Pour les trois, nous obtenons les indices inversés et faisons le même tri, mais en utilisant deux comme index des trois, de sorte que le 0et le 4donnent la même valeur pour la différence absolue, donc nous obtenons: [4, 0, 8]et nous prenons le 4.

Le tableau final des "valeurs de tri" sera alors [0, 1, 4, 3, 4, 5, 8, 7, 8]. Grâce au tri stable, les liens sont rompus par l'ordre d'apparition des valeurs, nous obtenons donc le tableau final que nous voulons.


Trier par l'index du plus proche 1est une bonne idée!
Zgarb

4

Rétine , 97 72 octets

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

L'entrée devrait être une liste séparée par des virgules d' entiers unaires (les délimiteurs avant et arrière comme le [...]travail fonctionnent très bien).

Exécutez tous les cas de test ici. (Pour plus de commodité, cela prend automatiquement en charge la conversion de et vers décimale.)

Voici une idée complètement différente qui évite les groupes d'équilibrage coûteux en utilisant plusieurs étapes. Il est actuellement de 6 octets de plus, mais pourrait être plus jouable au golf:

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

Dès que j'ai vu ce défi, j'ai pensé que Retina serait un bon choix (+1)
Michael Klein

@MichaelKlein Merci, mais je ne le pense pas vraiment. Je suis surpris qu'il bat même JavaScript, mais je suis sûr que cela n'aura aucune chance contre les langages de golf.
Martin Ender

Bon ajustement comme dans J'ai immédiatement commencé à penser à la façon de résoudre dans la rétine
Michael Klein

3

JavaScript (ES6), 108 octets

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

Explication

Itère sur chaque cellule et si elle contient du métal, vérifie si la cellule suivante en direction de l'aimant le plus proche est vide, et si c'est le cas, la déplace là. Ce processus est répété plusieurs fois jusqu'à ce que tout le métal se soit déplacé aussi loin que possible.

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 caractères

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

Oui, c'est très long, car PHP n'est pas vraiment un langage pour le golf, mais cela fonctionne et je me suis amusé à le faire, donc ça me va. Bien sûr, je suis ouvert à d'éventuelles pénuries.

Il y a aussi une petite fonctionnalité de bogue qui pense, alors par exemple ici:

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

on dirait que les 12 se sont magiquement placés devant les 3, mais ce n'est pas vrai!

Le 3 respecte le plus grand nombre et le laisse se rapprocher du maget!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.