Membuka Kunci Rahasia ke Labirin 1 Dimensi


41

Latar Belakang

Anda bangun untuk menemukan diri Anda tersesat dalam labirin satu dimensi! Sebuah jin mistik (atau sesuatu) muncul dan menjelaskan bahwa pintu keluar ada di depan Anda, tetapi di antara Anda dan pintu keluar itu adalah serangkaian tantangan. Ketika Anda berjalan maju, Anda menyadari bahwa semua tantangan yang disebut hanyalah pintu terkunci. Anda pertama kali melihat pintu dengan lubang kunci berbentuk tee, dan tidak memiliki kunci seperti itu sendiri, menelusuri kembali langkah-langkah Anda, mencari kunci dengan Tbentuk.

Frustrasi, Anda menemukan sup alfabet kunci di tanah, tidak ada yang cocok dengan pintu yang Anda temui. Dengan sedikit kejeniusan (atau kebodohan), Anda memutuskan bahwa kunci bentuk huruf kecil tmungkin bisa masuk ke dalam slot jika Anda cukup macet di sana. Ketika Anda mendekati pintu dengan tkunci huruf kecil di tangan, Tlubang itu menyala hijau dan pintu itu larut di depan Anda.

Satu down, masih banyak lagi ...

Tantangan

Tujuan dari tantangan ini adalah untuk menandai berapa banyak langkah yang Anda perlukan untuk keluar dari labirin.

Input dari tantangan ini adalah labirin: satu string yang hanya berisi karakter [A-Za-z^$ ]. Glosarium:

  • ^- Ruang mulai. Input akan berisi persis satu ^.
  • $- Pintu keluar (kebebasan!). Input akan berisi persis satu $.
  • [A-Z]- Huruf kapital menandakan pintu. Anda hanya dapat melewati pintu ini jika Anda telah mengumpulkan kunci yang diperlukan.
  • [a-z]- Huruf kecil menandakan kunci. Anda mengumpulkan kunci-kunci ini dengan berjalan ke ruang yang berisi kunci.

Akan ada paling banyak satu dari setiap huruf kapital di input. Ini berarti jumlah total pintu akan antara 0-26 inklusif.

Setiap pintu yang terkunci [A-Z]akan memiliki tepat satu kunci huruf kecil yang sesuai [a-z]. Mungkin ada sejumlah spasi ( ) di input.

Semua pintu berada di sebelah kanan awal, dan di sebelah kiri pintu keluar. Dengan demikian tidak akan ada pintu yang berlebihan. Semua input akan dapat dipecahkan.

Output untuk tantangan ini adalah sejumlah, jumlah langkah yang diperlukan untuk keluar dari labirin.

Algoritma

Pendekatan metodis Anda untuk keluar dari tempat celaka ini adalah sebagai berikut:

  • Mulai dari awal ( ^) dan bergerak maju (kanan) mengumpulkan semua kunci yang Anda temui.
  • Ketika Anda menemukan sebuah pintu, jika Anda memiliki kunci yang benar, Anda melanjutkan ke pintu. Jika Anda tidak memiliki kunci yang benar, Anda berjalan mundur (kiri) mengumpulkan kunci yang Anda temui sampai Anda menemukan kunci untuk pintu terbaru yang tidak dapat Anda buka.
  • Setelah Anda mengumpulkan kunci untuk pintu merepotkan saat ini, Anda kembali ke kanan dan melanjutkan.
  • Ulangi proses ini sampai Anda melangkah ke pintu keluar ( $).

Pegolf yang berpengalaman akan memahami bahwa kode Anda tidak harus mengimplementasikan algoritma spesifik ini asalkan menghasilkan hasil yang sama seolah-olah Anda telah menjalankan algoritma ini.

Perhitungan

Setiap kali Anda melangkah dari satu kotak ke kotak lain, itu dianggap sebagai satu langkah. Mengubah 180º tidak menimbulkan langkah tambahan. Anda tidak dapat melangkah maju ke pintu tanpa kunci yang diperlukan. Anda harus melangkah ke kunci untuk mengambilnya, dan harus melangkah ke pintu keluar untuk menang. Setelah langkah pertama Anda, ruang mulai ( ^) berperilaku seperti ruang biasa lainnya.

Contohnya

Dalam contoh-contoh ini saya telah meninggalkan ruang sebagai garis bawah untuk keterbacaan manusia.

Masukan adalah _a_^_A__$__. Outputnya adalah 11. Anda mengambil 1langkah maju, perhatikan bahwa Anda tidak memiliki kunci untuk Apintu, dan kemudian tentang wajah. Anda berjalan mundur sampai Anda menempati ruang yang berisi a( 3langkah mundur, sekarang 4total). Anda kemudian berjalan maju sampai Anda menempati ruang yang berisi pintu keluar ( 7langkah maju, 11total).

Masukan adalah b__j^__a_AJB_$. Hasilnya adalah 41Anda melakukan dua perjalanan terpisah ke bagian belakang labirin, satu untuk mendapatkan jkunci, dan yang berikutnya untuk mendapatkan bkunci.

