전주곡 구문 검사기


10

Prelude 는 밀교 프로그래밍 언어로, 유효한 프로그램을 구성하는 것에 대한 제한은 거의 없지만 드문 경우입니다. 다음과 같은 경우 인쇄 가능한 ASCII 텍스트 블록 ( "블록"은 인쇄 가능한 ASCII 행이 줄 바꿈으로 구분됨을 의미 함)입니다.

  • 텍스트의 모든 (수직) 열에는 (과 중 하나만 포함됩니다 ).
  • 수직 위치를 무시하고 ()균형을 잡습니다. 즉, 각각 ()오른쪽에 정확히 하나와 쌍을 이룹니다 .

인쇄 가능한 ASCII 및 줄 바꿈이 포함 된 문자열이 유효한 Prelude 프로그램을 구성하는지 확인하는 프로그램 또는 함수를 작성하십시오. STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을받을 수 있습니다. 선택한 고정 고정 / 거짓 값을 사용하여 결과를 STDOUT으로 반환하거나 인쇄 할 수 있습니다 .

입력이 직사각형이라고 가정 해서는 안됩니다 .

이것은 코드 골프이므로 가장 짧은 제출 (바이트)이 이깁니다.

유효한 Prelude 프로그램 은 다음과 같습니다 (사실 실제 Prelude 프로그램 임).

