도미노를 쓰러 뜨려 라!


22

영감을 얻은 질문 덕분에

이 챌린지에서 우리는 도미노 라인을 |, /및 의 문자열로 나타냅니다 \. 입력으로 도미노 문자열이 제공되며 정착시 모양을 결정해야합니다. 다음은 도미노가 넘어지는 방법에 대한 규칙입니다.

  • 상설 도미노은 |, 왼쪽 타락한 도미노의 왼쪽 \,뿐만 아니라 왼쪽 타락한 도미노 될 것입니다.

  • |오른쪽 도미노의 오른쪽에 서있는 도미노도 /오른쪽 도미노가됩니다.

  • 서있는 도미노가 왼쪽 \타락한 /도미노 와 오른쪽 타락한 도미노 사이에 있으면 서있는 상태로 유지됩니다.

이 규칙은 배열이 더 이상 변경되지 않을 때까지 반복해서 적용됩니다.

다음은 단일 입력이 결론에 도달하는 방법에 대한 예입니다.

|||||||\/|||||||\||\|||/||||||\|||||

||||||\\//|||||\\|\\|||//||||\\|||||
|||||\\\///|||\\\\\\|||///||\\\|||||
||||\\\\////|\\\\\\\|||////\\\\|||||
|||\\\\\////|\\\\\\\|||////\\\\|||||
||\\\\\\////|\\\\\\\|||////\\\\|||||
|\\\\\\\////|\\\\\\\|||////\\\\|||||

\\\\\\\\////|\\\\\\\|||////\\\\|||||

당신의 임무는 입력의 최종 결과를 찾아서 출력하는 코드를 작성하는 것입니다. 입력이 항상 유효하고 2 자 이상을 포함한다고 가정 할 수 있습니다.

이것은 이므로 바이트 수가 적을수록 답이 바이트로 표시됩니다.

테스트 사례

|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//

6
백 슬래시 탈출 아호이! (다른 기호를 사용할 수 있습니까?)
Arnauld

1
@Arnauld 아니요 슬래시를 사용해야합니다.
밀 마법사

1
탈출 할 수없는 것과 할 수없는 것을 알아낼 수 없습니다.
완전히 인간적인

입력이 빈 문자열 또는 단일 문자입니까?
Doorknob

3
`///////// | \와 같은 것이 안정적인 것으로 간주되어야하는 것보다 더 귀찮게합니다.
MooseBoys

답변:


13

레티 나 , 32 바이트

+`(/.\\)|(/)\||\|(\\)
$1$2$2$3$3

온라인으로 사용해보십시오!

설명

+문자열은 문자열 변경에 실패 할 때까지 Retina가 교체를 루프에서 실행하도록합니다. 각 교체품은 떨어지는 도미노를 한 단계 계산합니다. 대체품 자체는 실제로 3 가지 대체품이지만 동시에 이루어집니다.

(/.\\)...
$1

이 단지 일치 /|\(물론 /\\하고 /\\있지만, 그 문제가되지 않음)하고 다시 삽입을 변경. 이것의 목적은 |양쪽에 떨어진 도미노 로 건너 뛰는 것입니다. 다른 두 경우에 별도의 둘러보기가있는 경우를 제외하는 것보다 짧기 때문입니다.

...(/)\|...
$2$2

일치 /|하고로 바뀝니다 //.

...\|(\\)
$3$3

일치 |\하고로 바뀝니다 \\.


내가 오는 것을 보지 못했다고 말할 수 없습니다. Retina는 확실히 그 일을위한 좋은 도구입니다.
밀 마법사

@WheatWizard 해결하기는 쉽지만 모든 이스케이프와 $1$2$2$3$3골프 언어를 능가 하기에는 너무 장황 합니다.
마틴 엔더


4

V , 23 바이트

òÓ¯À<!|¨Ü©ü¨¯©|ÜÀ!/±±²²

온라인으로 사용해보십시오!

실제로 이것은 망막 답변과 매우 유사합니다. 정규식 압축을 사용합니다.

16 진 덤프 :

00000000: f2d3 afc0 3c21 7ca8 dca9 fca8 afa9 7cdc  ....<!|.......|.
00000010: c021 2fb1 b1b2 b2                        .!/....

설명:

ò문자열이 변경되지 않을 때까지 V가 실행되도록 지시합니다. 나머지는 압축 정규식입니다. 그것을 vim으로 변환하자 ...

:s/\v\/@<!\|(\\)|(\/)\|\\@!/\1\1\2\2/g

:s/                                     " Substitute...
   \v                                   " Turn on magic (use less escaping)
          \|                            " A bar
            (\\)                        " Followed by a captured backslash
       @<!                              " That is not preceded by
     \/                                 " A forward slash
                |                       " OR...
                 (\/)                   " A captured forward slash
                     \|                 " Followed by a bar
                       \\@!             " That is not followed by a backslash
                           /            " Replace this with
                            \1\1        " Pattern 1 twice (will be empty if we matched the second path)
                                \2\2    " Pattern 2 twice (will be empty if we matched the first path)
                                    /g  " Replace every match on this line

