Kami berputar di luar kendali, Dokter!

11

The Doctor, dalam upaya melarikan diri dari pasukan Dalek telah memutuskan untuk mengirim mereka dalam putaran dengan melakukan perjalanan di berbagai kantong ruang dalam gerakan spiral.

Tergantung pada sifat ruang-waktu yang tersedia, Dokter perlu masuk ke dalam TARDIS mengontrol ketinggian dan lebar bagian ruang dan titik masuknya untuk memulai spiral.

Bagian ruang dapat dibayangkan sebagai h x w kotak diisi dengan bilangan bulat berurutan dari kiri ke kanan, atas ke bawah, dimulai dengan 1.

Posisi awal disediakan sebagai rc untuk baris dan kolom ... Dari sini, perangkat lunak TARDIS perlu memuntahkan daftar bilangan bulat yang diperoleh dengan memutar ke arah luar dalam arah berlawanan jarum jam dari baris r kolom c , mulai ke atas ...

Tugas Anda, sebagai pendamping Dokter adalah memprogram TARDIS untuk mengambil empat angka, dalam format height width row columndan menentukannya untuk sektor ruang mana yang perlu dilalui TARDIS untuk menyesuaikan dengan gerakan spiral yang dijelaskan di bawah ...

Input 1

5 5 3 3

(5 x 5 kisi, mulai dari posisi 3,3)

Output 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

Menjelaskan output

Kotak asli masukkan deskripsi gambar di sini

Spiral yang dihasilkan masukkan deskripsi gambar di sini

Input 2

2 4 1 2

(2 x 4 grid mulai dari posisi 1,2)

Keluaran 2

2 1 5 6 7 3 8 4

Menjelaskan output

Sedikit berbeda karena spiral sekarang harus melingkari grid untuk menghasilkan output masing-masing ...

Kotak asli masukkan deskripsi gambar di sini

Spiral yang dihasilkan masukkan deskripsi gambar di sini

Aturan:

  1. Ini adalah kode-golf, sehingga panjang kode terpendek mendapat tanda persetujuan.

  2. Contoh di atas harus digunakan untuk menguji kode Anda. Jika tidak memberikan output masing-masing, ada yang salah ...

  3. Versi kode golf dan golf harus diberikan dalam jawaban Anda ...

Semoga berhasil!

WallyWest
sumber
Bolehkah saya mengarahkan Anda ke draw.io di mana orang dapat dengan cepat membuat gambar yang agak masuk akal (Anda memiliki keterbacaan yang sangat baik dengan versi yang digambar tangan Anda ... hanya saja saya tidak melihat lingkaran merah). Pertimbangkan i.stack.imgur.com/xbLSA.png sebagai contoh apa yang bisa dilakukan. Perhatikan bahwa xml sudah di-embed, jadi jika Anda masuk ke draw.io Anda bisa mengimpor dari url.
Saya akan mengingatnya untuk kebutuhan saya berikutnya untuk menggambar, @MichaelT, terima kasih ...
WallyWest
1
Saya memposting jawaban dengan fungsi mengembalikan array sebagai output. Apakah ini dapat diterima?
edc65
@ edc65 Mate, Anda dan saya kembali ke sini di CG, saya akan mengizinkan fungsi S (h, w, r, c) atau sejenisnya untuk ini ... :)
WallyWest

Jawaban:

3

JavaScript (ES6) 124 163 177

Sunting Cara yang sama sekali berbeda, tidak perlu array untuk menyimpan sel yang dikunjungi. Menggunakan fakta bahwa sisi spiral bertambah 1 setelah setiap 2 putaran.

// 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
sumber
Golf yang luar biasa! Dari 300 hingga 163 ... Saya angkat topi untuk Anda ...
WallyWest
1
@WallyWest dengan komentar itu Anda mendorong saya untuk berbuat lebih baik. Thnx
edc65
Bagus! Solusi Python saya jauh lebih lama tapi saya seperti, tidak apa-apa, Anda menggunakan metode yang lebih baik. Sekarang Anda menggunakan hal yang sama dan bahkan lebih pendek ... Saya punya beberapa pekerjaan yang harus dilakukan. :)
randomra
@randomra Saya masih ingin melihatnya ...
WallyWest
2

Python 3, 191

Mungkin bukan skor yang bagus, tapi ini dia:

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 

Kami bergerak sepanjang spiral dengan menambah panjang sisi setelah setiap detik berputar. Jika posisi kami di dalam kisi yang diberikan, kami mencetak nomor yang sesuai.

Variabelnya adalah:

  • p adalah posisi kompleks
  • x dan y adalah koordinat posisi
  • r adalah arah
  • s adalah posisi di sisi saat ini
  • l adalah panjang sisi saat ini
  • h adalah paritas ordinal sisi saat ini
randomra
sumber