Lepaskan labirin!


20

Anda terjebak dalam labirin 5x5 ini - setiap kamar diberi label dari 1 hingga 25 dan pintu keluarnya ada di kamar 1.

masukkan deskripsi gambar di sini

Anda diberikan sebagai input ruangan tempat Anda berada sekarang. Tugas Anda adalah menampilkan urutan gerakan terpendek (utara, timur, selatan, barat) yang diperlukan untuk mencapai ruang 1.

Bergerak dapat menjadi output dalam format apa pun yang Anda inginkan (daftar, string, array ...) selama Anda menggunakan karakter n,w,e,s.

Inilah semua kasus uji:

1 => empty string/list
2 => w
3 => ww
4 => swwnw
5 => wswwnw
6 => seenwnw
7 => nw
8 => wnw
9 => wwnw
10 => swwnwnw
11 => eenwnw
12 => enwnw
13 => nwnw
14 => wnwnw
15 => wwnwnw
16 => enenwnw
17 => nenwnw
18 => wnenwnw
19 => nwnwnw
20 => wnwnwnw
21 => nenenwnw
22 => enwnenwnw
23 => nwnenwnw
24 => wnwnenwnw
25 => nwnwnwnw

Jawaban terpendek dalam byte menang!


3
Seberapa fleksibel pelabelan / input ruangan? Bisakah kita 0-indeks bukannya 1-indeks? Bisakah kita mengambil nomor kamar sebagai karakter (berpikir, seperti pada base 36)?
Chas Brown

2
@Therandomguy tidak, Anda perlu menangani labirin khusus ini.
Arnaud

6
Karena itu mungkin, saya pikir semua kasus yang mungkin harus dimasukkan dalam kasus uji.
Jonathan Frech

1
@UnrelatedString Pertanyaan ini mengambil 1 input, dan output jalur berbeda berdasarkan inputnya. Saya percaya persyaratan ini tidak sesuai dengan tag kompleksitas-kolmogorov .
tsh

2
Seseorang harus memberikan jawaban dalam Labirin .
Draco18s

Jawaban:


20

Python 2 , 64 byte

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

Cobalah online!

Fungsi yang mencetak satu arah per baris, diakhiri dengan kesalahan.

Konstanta 0x1211252b5375mengkodekan dalam basis 4 arah yang dkita tempuh dari setiap nomor kamar sebagai angka 0 hingga 3. Digit ekstraksi >>2*n-4&3juga dirancang untuk memberikan kesalahan pergeseran negatif saat n=1, mengakhiri kode. Kami memperbarui nomor kamar nmelalui offset yang dihitung dari arah dsebagai d*3+d%2-5, yang memetakan:

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 

1
Saya tidak yakin apakah ini valid apa adanya, fungsi harus dapat digunakan kembali, dan Anda perlu trapping kesalahan ( try/ except) untuk dapat melanjutkan eksekusi setelah memanggil fungsi ini.
Erik the Outgolfer


6

05AB1E , 30 29 byte

-1 byte berkat kebetulan ajaib dengan bilangan prima

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

Cobalah online!