?1-(v  #1)-             
1   0v ^(#    0)(1+0)#)!
    (#)  ^#1-(0 #       
1(#  1) v #  - 1+)
    vv (##^v^+
? v-(0 # ^   #)
?
  1+              1-!

그리고 여기에 많은 입력이 있으며, 모두 유효하지 않습니다 :

#(#(##)##)##(
)##(##(##)#)#
#(#)
)###
#(##
(##)
(##)
(#)#
(##)
(###
#(#)
(##)
#(#)
###)
#()#
()##
#(#)##
###
###(#)

Prelude에 가까운 깎기를 막을 수있는 설명이 있습니까?
Alex A.

@Alex 아니요. 위의 규칙은 실제로 프로그램이 유효한지 여부를 결정하는 데 필요한 모든 것입니다.
Martin Ender

설명해 주셔서 감사합니다. 그냥 확인하고 싶었습니다.
Alex A.

규칙 1- "모든 텍스트 열에는 (및) 중 최대 하나가 포함됩니다"; 예 1, 2 행 : "1 0v ^ (# 0) (1 + 0) #)!" -> 3 )과 2를 (봅니다. 한 줄에 1이 아니어야합니까?
Ismael Miguel

1
@IsmaelMiguel "열" 은 일반적으로 수직선 (특히 그리드와 관련하여)을 나타내는 것으로 이해됩니다. 어쨌든 나는 그것을 명확히했다.
마틴 엔더

답변:


3

CJam, 57 56 바이트

qN/z_{_"()"--W<},,\s:Q,{)Q/({_')/,\'(/,-}:T~\sT0e>+z+}/!

너무 길면 골프를 많이 할 수 있습니다. 골프를 치고 나면 설명이 추가됩니다.

간단한 설명

코드에는 두 가지 검사가 있습니다.

  • 첫 번째 필터는 각 열이 최대 1 개의 브래킷인지 확인합니다. 필터의 최종 출력은 대괄호가 두 개 이상인 열 수입니다.
  • 두 번째로 입력을 열 주요 형식으로 변환 한 다음 각 인덱스에서 두 부분으로 나눕니다.
    • 이 두 부분 각각에서 ( Number of "(" - Number of ")")는 서로를 보완해야합니다. 따라서 추가 할 때 결과는 0이되어야합니다.이 속성에 실패하면 전체 입력에 대괄호가 일치하지 않습니다.
    • 또한 "("가 ")"의 왼쪽에 있는지 확인해야합니다. 즉 Number of "(" - Number of ")", 오른쪽 블록 의 값은 음수 일 수 없습니다.

여기에서 온라인으로 사용해보십시오


6

파이썬 2, 128 119 105 바이트

def F(p):
 v=n=1
 for r in map(None,*p.split("\n")):A,B=map(r.count,"()");n+=B-A;v*=n<2>A+B
 return n*v>0

Python 2에서 None매핑 할 수 있다는 것을 알고 있습니까?

설명

열이 행이되도록 Prelude를 바꿈으로써 시작하려고합니다. 일반적으로 우리는 이것을 사용 zip하지만 zip가장 짧은 행 길이로 자르고 itertools.zip_longest코드 골프에 비해 너무 길기 때문에 원하는 것을 할 수있는 짧은 방법이없는 것 같습니다 ...

매핑을 제외 None:

>>> print map(None,*[[1,2,3],[4],[5,6]])
[(1, 4, 5), (2, None, 6), (3, None, None)]

불행히도 (또는 불행히도 모든 골프 이외의 목적으로), 이것은 Python 2에서만 작동합니다.

에 관해서 nv:

  • n스택처럼 작동합니다 1 - <number of unmatched '(' remaining>. 모든 들어 (우리는 우리가 일을 빼기보고, 모든을 위해 )우리가 보는 우리는 1. 따라서 경우 추가 n >= 2어느 시점에, 우리는 너무 많은 본 적이 )들과 프로그램이 잘못되었습니다. 경우 n1에 완료되지 않습니다, 우리는 적어도 하나의 타의 추종을 불허이 (남아.
  • v유효성을 검사하고 1에서 시작합니다. 프로그램이 유효하지 않은 경우 ( n >= 2또는 A+B >= 2), 유효하지 않은 v것으로 표시하려면 0이됩니다.

따라서 프로그램이 유효하다면 결국 우리는 있어야합니다 n = 1, v = 1. 프로그램이 유효하지 않다면 결국에는 v = 0, 또는 이 있어야합니다 v = 1, n <= 0. 따라서 유효성은 간결하게로 표현 될 수 있습니다 n*v>0.

(14 바이트를 벗어난 많은 좋은 제안에 대해 @feersum에게 감사드립니다!)

더 읽기 쉬운 이전 제출 :

def F(p):
 p=map(None,*p.split("\n"));v=n=0
 for r in p:R=r.count;A=R("(");B=R(")");n+=A-B;v|=A+B>1or n<0
 return n<1>v

그것은 미친 짓입니다 map...
xnor

1
def F(p): v=n=3 for r in map(None,*p.split("\n")):A,B=map(R.count,"()");n+=A-B;v*=n>2>A+B return n*v==9
119-

@feersum 감사합니다! 나는를 변경하려고하고 있었다 or비교 체인으로,하지만 난 변화를 생각하지 않았다 |=으로 *=. 더 많은 것을 뒤로 함으로써 다른 바이트를
빼앗았다.

2

J, 64 바이트

입력은 줄 바꿈 문자가있는 문자열입니다. 출력은 0 또는 1입니다.

(0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)

사용법 예

   ]in=.'#(#)##',LF,'###',LF,'###(#)',LF
#(#)##
###
###(#)

   ((0=(1<|s)s+[:(|@{:+(0>])s)[:+/\]s=.+/@:)@(1 _1 0{~[:'()'&i.];.2)) in
0

방법은 다음과 같습니다

  • 줄 바꿈에서 입력을 자르고 행렬에 넣습니다. ];.2
  • 지도 (/ )/ anything else1/ -1/0 1 _1 0{~[:'()'&i.]
  • s=.+/@:동사에 추가 된 부사를 정의 하여 동사 배열 출력을 합산
  • 열에 값을 추가 ]s

    • ()모든 접두사에서 긍정적 인 균형을 확인하십시오[:(0>])s)[:+/\]
    • ()전체 목록에서 동일한 균형을 확인 하십시오 (즉, 마지막 접두사에서) |@{:@]
  • 열에 abs (values)를 추가하고 모든 요소의 최대 값이 1인지 확인하십시오. (1<|s)s

  • 이전의 모든 검사가 실패했을 때 양의 결과를 얻었으므로 우리는 그것들을 더하고 0과 비교하여 입력의 유효성을 얻습니다 0=]


2

J, 56 바이트

3 :'*/0<: ::0:(+/\*:b),-.|b=.+/+.^:_1]0|:''()''=/];.2 y'

이것은 줄 바꿈 문자가있는 문자열을 수락하고 0 또는 1을 반환하는 익명 함수입니다.

  • ];.2 y다른 J 제출에서와 같이 y마지막 문자가 발생할 때마다 문자열 을 자르고 (입력에 후행 줄 바꿈이 필요한 이유) 행이 조각 인 사각형 행렬을 만들고 필요한 경우 공백으로 채 웁니다.

  • '()'=/이 행렬의 모든 문자를 먼저 비교 (한 다음 )두 개의 0-1 행렬 목록을 반환합니다.

  • +.^:_1]0|:두 행렬 목록을 복소수의 단일 행렬로 바꿉니다. 지금까지 프로그램은 (입력의 모든 것을 1로, 모든 )것을 i로, 다른 모든 문자를 0 으로 바꿉니다 .

  • b=.+/해당 복소수 행렬의 행 합계를에 할당합니다 b.

  • -.|b1- | z |의 목록을 만듭니다. 모든 Z 대 b. 모든 열이 최대 하나의 괄호를 포함하는 조건은이 모든 숫자로 변환됩니다 1- | z | 음수가 아닙니다.

  • +/\*:b의의 제곱에 대한 누계의 벡터입니다 b. 모든 열에 최대 하나의 괄호가 포함 된 경우 숫자의 제곱 b은 모두 0, 1 또는 -1입니다. 이 ,벡터를 1- | z |의 벡터와 연결합니다.

  • 이제 우리 모두는 우리의 연결된 벡터의 항목이 있는지 테스트하기 만하면 v음이 아닌 실수 번호이 거의이다,이다 */0<:v의 일부 항목이있는 경우 오류가 발생하는 것을 제외하고, v우리가 바꿀 수 있도록, 실제 없습니다 <:<: ::0:단지 오류의 경우에는 0을 반환 .


복잡한 숫자로 된 훌륭한 아이디어이지만 0={:+/\*:b예를 들어 (유효하지 않기 때문에 확인해야 합니다.
randomra

아, 맞아요, @randomra, 잊어 버렸습니다!
Omar

1
0=(-|)v음이 아닌 실수를 확인하기 위해 2 바이트가 짧습니다. (CJam을 이길 보자! : P)
randomra

1
아, inv대신 ^:_1 다른 바이트 를 저장합니다.
randomra

1
56으로 돌아 가기 (밸런스 점검 사용) : 3 :'*/0=({:,]-|)(-.@|,+/\@:*:)+/+.inv]0|:''()''=/];.2 y'.
randomra
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.