Wir geraten außer Kontrolle, Doktor!

11

Der Doktor, der versucht, den Dalek-Kräften zu entkommen, hat beschlossen, sie in eine Spirale zu schicken, indem er sich in einer Spiralbewegung in verschiedenen Raumtaschen bewegt.

Abhängig von der Art der verfügbaren Raumzeit muss der Arzt in die TARDIS eintreten, um die Höhe und Breite des Raumabschnitts und seinen Einstiegspunkt zu steuern, mit dem die Spirale beginnen soll.

Der Raumabschnitt kann als ein h x w- Gitter betrachtet werden, das mit aufeinanderfolgenden ganzen Zahlen von links nach rechts, von oben nach unten, beginnend mit 1, gefüllt ist.

Die Startposition wird als rc für die Zeile und Spalte angegeben ... Daraus muss die TARDIS-Software die geordnete Liste von Ganzzahlen ausspucken, die durch Aufwärtsspiralen gegen den Uhrzeigersinn von Zeile r Spalte c nach oben erhalten werden ... beginnend nach oben ...

Ihre Aufgabe als Begleiter des Arztes ist es, die TARDIS so zu programmieren, dass sie vier Zahlen im Format annimmt height width row columnund bestimmt, welchen Raumsektor die TARDIS zurücklegen muss, um der unten beschriebenen Spiralbewegung zu entsprechen ...

Eingabe 1

5 5 3 3

(5 x 5 Gitter, beginnend an Position 3,3)

Ausgabe 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

Ausgabe erklären

Originalraster Geben Sie hier die Bildbeschreibung ein

Generierte Spirale Geben Sie hier die Bildbeschreibung ein

Eingabe 2

2 4 1 2

(2 x 4 Gitter ab Position 1,2)

Ausgabe 2

2 1 5 6 7 3 8 4

Ausgabe erklären

Etwas anders, da die Spirale jetzt um das Gitter kreisen muss, um die entsprechende Ausgabe zu generieren ...

Originalraster Geben Sie hier die Bildbeschreibung ein

Generierte Spirale Geben Sie hier die Bildbeschreibung ein

Regeln:

  1. Dies ist Code-Golf, daher wird die kürzeste Codelänge genehmigt.

  2. Die obigen Beispiele müssen verwendet werden, um Ihren Code zu testen. Wenn es nicht die entsprechende Ausgabe liefert, stimmt etwas nicht ...

  3. In Ihrer Antwort müssen sowohl Golf- als auch In-Golf-Versionen des Codes angegeben sein ...

Viel Glück!

WallyWest
quelle
Darf ich Sie auf draw.io hinweisen, wo man schnell ziemlich vernünftige Zeichnungen machen kann (Sie haben eine ausgezeichnete Lesbarkeit mit Ihrer handgezeichneten Version ... nur sehe ich keine roten Kreise). Betrachten Sie i.stack.imgur.com/xbLSA.png als Beispiel dafür, was getan werden könnte. Beachten Sie, dass die XML darin eingebettet ist. Wenn Sie also zu draw.io gehen, können Sie von der URL importieren.
Ich werde das für mein nächstes Bedürfnis nach einer Zeichnung berücksichtigen, @MichaelT, danke ...
WallyWest
1
Ich poste eine Antwort mit einer Funktion, die ein Array als Ausgabe zurückgibt. Ist das akzeptabel?
edc65
@ edc65 Kumpel, du und ich gehen hier auf CG zurück, ich werde eine Funktion von S (h, w, r, c) oder dergleichen dafür
zulassen

Antworten:

3

JavaScript (ES6) 124 163 177

Bearbeiten Völlig anders, kein Array zum Speichern der besuchten Zellen erforderlich. Unter Verwendung der Tatsache, dass die Seite der Spirale nach jeweils 2 Umdrehungen um 1 zunimmt.

// 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
quelle
Erstaunliches Golfen! Von 300 bis 163 ... Ich nehme dir meinen Hut ab ...
WallyWest
1
@WallyWest mit diesem Kommentar drängst du mich, es besser zu machen. Thnx
edc65
Nett! Meine Python-Lösung war viel länger, aber ich dachte, es ist in Ordnung, Sie verwenden eine bessere Methode. Jetzt benutzt du das gleiche und es ist noch kürzer ... Ich habe noch etwas zu tun. :)
randomra
@randomra Ich würde es immer noch gerne sehen ...
WallyWest
2

Python 3, 191

Wahrscheinlich keine gute Punktzahl, aber hier geht es:

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 

Wir bewegen uns entlang der Spirale, indem wir die Seitenlänge nach jeder zweiten Umdrehung erhöhen. Wenn sich unsere Position innerhalb des angegebenen Rasters befindet, drucken wir die entsprechende Nummer.

Variablen sind:

  • p ist eine komplexe Position
  • x und y sind Positionskoordinaten
  • r ist Richtung
  • s ist die Position auf der aktuellen Seite
  • l ist die aktuelle Seitenlänge
  • h ist die Parität der Ordnungszahl der aktuellen Seite
randomra
quelle