Nous devenons incontrôlables, docteur!

11

Le Docteur, en essayant de s'échapper des forces Dalek, a décidé de les envoyer en rotation en voyageant dans diverses poches d'espace dans un mouvement en spirale.

Selon la nature de l'espace-temps disponible, le médecin doit entrer dans le TARDIS contrôle la hauteur et la largeur de la section de l'espace et son point d'entrée avec lequel commencer la spirale.

La section de l'espace peut être envisagée comme une grille h x l remplie d'entiers séquentiels de gauche à droite, de haut en bas, en commençant par 1.

La position de départ est fournie en rc pour la ligne et la colonne ... À partir de là, le logiciel TARDIS doit cracher la liste ordonnée des nombres entiers obtenue en spirale vers l'extérieur dans le sens antihoraire à partir de la ligne r de la colonne c , en commençant par le haut ...

Votre tâche, en tant que compagnon du médecin, est de programmer le TARDIS pour qu'il prenne quatre nombres, dans le format height width row columnet qu'il détermine quel secteur d'espace le TARDIS doit parcourir pour correspondre au mouvement en spirale décrit ci-dessous ...

Entrée 1

5 5 3 3

(Grille 5 x 5, à partir de la position 3,3)

Sortie 1

13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5

Expliquer la sortie

Grille d'origine entrez la description de l'image ici

Spirale générée entrez la description de l'image ici

Entrée 2

2 4 1 2

(Grille 2 x 4 à partir de la position 1,2)

Sortie 2

2 1 5 6 7 3 8 4

Expliquer la sortie

Légèrement différent car la spirale doit maintenant tourner autour de la grille pour générer une sortie respective ...

Grille d'origine entrez la description de l'image ici

Spirale générée entrez la description de l'image ici

Règles:

  1. Il s'agit de code-golf, donc la longueur de code la plus courte est approuvée.

  2. Les exemples ci-dessus doivent être utilisés pour tester votre code. S'il ne fournit pas la sortie respective, il y a un problème ...

  3. Les versions de code golfées et golfées doivent être fournies dans votre réponse ...

Bonne chance!

WallyWest
la source
Puis-je vous indiquer draw.io où l'on peut rapidement faire des dessins plutôt raisonnables (vous avez une excellente lisibilité avec votre version dessinée à la main ... juste je ne vois pas de cercles rouges). Considérez i.stack.imgur.com/xbLSA.png comme exemple de ce qui pourrait être fait. Notez que le xml est intégré, donc si vous allez sur draw.io, vous pouvez importer à partir de l'url.
Je garderai cela à l'esprit pour mon prochain besoin de dessin, @MichaelT, merci ...
WallyWest
1
Je poste une réponse avec une fonction renvoyant un tableau en sortie. Est ce acceptable?
edc65
@ edc65 Mate, vous et moi revenons ici sur CG, je vais autoriser une fonction de S (h, w, r, c) ou similaire pour cela ... :)
WallyWest

Réponses:

3

JavaScript (ES6) 124 163 177

Modifier de manière totalement différente, pas besoin d'un tableau pour stocker les cellules visitées. En utilisant le fait que le côté de la spirale augmente de 1 après tous les 2 tours.

// New way
f=(h,w,y,x)=>
  (e=>{
    for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
      o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
  })(1)||o


// Golfed
g=(h,w,y,x)=>
  (g=>{
    for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
    for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
      g[[x,y]]=0,
      g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
  })([])||o



// Not golfed
u=(h,w,y,x)=>{
  var i,j,dx,dy,kx,ky,o,n,
    g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'

  for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
    for(j=0; j++<w;)
      g[[j,i]] = ++n;
  o=[g[[x,y]]] // starting point in output
  dx=1, dy=0 // start headed right
  
  for(; !o[w*h-1]; ) // loop until all w*h position are put in output
  {
    g[[x, y]] = 0 // mark current position to avoid reusing
    kx=dy, ky=-dx // try turning left
    if(g[[x+kx, y+ky]] != 0) // check if position marked
    { // found a valid position
      dx=kx, dy=ky // change direction
    }
    x+=dx, y+=dy // move
    k=g[[x, y]] // get current value
    if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
  }
  return o
}

// TEST - In FireFox

out=x=>O.innerHTML+=x+'\n';
[
 [[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
 [[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check:  ' + t[1]))

test=()=>
{
  var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
  if (y>h||x>w) r = 'Invalid input'
  else r = f(h,w,y,x)
  out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>

edc65
la source
Golf incroyable! De 300 à 163 ... je vous enlève mon chapeau ...
WallyWest
1
@WallyWest avec ce commentaire tu me pousses à faire mieux. Thnx
edc65
Agréable! Ma solution Python était beaucoup plus longue mais je me disais, ça va, vous utilisez une meilleure méthode. Maintenant, vous utilisez le même et il est encore plus court ... J'ai du travail à faire. :)
randomra
@randomra J'aimerais toujours le voir ...
WallyWest
2

Python 3, 191

Probablement pas un bon score, mais voilà:

def f(b,a,d,c):
 p,r,l,s,h=c+1j*d,-1j,1,0,0
 for _ in [0]*((a+b)**2):x,y=p.real,p.imag;0<x<a+1and 0<y<b+1and print(int((y-1)*a+x),end=' ');p+=r;s=(s+1)%l;t=s==0;h=(h+t)%2;l+=h<t;r*=(-1j)**t 

Nous nous déplaçons le long de la spirale en augmentant la longueur du côté après chaque deuxième tour. Si notre position est à l'intérieur de la grille donnée, nous imprimons son numéro correspondant.

Les variables sont:

  • p est une position complexe
  • x et y sont des coordonnées de position
  • r est la direction
  • s est la position du côté actuel
  • l est la longueur actuelle du côté
  • h est la parité de l'ordinal du côté actuel
randomra
la source