ปลดล็อกความลับสู่เขาวงกต 1 มิติ


41

พื้นหลัง

คุณตื่นขึ้นมาเพื่อพบว่าตัวเองหลงทางในเขาวงกตหนึ่งมิติ! มารลึกลับ (หรือบางอย่าง) ปรากฏขึ้นและอธิบายว่าทางออกอยู่ข้างหน้าคุณ แต่ระหว่างคุณกับทางออกนั้นเป็นความท้าทาย เมื่อคุณเดินไปข้างหน้าคุณจะพบว่าความท้าทายที่เรียกว่าทั้งหมดเป็นเพียงประตูที่ถูกล็อค ก่อนอื่นคุณจะเห็นประตูที่มีรูกุญแจรูปตัวทีและไม่มีกุญแจดังกล่าวทำตามขั้นตอนของคุณอีกครั้งมองหากุญแจที่มีTรูปร่าง

ท้อแท้คุณพบซุปตัวอักษรของกุญแจอยู่บนพื้นดินซึ่งไม่ตรงกับประตูที่คุณเจอ ด้วยสกิลอัจฉริยะ (หรือ idiocy) คุณคิดว่าtคีย์ตัวพิมพ์เล็กอาจจะสามารถใส่ในช่องได้หากคุณติดขัดในที่นั่นยากพอ ในขณะที่คุณเข้าใกล้ประตูโดยใช้tกุญแจตัวพิมพ์เล็กในมือTรูเรืองแสงสีเขียวและประตูจะละลายด้านหน้าของคุณ

ลงหนึ่งไปอีกมากมาย ...

ท้าทาย

เป้าหมายของการท้าทายนี้คือการทำเครื่องหมายว่ามีกี่ขั้นตอนที่คุณต้องออกจากเขาวงกต

การป้อนข้อมูลของความท้าทายนี้เป็นเขาวงกต: [A-Za-z^$ ]หนึ่งสายที่มีเพียงตัวอักษร คำศัพท์:

  • ^- พื้นที่เริ่มต้น ^การป้อนข้อมูลจะมีตรงหนึ่ง
  • $- ทางออก (อิสระ!) $การป้อนข้อมูลจะมีตรงหนึ่ง
  • [A-Z]- อักษรตัวใหญ่มีความหมายว่าประตู คุณสามารถผ่านประตูนี้ได้หากคุณได้รวบรวมกุญแจที่จำเป็นแล้ว
  • [a-z]- ตัวอักษรตัวพิมพ์เล็กหมายถึงกุญแจ คุณรวบรวมกุญแจเหล่านี้โดยการเดินไปยังพื้นที่ที่มีกุญแจ

จะมีตัวอักษรตัวใหญ่อย่างน้อยหนึ่งตัวในอินพุต หมายความว่าจำนวนประตูทั้งหมดจะอยู่ระหว่าง 0-26

ประตูทุกบาน[A-Z]จะมีรหัสตัวพิมพ์เล็กที่ตรงกันหนึ่ง[a-z]ตัว อาจมีช่องว่างจำนวนเท่าใดก็ได้ ( ) ในอินพุต

ประตูทุกบานจะอยู่ทางขวาของจุดเริ่มต้นและทางซ้ายของทางออก ดังนั้นจะไม่มีประตูฟุ่มเฟือย อินพุตทั้งหมดจะสามารถแก้ไขได้

ผลลัพธ์สำหรับความท้าทายนี้จะเป็นตัวเลขจำนวนขั้นตอนที่ใช้เพื่อออกจากเขาวงกต

ขั้นตอนวิธี

วิธีการที่เป็นระบบของคุณเพื่อออกจากสถานที่ที่น่าสังเวชนี้มีดังนี้:

  • เริ่มต้นที่จุดเริ่มต้น ( ^) และก้าวไปข้างหน้า (ขวา) การรวบรวมคีย์ใด ๆ ที่คุณเจอ
  • เมื่อคุณเจอประตูถ้าคุณมีกุญแจที่ถูกต้องคุณจะเดินหน้าต่อไปที่ประตู หากคุณไม่มีคีย์ที่ถูกต้องคุณจะเดินถอยหลัง (ซ้าย) รวบรวมกุญแจที่คุณเจอจนกว่าคุณจะพบกุญแจสำหรับประตูล่าสุดที่คุณไม่สามารถเปิดได้
  • เมื่อคุณรวบรวมกุญแจสำหรับประตูที่มีปัญหาในปัจจุบันคุณจะเลี้ยวกลับไปทางขวาและดำเนินการต่อไป
  • ทำซ้ำขั้นตอนนี้จนกว่าคุณจะไปที่ทางออก ( $)

