Sırları 1 Boyutlu Bir Labirentte Açma


41

Arka fon

Kendinizi tek boyutlu bir labirentte kaybolmuş olarak bulmak için uyanıksınız! Mistik bir cin (ya da başka bir şey) ortaya çıkar ve çıkışın önünüzde bulunduğunu açıklar, ancak siz ve çıkış arasındakiler bir dizi zorluktur. İlerledikçe, tüm bu zorlukların sadece kilitli kapılar olduğunu anlıyorsunuz . İlk önce tee şeklinde bir anahtar deliği olan bir kapı görüyorsunuz ve kendinizde böyle bir anahtar bulunmuyorsa, adımlarınızı takip edin, Tşekli olan bir anahtar arayın.

Sinirli, yerde hiçbiri rastladığınız kapıyla uyuşmayan, bir alfabe anahtar çorbası buluyorsunuz. Bir miktar deha (veya aptallık) darbesiyle, küçük harf tşeklindeki anahtarın yeterince sıkıştığında yuvaya sığabileceğine karar verirsiniz . Küçük harfli tanahtar elinizle kapıya yaklaşırken, Tdelik yeşil yanar ve kapı önünüzde çözülür.

Birincisi, gidecek çok daha fazlası ...

Meydan okuma

Bu zorluğun amacı, labirentten kaç adım attığınızı işaretlemektir.

Bu zorluğun girişi labirenttir: sadece karakter içeren bir dize [A-Za-z^$ ]. Sözlük:

  • ^- Başlangıç ​​alanı. Giriş tam olarak bir tane içerecektir ^.
  • $- Çıkış (özgürlük!). Giriş tam olarak bir tane içerecektir $.
  • [A-Z]- Büyük harfler kapıları belirtir. Bu kapıdan ancak gerekli anahtarı topladıysanız geçebilirsiniz.
  • [a-z]- Küçük harfler tuşları belirtir. Bu anahtarları, anahtarı içeren alana doğru yürüyerek toplarsınız.

Girdide her büyük harften en fazla biri olacaktır. Bu, toplam kapı sayısının 0-26 arasında olacağı anlamına gelir.

Her kilitli kapıda [A-Z]tam olarak bir tane küçük harf tuşu bulunur [a-z]. Girişte herhangi bir sayıda boşluk ( ) olabilir.

Tüm kapılar başlangıçta sağda ve çıkışta solda olacaktır. Böylece gereksiz kapılar olmayacak. Tüm girişler çözülebilir olacak.

Bu mücadelenin çıktısı, labirentten çıkmak için attığı adımların sayısı olacak.

Algoritma

Bu sefil yere çıkmak için yöntemsel yaklaşımınız şöyle:

  • Baştan ( ^) başlayın ve karşılaştığınız tüm anahtarları toplayarak ileri (sağ) ilerleyin.
  • Bir kapıya rastladığınızda, doğru anahtara sahipseniz kapıya doğru ilerlersiniz. Doğru anahtara sahip değilseniz, açamadığınız en son kapının anahtarını bulana kadar rastladığınız anahtarları toplayarak geriye doğru (solda) yürürsünüz.
  • Mevcut sorunlu kapının anahtarını topladığınızda, sağa dönün ve devam edin.
  • Exit ( $) adımına kadar bu işlemi tekrarlayın .

Deneyimli golfçüler, bu algoritmayı çalıştırdığınız ile aynı sonucu çıkardığı sürece kodunuzun bu özel algoritmayı uygulamak zorunda olmadığını anlayacaktır.

sayma

Bir kareden başka bir kareye adım attığınızda, bu bir adım olarak sayılır. 180º döndürmek, ek bir adım gerektirmez. İstenilen anahtar olmadan bir kapıya doğru ileri gidemezsiniz. Almak için bir anahtara basmalı ve kazanmak için çıkışa basmalısınız. İlk hamlenizden sonra, başlangıç ​​alanı ( ^) diğer normal boşluklar gibi davranır.

Örnekler

Bu örneklerde boşlukları insan tarafından okunabilirlik için alt çizgi olarak bıraktım.

Girdi olduğunu _a_^_A__$__. Çıktı 11. Sen almak 1için hiçbir anahtara sahip olduğunu ileri adımı, haber Akapı ve sonra yüzüne hakkında. İçinde kalan alanı kaplayana kadar geriye doğru yürüyorsunuz a( 3geriye doğru, şimdi 4toplam). Daha sonra çıkışı içeren alanı kaplayana kadar ileri yürüyün ( 7ileri, 11toplam adımlar ).

Girdi olduğunu b__j^__a_AJB_$. Çıktı, 41labirentin arkasına, biri janahtarı, diğeri anahtarı almak için iki ayrı yolculuk yaparsınız b.

Girdi olduğunu __m__t_^__x_T_MX_$____. Çıktı 44. xAnahtarı almak için fazladan bir yolculuk yapmazsınız, çünkü baştan kapıya giderken yoldan çıkardığınız gibi T.

