Siamo fuori controllo, dottore!


11

Il Dottore, nel tentativo di fuggire dalle forze di Dalek, ha deciso di mandarle in un viaggio viaggiando in varie tasche dello spazio con un movimento a spirale.

A seconda della natura dello spazio-tempo disponibile, Il Dottore deve entrare nel TARDIS controlla l'altezza e la larghezza della sezione dello spazio e il suo punto di ingresso con cui iniziare la spirale.

La sezione dello spazio può essere immaginata come una griglia h x w riempita con numeri interi sequenziali da sinistra a destra, dall'alto verso il basso, a partire da 1.

La posizione iniziale è fornita come rc per la riga e la colonna ... Da questo il software TARDIS deve sputare la lista ordinata di numeri interi ottenuti facendo una spirale verso l'esterno in senso antiorario dalla riga r colonna c , iniziando verso l'alto ...

Il tuo compito, come compagno del dottore, è programmare il TARDIS in modo che prenda quattro numeri, nel formato height width row columne faccia in modo che determini quale settore di spazio il TARDIS deve percorrere per adattarsi al movimento a spirale descritto di seguito ...

Ingresso 1

5 5 3 3

(Griglia 5 x 5, a partire dalla posizione 3,3)

Uscita 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

Spiegare l'output

Griglia originale inserisci qui la descrizione dell'immagine

Spirale generata inserisci qui la descrizione dell'immagine

Ingresso 2

2 4 1 2

(Griglia 2 x 4 a partire dalla posizione 1,2)

Uscita 2

2 1 5 6 7 3 8 4

Spiegare l'output

Leggermente diverso come la spirale ora deve girare attorno alla griglia per generare il rispettivo output ...

Griglia originale inserisci qui la descrizione dell'immagine

Spirale generata inserisci qui la descrizione dell'immagine

Regole:

  1. Questo è code-golf, quindi la lunghezza del codice più breve ottiene il segno di spunta dell'approvazione.

  2. Gli esempi sopra devono essere usati per testare il tuo codice. Se non fornisce il rispettivo output, c'è qualcosa che non va ...

  3. Nella tua risposta devono essere fornite sia le versioni golfizzate sia quelle non golfizzate ...

In bocca al lupo!


Vorrei indicarti draw.io dove si possono rapidamente fare disegni piuttosto ragionevoli (hai un'ottima leggibilità con la tua versione disegnata a mano ... solo che non vedo alcun cerchio rosso). Considera i.stack.imgur.com/xbLSA.png come un esempio di cosa si potrebbe fare. Nota che contiene l'xml incorporato, quindi se vai su draw.io puoi importare dall'URL.

Lo terrò a mente per il mio prossimo bisogno di un disegno, @MichaelT, grazie ...
WallyWest

1
Pubblico una risposta con una funzione che restituisce array come output. È accettabile?
edc65,

@ edc65 Mate, io e te torniamo qui su CG, consentirò una funzione di S (h, w, r, c) o simili per questo ... :)
WallyWest

Risposte:


3

JavaScript (ES6) 124163 177

Modifica Modo completamente diverso, non è necessario un array per archiviare le celle visitate. Utilizzando il fatto che il lato della spirale aumenta di 1 ogni 2 giri.

// 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>


Incredibile golf! Dalle 300 alle 163 ... Mi tolgo il cappello ...
WallyWest,

1
@WallyWest con quel commento mi spingi a fare meglio. Thnx
edc65,

Bello! La mia soluzione Python è stata molto più lunga ma ero tipo, va bene, usi un metodo migliore. Ora usi lo stesso ed è ancora più breve ... Ho del lavoro da fare. :)
randomra,

@randomra Mi piacerebbe ancora vederlo ...
WallyWest,

2

Python 3, 191

Probabilmente non è un ottimo punteggio, ma qui va:

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 

Ci muoviamo lungo la spirale aumentando la lunghezza del lato dopo ogni secondo giro. Se la nostra posizione è all'interno della griglia data, stampiamo il suo numero corrispondente.

Le variabili sono:

  • p è una posizione complessa
  • xey sono coordinate di posizione
  • r è direzione
  • s è la posizione sul lato corrente
  • l è la lunghezza del lato corrente
  • h è la parità dell'ordinale della parte corrente
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.