[                      }    # infinite loop:
 Ð                          #  triplicate the room number (initially, the input)
  #                         #  break if room number == 1
   •θzƶ‰`Ó•4в               #  compressed list 202232302231102210202010
             sè             #  use the room number to index into that list
               <            #  decrement
                Dˆ          #  add a copy to the global array
                  Ø         #  nth prime (-1 => 0, 0 => 2, 1 => 3, 2 => 5)
                   ·        #  double
                    5-      #  subtract 5
                      +     #  add that to the room number
'‹™                         # dictionary string "western"
   ¯                        # push the global array
    è                       # index (wraps around, so -1 => n, 0 => w, 1 => e, 2 => s)

1
Ini output 1untuk input1 , bukan string kosong (perbaikan mudah akan menambahkan memimpin õ?). Terlepas dari itu, jawaban yang bagus!
Kevin Cruijssen

1
@KevinCruijssen terima kasih telah menunjukkan kesalahan itu! Saya menemukan perbaikan byte tunggal.
Grimmy

5

Ruby , 72 62 byte

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

Cobalah online!

Bagaimana?

Kuncinya di sini adalah dengan menggunakan 2 konstanta untuk membangun langkah berikutnya untuk setiap sel, kemudian memecahkan masalah secara rekursif.

2 konstanta 18139004 dan 4267088 adalah string biner yang memberikan arah langkah selanjutnya, dengan mengekstraksi bit tunggal dari keduanya untuk setiap sel, kita bisa mendapatkan:

"n" = 4*0+6*0-5 = -5
"w" = 4*1+6*0-5 = -1
"e" = 4*0+6*1-5 = +1
"s" = 4*1+6*1-5 = +5

Lebih mudah daripada bergeser dan menutupi satu nomor biner besar IMHO.

Ketika kami mendapatkan arahan, kami mengekstrak surat yang sesuai dari string "en sw":

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

Dan lanjutkan secara rekursif pada sel [n + x]



3

Perl 5 ( -n), 94 byte

-5 byte terima kasih kepada Grimy

@A=map/./g,__wwswsnwwseenwwenwnwnenwn;%H=(n,-5,s=>5,e,1,w,-1);$_+=$H{$,=$A[$_]},say$,until$_<2

TIO





1
Apakah maksud Anda saya harus mempostingnya sebagai jawaban terpisah?
Grimmy

1
ya karena tampaknya Anda melakukan sebagian besar pekerjaan, menarik untuk melihat bagaimana kami selalu dapat menghemat ruang
Nahuel Fouilleul



2

Arang , 43 40 byte

NθW⊖θ«≔I§”)“⊞x⟧∧⎚⁵2”ιι§nwesι≧⁺⁻⁺﹪ι²×³ι⁵θ

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Berdasarkan jawaban @ ChasBrown dan @ xnor. Penjelasan:

Nθ

Masukkan ruangan.

W⊖θ«

Atur variabel loop ike satu kurang dari nomor kamar dan ulangi saat itu bukan nol.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

Ekstrak arah dari string yang dikompresi 0113130113220112010102010. (Yang terdepan 0hanyalah angka pengisi.)

§nwesι

Cetak arahnya.

≧⁺⁻⁺﹪ι²×³ι⁵θ

Gunakan rumus @ xnor untuk menghitung nomor kamar baru.


2

Jelly , 30 29 byte

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

Cobalah online!

Tautan monadik mengambil sel awal dan mengembalikan string dengan arah.

Saya suka fakta bahwa kamus Jelly memiliki kata seperti 'Kennesaw' (sebuah kota di barat laut Atlanta, Georgia), digunakan di sini karena mengindeks ke dalamnya dengan [5, 1, -5, -1] + 1memberi nesw!

Penjelasan

“þ...e’                    | Base-250 integer 1962789844189344852  
       b6                  | Convert to base 6 (2, 2, 5, 2, 5, 0, 2, 2, 5, 3, 3, 0, 2, 2, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0)
         Ḥ                 | Double
          _5               | Subtract 5
            Ż              | Prepend 0
             ⁸  ¥Ƭ         | Using this as the right argument and the original link argument as the left argument, loop the following as a dyad until there is no change, collecting up results
              +            | - Add the left argument to:
               ị           |   - The left argument indexed into the right argument
                  I        | Differences between consecutive numbers
                   ‘       | Increment by 1
                    ị“®ȯẹ» | Index into "Kennesaw"

2

PHP , 110 byte

Sebuah solusi yang bukan port jawaban Chas Brown atau xnor jawaban yang bagus . Saya tahu ini lebih lama tetapi saya ingin memiliki solusi yang berbeda!

for($n=$argn;$n>1;$n=ord($s[$n*2+1])%30)echo($s='0000w<w sEw"s)n w%w&s-e*e+n&w+w,e/n*w/n,w1n.e5n0w5n2')[$n*2];

Cobalah online!

Saya telah membuat string pemetaan yang memiliki 2 karakter untuk setiap sel di papan tulis. Karakter pertama untuk setiap sel adalah gerakan (n / e / s / w) atau 0dan karakter ASCII kode 30 mod kedua akan mengembalikan nomor sel lain yang harus kita ikuti langkahnya dalam mode rekursif sampai kita keluar dari sel ( cell < 2).

Misalnya untuk input 8:

  • 2 karakter untuk sel 8adalah:w%
  • Ini berarti mencetak wdan melanjutkan dengan gerakan untuk sel%
  • Kode ASCII %adalah 37 yang mod 30 akan menjadi 7, jadi sel berikutnya yang harus diikuti adalah 7.
  • 2 karakter untuk sel 7adalah: n (karakter terakhir adalah spasi, kode ASCII = 32)
  • Ini berarti mencetak ndan melanjutkan dengan gerakan untuk sel 32 mod 30 yang 2.
  • 2 karakter untuk sel 2adalah: w<(karakter terakhir kode ASCII = 60)
  • Ini berarti mencetak wdan melanjutkan dengan gerakan untuk sel 60 mod 30 yang 0.
  • Jika jumlah sel kurang dari 2, loop berhenti!
  • Hasil cetak akhir: wnw

PHP , 75 byte

Versi ini ditulis oleh Grimy , 35 byte lebih pendek dari jawaban asli saya karena dia lebih pintar! Komentar Grimy: "4 * 25 <256, jadi Anda hanya perlu 1 byte per sel, bukan 2"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

Cobalah online!


PHP , 71 byte

Port jawaban Arnauld ini yang merupakan port jawaban xnor , tetapi sebagai loop bukan fungsi rekursif, karena ternyata lebih pendek dalam PHP.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

Cobalah online!


2
4 * 25 <256, jadi Anda hanya perlu 1 byte per sel, bukan 2: Coba online!
Grimmy

1
@ Grimy, luar biasa, saya pikir Anda harus mempostingnya sebagai jawaban terpisah, cukup berbeda.
Night2

1
Saya tidak akan melakukan itu, jadi Anda memilih untuk memasukkannya ke dalam jawaban atau membiarkannya hanya sebagai komentar.
Grimmy

1
@ Grimy, menambahkan versi Anda dengan nama Anda. Terima kasih.
Night2

2

C (dentang) , 81 byte

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

Cobalah online!

Berkat saran @ Tommylee2k -8! + panggilan rekursif

C (dentang) , 90 byte

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

Cobalah online!

Mirip dengan semua solusi yang tidak dikompresi.


1
dapat disingkat:v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k

1

05AB1E , 45 43 byte

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

Port of @ChasBrown menjawab Python 2 .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

õ?               # Output an empty string
                 # (to overwrite the implicit output if the input is 1)
[                # Start an infinite loop:
 Ð               #  Triplicate the top of the stack
                 #  (which is the (implicit) input in the first iteration)
  #              #  If it's exactly 1: stop the infinite loop
  .•DUo¢ê`Ω÷‰₂¡)R€ûK
                 #  Push compressed string "a  wwswsnwwseenwwenwnwnenwn"
   ¦             #  Remove the first character
    sè           #  Swap to get the number, and use it to index into the string
      ©          #  Store it in variable `®` (without popping)
       ?         #  Print it without trailing newline
  Ž₁9            #  Push compressed integer 22449
     ₂в          #  Convert to base-26 as list: [1,7,5,11]
       6-        #  Subtract 6 from each: [-5,1,-1,5]
         '€Ã    '#  Push dictionary string "news"
            ®k   #  Get the index in this string of character `®`
              è  #  And use that to index into the integer-list
               + #  And add it to the originally triplicated integer