Masukan adalah __m__t_^__x_T_MX_$____. Outputnya adalah 44. Anda tidak akan melakukan perjalanan ekstra untuk mendapatkan xkunci, karena Anda mengambilnya dari awal hingga awal T.

Masukan adalah g_t_^G_T$. Outputnya adalah 12. Anda tidak dapat pindah ke Gruang tanpa kunci, dan segera tentang-wajah. Anda cukup beruntung untuk mengambil tkunci menuju gkunci, dan dengan demikian membuka kedua pintu menuju kebebasan.

Masukan adalah _^_____$. Outputnya adalah 6. Itu mudah.

Pedoman I / O dan Kriteria Kemenangan

Aturan I / O standar berlaku. Ini adalah tantangan .


17
Terlepas dari tantangan yang menyenangkan, saya ingin mengatakan betapa bagusnya kata-kata dan penjelasannya
Luis Mendo

4
"Dengan demikian tidak akan ada pintu berlebihan." Saya pikir Adi bA^aB$tidak akan berlebihan baik. ;)
Martin Ender

4
@ Atlp Saya lebih tertarik melihat bagaimana orang-orang bermain golf dalam algoritma yang mengembara ini. Tampaknya sepele untuk melakukan solusi optimal "pergi dapatkan semua kunci lalu buka semua pintu".
turbulencetoo

2
@PeterTaylor dan turbulencetoo Tidak bukan, siapa bilang semua kunci ada di sebelah kiri, dan semua pintu di kanan? Dan kunci / pintu yang berlebihan akan menarik juga. Ini akan sangat menarik, karena itu berarti menyelesaikan grafik ketergantungan.
orlp

5
Setiap pintu memiliki kunci. Apakah setiap kunci punya pintu?
user2357112 mendukung Monica

Jawaban:


3

CJam, 45

1q_'$#<'^/~\W%:A;ee{~32+A#)_T>{:T+2*+}&]0=)}/

Cobalah online

Penjelasan:

1         initial step count; this 1 is actually for the last step :)
q_'$#<    read the input and only keep the part before the '$'
'^/~      split by '^' and dump the 2 pieces on the stack
\W%:A;    take the first piece, reverse it and store it in A
ee        enumerate the other piece (making [index char] pairs)
{…}/      for each [index char] pair
  ~32+    dump the index and character on the stack, and add 32 to the character;
           uppercase letters become lowercase and other chars become garbage
  A#)     find the index of this character in A and increment it (not found -> 0)
  _T>     check if this index (number of steps from '^' back to the key)
           is greater than T (which is initially 0)
  {…}&    if that's true (we need to go back), then
    :T    store that index in T (keeping track of how far we go back before '^')
    +     add to the other index (from the pair, number of steps we took after '^')
    2*    double the result (going back and forth)
    +     add it to the step count
  ]0=     keep only the first value from the bottom of the stack (step count)
           (if the condition above was false, we'd have 2 extra values)
  )       increment the step count (for the current step)

7

Pyth, 51 byte

JxQ"^"K-xQ"$"JVQI&}NrG1>JxQrN0=JxQrN0=+K*2t-xQNJ;pK

jumlah jarak antara pintu dan kuncinya (dua kali lipat, untuk mengambil perjalanan pulang pergi), mengabaikan kunci "bersarang" dan jarak dari awal hingga akhir:

JxQ"^"                                              #Initialize the farther point with the starting position
      K-xQ"$"J                                      #Initialize the step counter with the difference between the exit and the start
              VQ                                    #iterate over the input
                I&}NrG1>JxQrN0                      #check if is upper and if the keys is father than one stored (to eliminate nested keys)
                              =JxQrN0               #update the farther key
                                     =+K*2t-xQNJ;   #update step counter with the round trip door<>key
                                                 pK #print the step counter

algorythm yang sama di python2.7:

lab=raw_input()
farther_key=lab.index('^')
steps = lab.index('$') - farther_key
for i in lab:
    if i.isupper():
        if farther_key> lab.index(i.lower()):
            farther_key=lab.index(i.lower())
            steps+=((lab.index(i) - farther_key)-1)*2
print steps

5

Python 2, 155 154 134 128 byte

Sunting: Terima kasih kepada @ user2357112 dan @loovjo atas komentar mereka yang membantu saya mencukur 20 26 byte dari solusi saya!

def f(l):
 i=l.index;b=i('^');t=i('$')-b
 for d in filter(str.isupper,l):
  k=i(d.lower())
  if k<b:b=k;t+=2*(i(d)-k-1)
 print t

1
Anda dapat menggabungkan baris kedua dan ketiga dengan titik koma, menghemat satu byte. Juga, variabel i tampaknya tidak perlu dalam loop.
Loovjo