4

SNOBOL4 (CSNOBOL4) , 117 (115) 112 111 바이트

	D =INPUT
S	D '/|\' ='_'	:S(S)
	E =D
	D '/|' ='//'
	D '|\' ='\\'
	D E	:F(S)
R	D '_' ='/|\'	:S(R)
	OUTPUT =D
END

온라인으로 사용해보십시오!

에 신용 로드의 파이썬 응답 변화보다는 시험을 볼 수있는 두 번째 변수 정지 조건에 대한 아이디어 D '/|' | '|\'.

	D =INPUT		;* read input
S	D '/|\' ='_'	:S(S)	;* replace '/|\' with '_', recursively
	E =D			;* set E to D, this is the while loop
	D '/|' ='//'		;* topple right
	D '|\' ='\\'		;* topple left
	D E	:F(S)		;* if D doesn't match E, goto S
R	D '_' ='/|\'	:S(R)	;* replace '_' with '/|\' (inverse of statement S)
	OUTPUT =D		;* output
END

3

하스켈 , 114 107 바이트

until=<<((==)=<<)$g
g s=t<$>zip3('|':s)s(tail s++"|")
t(l,'|',r)|l<'0',r/='\\'=l|r=='\\',l>'/'=r
t(_,e,_)=e

온라인으로 사용해보십시오! 첫 번째 줄은 익명 함수를 정의합니다.

설명:

  • until=<<((==)=<<)$g는 결과가 더 이상 변경되지 않을 때까지 입력 문자열에 함수 를 적용 하는 수정 점 함수 ( 설명 은 여기 참조 )입니다 g.
  • zip3('|':s)s(tail s++"|")각 도미노, 즉 문자열의 문자 s, 사전 및 후속 도미노가있는 트리플 |, 가장자리에 패딩을 만듭니다. 예가 /\|된다 [(|,/,\),(/,\,|),(\,|,|)](탈출 무시).
  • 그런 다음이 함수 t는 각 트리플에 적용되어 트리플의 중심 부분의 새로운 위치를 계산합니다.


2

프롤로그 (SWI) , 132 바이트

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

온라인으로 사용해보십시오!

이 프로그램은 술어를 정의합니다 +/2 두 번째 인수가 첫 번째 인수의 정식 버전 인 경우에 맞는 를 . 두 인수 모두 문자 코드 목록입니다.

설명

이 솔루션은 DCG를 사용하여 다음 단계가 무엇인지 파악한 후 다음 단계가 현재 단계와 동일 할 때까지 다음 단계를 반복적으로 계산합니다.

DCG

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.

이 다섯 줄의 코드 +는 프로그램에서 단일 도미노 토핑 단계를 계산하는 데 사용되는 DCG (Definite Clause Grammar) 규칙 을 정의합니다 . 프롤로그의 DCG는 오른쪽이 문자열과 일치하는 규칙의 첫 번째 사례를 찾고 해당 프로세스를 통해 왼쪽의 규칙 인수를 결정하여 작동합니다. 사례가 일치하지 않으면 역 추적하여 이후 사례를 시도합니다.

+[]-->[].

이 줄은 +규칙 의 기본 사례를 나타냅니다 . 현재 도미노가없는 경우 다음 단계에서 도미노가 여전히 존재하지 않는다는 것입니다.

+[47,124,92|T]-->"/|\\",+T.

이 프로그램은 문자 코드의 목록을 독점적으로 취급하기 때문에 그것은주의하는 것이 중요하다위한 문자 코드 /, \|47, 92, 124이 각각 있습니다. 이 +규칙의 경우 /|\문자열을 처리 합니다.

+[47,47|T]-->"/|",+T.

이 경우는 오른쪽으로 떨어지는 도미노를 두드리는 오른쪽 떨어지는 도미노를 처리합니다. 취급 사례 이후에 제공되므로 /|\해당 가능성에 사용되지 않습니다.

+[92,92|T]-->"|\\",+T.

왼쪽으로 떨어지는 도미노가 왼쪽으로 도미노를 두드리는 경우를 처리합니다.

+[X|T]-->[X],+T.

이것은 와일드 카드 사례입니다. 위에서 설명한 것 외에 다른 것은 바뀌지 않기 때문에 입력 문자열에 텍스트가 남아 있으면 위의 경우와 일치하지 않는 한 출력에 텍스트를 복사합니다.

술어

X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