นักกอล์ฟที่มีประสบการณ์จะเข้าใจว่ารหัสของคุณไม่จำเป็นต้องใช้อัลกอริทึมเฉพาะนี้ตราบใดที่ผลลัพธ์นั้นเหมือนกันกับว่าคุณใช้อัลกอริทึมนี้

นับ

ทุกครั้งที่คุณก้าวจากสี่เหลี่ยมหนึ่งไปยังอีกสี่เหลี่ยมจัตุรัสนั่นจะนับเป็นหนึ่งก้าว การหมุน180ºไม่มีขั้นตอนเพิ่มเติม คุณไม่สามารถก้าวไปข้างหน้าสู่ประตูโดยไม่ต้องใช้คีย์ที่จำเป็น คุณต้องก้าวเข้าสู่กุญแจเพื่อหยิบมันขึ้นมาและต้องก้าวเข้าสู่ทางออกเพื่อให้ชนะ หลังจากย้ายครั้งแรกพื้นที่เริ่มต้น ( ^) จะทำงานเหมือนกับพื้นที่ปกติอื่น ๆ

ตัวอย่าง

ในตัวอย่างเหล่านี้ฉันได้เว้นช่องว่างไว้เป็นขีดล่างเพื่อให้มนุษย์สามารถอ่านได้

_a_^_A__$__การป้อนข้อมูลเป็น 11เอาท์พุทเป็น คุณ1ก้าวไปข้างหน้าสังเกตว่าคุณไม่มีกุญแจสำหรับAประตูและใบหน้า คุณเดินไปข้างหลังจนกว่าคุณจะครอบครองพื้นที่ที่มีa( 3ก้าวถอยหลังไปตอนนี้4รวม) จากนั้นคุณเดินไปข้างหน้าจนกว่าคุณจะครอบครองพื้นที่ที่มีทางออก ( 7ขั้นตอนไปข้างหน้า11รวม)

b__j^__a_AJB_$ป้อนข้อมูลเป็น ผลลัพธ์คือ41คุณใช้การเดินทางสองทางแยกกันไปทางด้านหลังของเขาวงกตเพื่อให้ได้jกุญแจและอีกอันถัดไปเพื่อรับbกุญแจ

__m__t_^__x_T_MX_$____การป้อนข้อมูลเป็น 44เอาท์พุทเป็น คุณจะไม่เดินทางเพิ่มเพื่อรับxกุญแจขณะที่คุณหยิบกุญแจขึ้นมาตั้งแต่ต้นจนTจบ

g_t_^G_T$การป้อนข้อมูลเป็น 12เอาท์พุทเป็น คุณไม่สามารถย้ายไปยังGพื้นที่ว่างได้โดยไม่ต้องใช้กุญแจ คุณโชคดีพอที่จะรับtกุญแจระหว่างทางสู่gกุญแจและเปิดประตูทั้งสองข้างเพื่อไปสู่อิสรภาพ

_^_____$การป้อนข้อมูลเป็น 6เอาท์พุทเป็น นั่นเป็นเรื่องง่าย

หลักเกณฑ์ I / O และเกณฑ์การชนะ

ใช้กฎ I / O มาตรฐาน นี่คือความท้าทาย


17
นอกจากความท้าทายที่ดีแล้วฉันอยากจะสังเกตว่าถ้อยคำและคำอธิบายนั้นดีแค่ไหน
Luis Mendo

4
"ดังนั้นจะไม่มีประตูฟุ่มเฟือย" ผมคิดว่าAในbA^aB$จะไม่ฟุ่มเฟือยอย่างใดอย่างหนึ่ง ;)
Martin Ender

4
@ orlp ฉันสนใจที่จะเห็นว่าผู้คนเล่นกอล์ฟอัลกอริทึมที่หลงทางในความมืดได้อย่างไร ดูเหมือนว่าจะเป็นการแก้ปัญหาที่ดีที่สุดของ "ไปรับกุญแจทั้งหมดจากนั้นเปิดประตูทุกบาน"
turbulencetoo

2
@PeterTaylor และ turbulencetoo ไม่เป็นไรใครจะพูดว่ากุญแจทั้งหมดอยู่ทางด้านซ้ายและประตูทุกบานอยู่ทางขวา? และปุ่ม / ประตูที่ฟุ่มเฟือยก็น่าสนใจเช่นกัน มันน่าสนใจทีเดียวเนื่องจากมันจะหมายถึงการแก้กราฟการพึ่งพา
orlp

5
ประตูทุกบานมีกุญแจ กุญแจทุกดอกมีประตูหรือไม่?
user2357112

คำตอบ:


3

CJam, 45

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

ลองออนไลน์

คำอธิบาย:

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 ไบต์

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