Setuju pada baris ke-2 dan ke-3, @Loovjo, tetapi mengapa menurut Anda itidak perlu? imelacak posisi pintu yang saat ini sedang diproses, dan diperlukan jika kuncinya belum diambil (yaitu jika k- posisi kunci - kurang dari f- yang terjauh yang pernah kita lewati - maka kita perlu menambahkan 2*(i-k-1)langkah-langkah ke total kami (berjalan ke kiri untuk mendapatkan kunci, dan berjalan kembali ke pintu) ...?
Ken 'Joey' Mosher

1
Tapi tidak bisakah idigantikan oleh l.index(d)pada baris kelima dan tugas dengan dihapus pada baris keempat?
Loovjo

Variabel yang terpisah edan fterlihat berlebihan. Selain itu, Anda bisa menyimpan banyak karakter dengan menyimpan l.indexke variabel.
user2357112 mendukung Monica

@loovjo: Yup, Anda benar ... Saya salah paham pada awalnya. @ user2357112: benar sekali. xberlebihan juga. Tebak golf noob-iness saya menunjukkan. :) Terima kasih untuk bantuannya!
Ken 'Joey' Mosher

4

C, 136 byte

q,x,p[300],z,c,k;main(i){for(;p[c=getchar()]=++i,c-36;z&&(k+=(x=p[c+32])&&x<q?(q=q>x?x:q,2*i-2*x-1):1))z=p[94],q||(q=z);printf("%d",k);}

4

PHP 5.3, 123 byte

Ini adalah posting pertama saya di Code Golf, semoga kualitas golf ini cukup tinggi untuk posting pertama. Pasti tantangan yang menyenangkan dan pertanyaan yang luar biasa!

function n($m){while('$'!=$o=$m[$i++])$o=='^'?$b=$i+$c=0:$o>'Z'||$b<=$k=stripos($m,$o))?$c++:$c+=2*$i-3-2*$b=$k;return$c;}

Program ini dengan baik menyalahgunakan fakta bahwa PHP tidak perlu Anda untuk mendeklarasikan variabel apa pun sebelum Anda menggunakannya.

Itu juga ternyata menjadi beberapa byte lebih pendek dalam solusi akhir saya untuk mulai dari 0 dan mengatur ulang jumlah langkah ketika karakter awal ditemukan, daripada memulai pada '^'.

Ada tips yang pasti diterima!


3

JavaScript (ES6), 110 byte

s=>(i=c=>s.indexOf(c),p=i`^`,l=i`$`-p,s.replace(/[A-Z]/g,(c,j)=>p>(t=i(c.toLowerCase()))?l+=j-(p=t)-1<<1:0),l)

Port of @ Rob's Pyth menjawab.


2

Python 2.7, 234 199 179

a=raw_input()
x=a.index
v=x('^')
b=x('$')-v
l=filter(str.islower,a[:v])[::-1]
for i in filter(str.isupper,a):
 k=i.lower()
 if k in l:b+=(x(i)-x(k)-1)*2;l=l[l.index(k)+1:]
print b

1

AWK, 174 Bytes

func f(xmS){x+=S
c=a[x]
if(c~/^[A-Z]/&&!k[c]){C=c
S=-S
s--}else{c=toupper(c)
k[c]=1
s++
if(c==C){S=-S;C=9}}if(c=="$"){print s}else f(x,S)}{split($0,a,"")
f(index($0,"^"),1)}

Mungkin ada algoritma yang lebih ketat, tapi inilah yang saya hasilkan.

Perhatikan bahwa saya menggunakan gawk. Beberapa implementasi AWKmungkin tidak memecah string dengan ""cara ini.


1

C #, 309 byte

class P{static void Main(string[]a){string m=Console.ReadLine(),k="";var f=true;char b,c=b=' ';int j=m.IndexOf('^'),t=0;for(;m[j]!='$';j+=f?1:-1){c=m[j];if(char.IsUpper(c)){if(k.IndexOf(char.ToLower(c))<0){f=!f;b=c;t--;}}if(char.IsLower(c)){k+=c;if(char.ToUpper(c)==b){f=!f;t--;}}t++;}Console.WriteLine(t);}}

Versi tidak disatukan:

    class P
{
    static void Main(string[] a)
    {
        string m = Console.ReadLine(), k = "";
        var f = true;
        char b, c = b = ' ';
        int j = m.IndexOf('^'), t = 0;
        for (; m[j] != '$'; j += f ? 1 : -1)
        {
            c = m[j];
            if (char.IsUpper(c))
            {
                if (k.IndexOf(char.ToLower(c)) < 0)
                {
                    f = !f; b = c; t--;
                }
            }

            if (char.IsLower(c))
            {
                k += c;
                if (char.ToUpper(c) == b) { f = !f; t--; }
            }


            t++;
        }
        Console.WriteLine(t);
        Console.ReadKey();

    }
}

Tidak ada yang mewah di sini, hanya iterasi melalui string dan ubah arah berdasarkan karakter dan apakah kunci tersebut terkandung dalam string kunci.

m = string maze

k = string kunci

f = arah (benar maju dalam labirin)

b = kunci untuk mencari ketika mundur

c = placeholder untuk m [j] untuk menyimpan beberapa byte karena sering digunakan

j = indeks char dari string untuk dilihat

t = hitungan

Masih relatif baru dalam bermain golf, jadi jika Anda melihat suatu tempat saya dapat menurunkannya, beri tahu saya!

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.