기본 술어는 두 가지 인수를 취합니다. 첫 번째 인수는 초기 도미노 설정이고 두 번째 인수는 정착 된 도미노입니다. 이것이 프롤로그이기 때문에 두 번째는 알 수 없으며 프로그램이이를 계산합니다. 술어 자체는 +(N,X,[])DCG를 호출하는 간단한 술어이며 이를 저장하는 도미노의 다음 단계를 계산합니다 N. (X=N,Y=N;N+Y)도미노의 다음 단계가 현재와 동일한 지 확인 Y하고 도미노가 정착되었으므로 설정 되어 있는지 여부를 확인하고 그렇지 않은 경우에는 도미노 N대신 다음 단계로 동일한 술어를 호출합니다 X.



1

face , 166 바이트

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

입력을 명령 행 인수로 사용하여 STDOUT으로 출력합니다. 이것은 커밋의 버그 수정으로 인해 커밋 86494f6 이상에서만 작동합니다.

미학을 위해 감싸 인 :

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I
-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III
+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

그리고 ungolfed / 코멘트 :

\|/,cm_/o>              ( setup )

AvI[II                  ( store input into I )
cP/+PP|m_/              ( store 92, ascii for \, into P, meaning prev char )
m*/Sl*Im1/11            ( store length of input into counter variable * )

( main loop: )
:~

    -_I|'|?_1           ( branch to 1 if the character is not \ )
    -_P|?_1             ( also branch to 1 if the previous character wasn't | )
    `I-III_|+II|'I      ( we have a sequence |\ so prev needs to be toppled )
    .C                  ( jump to C, the "continue" label at end of loop )

    :1
    -_I|?_C             ( branch to C if the character is not | )
    '|-_P|?_C           ( also branch to C if the previous character wasn't / )
    _|'I-_I|`I?_!       ( branch to ! if the next character isn't \ )
    'I.C:!              ( otherwise, skip the next \ and branch to continue )
    '|'|-III+II|'I      ( if all conditions hold we have /|| or /|/ so topple )

    :C
    _|                  ( reset pointer to source )
    -PPP+PPI            ( update prev variable )
    'I                  ( step through data )

?I~

_I-PPP+PP|-**1          ( reset input/prev and decrement counter )
?*~                     ( repeat main loop as many times as there are chars )

Sl*Iw*I*>               ( output final string to stdout )

여기에 몇 가지 여분의 바이트를 제거하는 몇 가지 미묘한 트릭이 있습니다.

  • 변수의 이름 | /는 ASCII 코드에 나중에 코드에서 내부 검사를 통해 액세스합니다.

  • 그만큼 '|를 설정하기 위해 두 번째 줄에 대신가 호출 메인 루프의 첫 번째 행 | 메인 루프의 두 번째 섹션에서 사용하기위한 포인터


1

펄 5 , 52 + 1 (-p) = 53 바이트

mik 덕분에 -6 바이트

아마도 펄에게는 최선의 방법은 아니지만, 내가 생각 해낼 수있는 것입니다.

0while(s/(?<!\/)\|(?=(\\))|(?<=(\/))\|(?!\\)/$1$2/g)

설명

while(
  s/
    (?<!\/)\|(?=(//)) # If there's a | that precedes a \ but doesn't follow a /, capture /
      | # Or
    (?<=(\/))\|(?!//)/ # If there's a | that follows a / doesn't precede a \, capture /
  /$1$2/ # Replace all | with capture group 1 or 2, as one of the two will always be empty
  g # Repeat as much as possible for this string
)

온라인으로 사용해보십시오!


-p대신에 -a필요를 제거 print;한다; 사용 while더미 표현 (예에 접미사로 0) 또 다른 2 바이트 저장합니다
MIK

@ mik 감사합니다, 나는 그 트릭을 몰랐습니다. 또한 정규 표현식을 다른 바이트로 구분하여 바이트를 절약 할 수 있다는 것을 알고 있습니다. 나중에 얻을 수 있습니다.
Geoffrey H.

1

펄 5 , 44 (코드) + 1 ( -p) = 45 바이트

1while s,(/)\|(?!\\)|(?<!/)\|(\\),$1$1$2$2,g

온라인으로 사용해보십시오!

설명

1while s,                        ,        ,g   while anything found substitute globally
         (/)\|(?!\\)              $1$1         /| that is not followed by \ to //
                    |                          or
                     (?<!/)\|(\\)     $2$2     |\ that is not preceded by / to \\


0

루비 , 83 바이트

기술적으로 9.times , 또는 심지어 999.times저렴하지만 기분이 좋지 않습니다 :)

여전히 큰 골프 잠재력이 있습니다. (참고 : y while undone보다 깁니다 x.size.times)

->x{x.size.times{x.gsub! /\/\|\\?|\|\\/,'/|\\'=>'/|\\','/|'=>'//','|\\'=>'\\\\'}
x}

온라인으로 사용해보십시오!



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.