รวมระยะห่างระหว่างประตูกับกุญแจ (เพิ่มเป็นสองเท่าเพื่อเดินทางไปกลับ) โดยไม่สนใจปุ่ม "ซ้อน" และระยะห่างจากจุดเริ่มต้นถึงจุดสิ้นสุด:

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 เดียวกันใน 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 ไบต์

แก้ไข: ขอบคุณ @ user2357112 และ @loovjo สำหรับความคิดเห็นของพวกเขาที่ช่วยให้ฉันโกนอีก20 26 ไบต์ออกจากโซลูชันของฉัน!

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
คุณสามารถรวมบรรทัดที่สองและสามกับเซมิโคลอนโดยบันทึกหนึ่งไบต์ นอกจากนี้ตัวแปร i ดูเหมือนว่าไม่จำเป็นในลูป
Loovjo

เห็นด้วยกับบรรทัดที่ 2 และ 3 @Loovjo แต่ทำไมคุณถึงพูดว่าiไม่จำเป็น? iติดตามตำแหน่งของประตูที่กำลังดำเนินการอยู่และจำเป็นถ้ายังไม่ได้รับกุญแจ (เช่นถ้าk- ตำแหน่งของกุญแจ - น้อยกว่าf- ซ้ายสุดที่เราเดินไป - จากนั้นเราต้องเพิ่ม2*(i-k-1)ขั้นตอนในการรวมของเรา (เดินไปทางซ้ายเพื่อรับกุญแจและเดินกลับไปที่ประตู) ... ?
Ken 'Joey' Mosher

1
แต่ไม่iสามารถแทนที่ด้วยl.index(d)ในบรรทัดที่ห้าและการมอบหมายโดยลบที่สี่?
Loovjo

แยกeและfตัวแปรดูซ้ำซ้อน นอกจากนี้คุณยังสามารถบันทึกอักขระจำนวนมากได้ด้วยการบันทึกl.indexเป็นตัวแปร
user2357112

@loovjo: ใช่คุณพูดถูก ... ฉันเข้าใจความคิดเห็นของคุณผิดในตอนแรก @ user2357112: ถูกต้องอย่างแน่นอน xซ้ำซ้อนเช่นกัน คาดเดา noob-iness ของฉันกอล์ฟแสดง :) ขอบคุณสำหรับความช่วยเหลือ!
Ken 'Joey' Mosher

4

C, 136 ไบต์

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 ไบต์

นี่เป็นบทความแรกของฉันเกี่ยวกับ Code Golf หวังว่านี่จะเป็นเรื่องของคุณภาพการเล่นกอล์ฟที่สูงพอสำหรับการโพสต์แรก เป็นเกมที่ท้าทายและเป็นคำถามที่ยอดเยี่ยม!

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

โปรแกรมนี้ละเมิดต่อความจริงที่ว่า PHP ไม่ต้องการให้คุณประกาศตัวแปรล่วงหน้าก่อนที่จะใช้

มันกลายเป็นว่าสั้นลงสองสามไบต์ในโซลูชันสุดท้ายของฉันที่จะเริ่มต้นที่ 0 และรีเซ็ตจำนวนขั้นตอนเมื่อพบอักขระเริ่มต้นแทนที่จะเริ่มที่ '^'

คำแนะนำใด ๆ ยินดีต้อนรับอย่างแน่นอน!


3

JavaScript (ES6), 110 ไบต์

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's Pyth


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 ไบต์

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

อาจมีอัลกอริทึมที่เข้มงวดมากขึ้น แต่นี่คือสิ่งที่ฉันคิดขึ้นมา

gawkทำทราบว่าฉันใช้ การใช้งานบางอย่างAWKอาจไม่แยกสตริง""ด้วยวิธีนี้


1

C #, 309 ไบต์

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

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

    }
}

ไม่มีอะไรแฟนซีที่นี่เพียงแค่วนซ้ำสตริงและเปลี่ยนทิศทางตามอักขระและดูว่ามีคีย์อยู่ในสตริงคีย์หรือไม่

m = สตริงเขาวงกต

k = สตริงคีย์

f = ทิศทาง (เป็นจริงไปข้างหน้าในเขาวงกต)

b = ปุ่มเพื่อค้นหาเมื่อย้อนรอย

c = ตัวยึดตำแหน่งสำหรับ m [j] เพื่อบันทึกบางไบต์เนื่องจากการใช้งานบ่อย

j = ดัชนีถ่านของสตริงที่จะดู

t = การนับ

ยังค่อนข้างใหม่กับการเล่นกอล์ฟดังนั้นหากคุณเห็นบางที่ฉันสามารถทำให้ผอมลงแจ้งให้ฉันทราบ!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.