Lihat ini 05AB1E ujung tambang (semua empat bagian) untuk memahami mengapa .•DUo¢ê`Ω÷‰₂¡)R€ûK•adalah "a wwswsnwwseenwwenwnwnenwn"; Ž₁9adalah 22449; Ž₁9₂вadalah [1,7,5,11]; dan '€Ãadalah "news".


1
String kamus yang nyaman itu pastilah kabar baik!
Neil

@ Neil Pasti. :) Meskipun ternyata string kamus westernlebih baik. ; p
Kevin Cruijssen

1

Bash , 120 byte

S=__wwswsnwwseenwwenwnwnenwn
N=n-5w-1s05e01
for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Cobalah online!

Saya bermain-main sebentar dengan mencoba mengemas string sebagai camilan, tetapi decoding akan membutuhkan lebih banyak karakter daripada jumlah yang disimpan.

Bagaimana itu bekerja:

S=__wwswsnwwseenwwenwnwnenwn

String $ S memegang karakter tunggal (n, w, s, e) untuk setiap kamar yang menunjukkan arah mana yang harus diambil untuk memindahkan satu ruangan menuju pintu keluar, melewatkan kamar 0 dan 1.

N=n-5w-1s05e01

String $ N memiliki delta untuk ditambahkan / dikurangi dari nomor kamar saat ini untuk setiap perubahan arah (n: -5, w: -1, s: +5, e: +1)

for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Mulai dengan $ i sama dengan nomor kamar yang diberikan pada baris perintah ($ 1). Tetapkan karakter pada indeks $ i dalam string $ S ke $ d. Ambil nilai delta dari $ N untuk arah untuk dibawa ke ruangan berikutnya, tetapkan ke $ j.

Cetak arah selanjutnya untuk menerima $ d.

Tambahkan / kurangi delta dalam $ j ke / dari $ i.

Ulangi sampai kami meninggalkan kamar # 2 (sementara $ i> 1).



Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.