1 차원 미로의 비밀을 밝히다


41

배경

당신은 일차원 미로에서 길을 잃은 것을 발견하기 위해 깨어 있습니다! 신비로운 요정 (혹은 무엇인가)이 나타나고 출구가 당신 앞에 놓여 있다고 설명하지만, 출구와 출구 사이에는 일련의 도전이 있습니다. 당신이 앞으로 돌아 다니면서 당신은 모든 소위 도전 이 단지 잠겨진 문 이라는 것을 알고 있습니다. 먼저 티 모양의 열쇠 구멍이있는 문을보고, 그런 열쇠가없는 경우에는 걸음을 되찾아 T모양이 있는 열쇠를 찾으십시오 .

좌절, 당신은 지상에 열쇠의 알파벳 수프를 발견하고, 어느 것도 당신이 겪은 문과 일치하지 않습니다. 천재 (또는 관용구)를 치기 때문에 소문자 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
"따라서 불필요한 문은 없을 것이다." 내 생각 AbA^aB$하나 불필요한 없을 것이다. ;)
Martin Ender 2016 년

4
@orlp 저는 사람들이이 방랑하는 알고리즘을 어떻게 골프화하는지 보는 데 더 관심이 있습니다. "모든 열쇠를 가져 가서 모든 문을 열어 라"는 최적의 해결책을 취하는 것은 사소한 것 같습니다.
turbulencetoo

2
@PeterTaylor and 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

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

파이썬 2 155 154 134 128 바이트

편집 : 내 솔루션에서 다른 20 26 바이트를 면도하는 데 도움이 된 의견을 주신 @ user2357112 및 @loovjo에게 감사드립니다 !

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
두 번째와 세 번째 줄을 세미콜론과 결합하여 1 바이트를 절약 할 수 있습니다. 또한 루프에서 i 변수가 필요하지 않은 것 같습니다.
Loovjo

@Loovjo의 두 번째와 세 번째 줄에 동의했지만 왜 i불필요 하다고 말 합니까? i현재 처리중인 도어의 위치를 ​​추적하며 키를 아직 가져 오지 않은 경우 (예 : k키의 위치가 f-가장 왼쪽으로 걷은 거리보다 작은 경우) 필요한 경우 추가해야합니다. 2*(i-k-1)우리의 총계까지 단계 (키를 얻기 위해 왼쪽으로 걸어 가고 문으로 다시 걸어 감) ...?
Ken 'Joey'Mosher

1
그러나 다섯 번째 줄로 i대체 할 수없고 l.index(d)네 번째 줄에서 배정을 제거 할 수 없었 습니까?
Loovjo

개별 변수 ef변수는 중복되어 보입니다. 또한 l.index변수 에 저장하여 많은 문자를 저장할 수 있습니다.
user2357112

@loovjo : 네, 맞아요. 처음에 당신의 의견을 오해했습니다. @ user2357112 : 절대적으로 맞습니다. x중복됩니다. 내 골프 멍청한 듯함이 보이고 있다고 생각합니다. :) 도와 주셔서 감사합니다!
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

자바 스크립트 (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의 Pyth 답변 포트.


2

파이썬 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.