Mode autopilot

10

Helikopter mulai dari sudut kiri atas sedang turun (dalam ruang 2D, untuk tujuan pertanyaan ini) menuju tanah. Ini memiliki mode autopilot dan mode manual.

Mode autopilot berlaku sebagai berikut:

  • Jika ruang langsung di bawah ini gratis, turunlah ke sana.
  • Kalau tidak, gerakkan langkah ke kiri atau kanan, sepenuhnya secara acak. (Ini dapat memindahkan beberapa langkah dengan cara ini.)

Dan itu terus mengulangi kedua langkah ini sampai menyentuh tanah. Mode manual lebih pintar dan akan menemukan jalur optimal ke tanah, bahkan jika ini membutuhkan gerakan ke atas, atau beberapa manuver terampil.

Tugas Anda adalah menentukan apakah

  1. Autopilot akan lolos dalam skenario yang diberikan,
  2. Autopilot mungkin gagal dalam skenario yang diberikan,
  3. Autopilot akan gagal, tetapi mode manual akan berlalu, atau
  4. Kedua mode akan gagal (tidak ada jalur yang valid ke tanah).

Memasukkan

  • Skenario yang diberikan sebagai larik non-kosong 1d atau 2d, menggunakan dua karakter yang berbeda untuk mewakili ruang bebas dan diblokir. Tanda baca opsional.
  • Opsional: dimensi array

Keluaran

Satu dari empat karakter yang telah ditentukan yang menunjukkan kasus mana yang telah terjadi.

Contoh data

Menggunakan 0 (kosong) dan 1 (diblokir) dalam input, 1 2 3 4 dalam output (seperti bernomor di atas)

0 0 0 0
0 1 0 0
0 0 0 1
1 1 0 0

Keluaran: 1

0 0 1 0
1 0 0 1
0 0 0 0
0 1 1 0
0 0 0 1

Output: 2(Helikopter akan menemukan 1 di baris keempat, dan ada kemungkinan ia akan menjebak dirinya sendiri di akhir baris 5, jika pada mode autopilot)

0 0 0 1 0
0 1 1 0 0
0 1 0 0 0
0 0 0 1 0
1 1 1 1 0

Output: 3(Ini membutuhkan bergerak ke atas, sehingga autopilot gagal)

1 0 0
0 0 0

Keluaran: 4

0 0 0 0 1
1 1 1 0 0
1 0 0 1 0
0 1 0 0 0
0 0 1 1 1

Keluaran: 4

ghosts_in_the_code
sumber
@ MartinBüttner Selesai. Sebagai catatan tambahan, apakah Anda lebih suka orang mengirimnya di kotak pasir, atau langsung mengirim dan memperbaiki kesalahan mereka? Opsi kedua lebih sederhana, jadi kecuali ada beberapa insentif untuk tidak, saya tidak bisa membayangkan mengapa saya mengikuti opsi satu.
ghosts_in_the_code
7
Saya pribadi lebih suka kotak pasir, karena memberi orang lebih banyak waktu untuk memikirkan potensi kesalahan, celah atau kasus tes yang hilang, sebelum orang mulai mengerjakan tantangan. Jika seseorang memposting jawaban awal untuk tantangan cacat, maka Anda tidak dapat benar-benar memperbaiki tantangan tanpa membatalkan jawaban yang ada.
Martin Ender
Juga - apakah input selalu berupa karakter, atau bisakah mereka menjadi boolean / integer / dll? Dan output - dapatkah itu bilangan bulat, atau apakah itu diperlukan untuk menjadi karakter?
Bukan berarti Charles

Jawaban:

1

Ruby, 259

Saya bersenang-senang dengan ini. Terima kasih! tantangan cenderung menyenangkan dengan tantangan yang menarik. Ini mengasumsikan bahwa "karakter" dalam pertanyaan dapat berupa bilangan bulat.

Saya pikir poin utama peningkatan di sini adalah:

  1. Penciptaan r
  2. Penyalahgunaan terner mengerikan di baris ketiga kemungkinan bisa dibuat menjadi sesuatu yang lebih mengerikan, tetapi terser.
->a,h,w{f=->l,s=0,y=[0]{r=w-2<s%w ?w:1,1>s%w ?w:-1,w
v=(l ?r+[-w]:a[s+w]==0?[w]:r).map{|d|a[m=s+d]==0&&!y[m]?m:p}-q=[p]
a[s]>0?q:s/w>h-2?8:v[0]?v.map{|o|f[l,y[o]=o,y]}.flatten-q :r.any?{|i|a[s+i]<1}?p: !0}
g=f[p]
[8,g[0]&&g.all?,g.any?,f[8].any?,!p].index !p}

Tidak digabungkan (sedikit kedaluwarsa, tetapi sangat dekat):

# a is a one-dimensional array of 0s and 1s, h is height, w is width
->a,h,w{
  # f recursively walks the array and returns true/false/nil for each path.
  #    True means we can reach ground.
  #    False means we are stuck in a local minimum and cannot escape
  #    Nil means we reached a local dead-end and need to backtrack.
  # l: {true=>"manual", false=>"autopilot"}
  # s: the position index
  # y: an array of booleans - true-ish means we've visited that square before
  #         (this is to prevent infinite loops, esp in manual mode)
  f=->l,s=0,y=[0]{
    # d: all the legal deltas from s (maximally, that's [1,-1,w,-w], aka [LRDU])
    # r: but the right and left get tricky on the edges, so let's pre-calculate those
    #    we'll default to "down" if "left" or "right" are illegal
    r=[w-2<s%w ?w:1,1>s%w ?w:-1]
    # if manual, [LRDU]; if auto, and you can go down, [D]. else, [LR] 
    d=l ?r+[w,-w]:a[s+w]==0?[w]:r
    # v: the legal deltas that you can go to from s (that is, unvisited and unblocked)
    v=d.map{|d|a[m=s+d]==0&&!y[m]?m:p}-[p]


    a[s]>0 ? [p]     # if we're currently blocked, return [nil] (this is only the case when a[0]==1)
      : s/w>h-2 ? !p # if we're at the bottom, return true
        : v[0] ?     # if we have a place to go....
        v.map{|o|f[l,y[o]=o,y]}.flatten-[p] # recurse with each step.
                                            # y[o]=o is a neat trick to make y[o] truthy and return o
          : r.any?{|i|a[s+i]==0} ? # otherwise, we have nowhere to go. If we could visit left/right, but have already been there
            p                      #    this is not a dead-end - return nil to remove this path
            : !!p                  # If we have a true dead-end (auto-mode with a local minimum), false
  }
  # g is the auto flight
  g=f[p]
  # finally, choose the first "true" out of:
  # 0: always 8.  Cuz why not 8?
  # 1: there is at least one auto path, and all are truthy
  # 2: any auto path is truthy
  # 3: any manual path is truthy
  # 4: true
  [8,g[0]&&g.all?,g.any?,f[!p].any?,!p].index !p
}
Bukan itu Charles
sumber