Girdi olduğunu g_t_^G_T$. Çıktı 12. GBir anahtar olmadan ve hemen yüzün hemen etrafına gidemezsiniz . tAnahtarı anahtara götürecek kadar şanslısın gve böylece özgürlüğün yolunda iki kapıyı da aç.

Girdi olduğunu _^_____$. Çıktı 6. Kolaydı.

G / Ç Kuralları ve Kazanma Kriteri

Standart I / O kuralları geçerlidir. Bu bir mücadelesi.


17
Güzel mücadelenin yanı sıra, ifadelerin ve açıklamaların ne kadar iyi olduğunu da belirtmek isterim
Luis Mendo

4
“Böylece gereksiz kapılar olmayacak.” Bence Ade bA^aB$ya gereksiz olmaz. ;)
Martin Ender

4
@orlp İnsanların karanlık dolaşan bu algoritmayı nasıl golf oynadıklarını görmekle daha çok ilgileniyorum. "Git tüm anahtarları al sonra tüm kapıları aç" ın optimal çözümünü yapmak önemsiz görünüyor.
türbülans,

2
@ PeterTaylor ve türbülanstoo Hayır değil, kim bütün anahtarların solda ve tüm kapılar sağda? Gereksiz anahtarlar / kapılar da ilginç olurdu. Bir bağımlılık grafiği çözmek anlamına geleceği için oldukça ilginç olurdu.
orlp

5
Her kapının anahtarı var. Her anahtarın kapısı var mı?
user2357112

Yanıtlar:


3

CJam, 45

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

Çevrimiçi deneyin

Açıklama:

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 bayt

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

"iç içe" tuşları ve başlangıçtan sona kadar olan mesafeyi yok sayarak, kapıyla anahtarı arasındaki mesafeyi (iki katına çıkın, gidiş dönüş yapmak için) toplayın:

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

python2.7'de aynı algorythm:

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 bayt

Düzenleme: Çözümümden başka 20 26 bayt tıraş etmeme yardım eden yorumları için @ user2357112 ve @loovjo'ya teşekkürler !

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
İkinci ve üçüncü satırları noktalı virgülle birleştirerek bir bayt tasarruf edebilirsiniz. Ayrıca, i değişkeni döngüde gereksiz görünüyor.
Loovjo

2. ve 3. satırda anlaşılan @Loovjo, ama neden igereksiz diyorsunuz ? işu anda işlenmekte olan kapının konumunu izler ve anahtarı henüz alınmamışsa gereklidir (örneğin - eğer k- anahtarın konumu - daha azsa f- yürüdüğümüz en uzak sol - o zaman eklemeliyiz) 2*(i-k-1)toplamımız için adımlar (anahtarı almak için sola doğru yürüyün ve hemen kapıya geri dönün) ...?
Ken 'Joey' Mosher

1
Fakat beşinci hatta yer ideğiştiremedi l.index(d)ve dördüncüde görevlendirilemedi mi?
Loovjo

Ayrı eve fdeğişkenler gereksiz görünüyor. Ayrıca, l.indexbir değişkene kaydederek birkaç karakter kaydedebilirsiniz .
user2357112

@loovjo: Evet, haklısın ... İlk başta yorumunuzu yanlış anladım. @ user2357112: kesinlikle doğru. xde gereksiz. Sanırım golf noob-iness gösteriliyor. :) Yardım için teşekkürler!
Ken 'Joey' Mosher

4

C, 136 bayt

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 bayt

Bu Code Golf'taki ilk yazım, umarım bu ilk yazılan için yeterince yüksek bir golf kalitesindedir. Kesinlikle eğlenceli bir meydan okuma ve harika bir soru!

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;}

Bu program, PHP'yi kullanmadan önce herhangi bir değişkeni önceden bildirmeniz gerekmediğini kötüye kullanır.

Ayrıca, son çözümümde 0 ile başlamak ve '^' ile başlamak yerine başlangıç ​​karakteri bulunduğunda adım sayısını sıfırlamak için birkaç bayt daha kısa çıktı.

Herhangi bir ipucu kesinlikle açıktır!


3

JavaScript (ES6), 110 bayt

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)

@ Rob'ın Pyth cevabının limanı.


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 Bayt

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)}

Muhtemelen daha sıkı bir algoritma var, ama bu benim geldiğim şey.

Kullandığımı not et gawk. Bazı uygulamaları bu şekilde AWKbir dize ""bölmeyebilir.


1

C #, 309 bayt

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);}}

Ungolfed versiyonu:

    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();

    }
}

Hiçbir şey fantezi burada, sadece dize arasında yineleme ve karakter ve anahtar bir anahtar dizesinde bulunan olup olmadığını dayalı yönünü değiştirmek.

m = labirent dizesi

k = anahtar dizesi

f = yön (gerçek labirentte ileri)

b = geriye doğru arama yaparken aranacak anahtar

c = sık kullanım nedeniyle bazı baytları kaydetmek için m [j] için yer tutucu

j = aranacak dizgenin karakter dizini

t = sayım

Yine de golf oynamak için nispeten yeni, bu yüzden eğer bir yeri görürseniz zayıflatabilirim, haberim olsun!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.