도전
당신의 도전은 리스프와 같은 언어를위한 통역사를 디자인하는 것입니다. GLisp . GLisp 의 프로그램 코드 는 다음과 같은 형식으로 대괄호로 표시되는 임의의 양의 중첩 표현식으로 구성됩니다.
(func arg1 arg2 ...)
인터프리터는 대괄호, 함수 및 인수 앞뒤에 공백 문자를 허용해야합니다.
종류
정수, 목록, 부울 및 함수의 네 가지 유형을 구현합니다. 자체 구문을 사용하여 정수 및 부울 값을 소스 코드에 명시 적으로 삽입 할 수 있습니다. 인터프리터는 숫자 문자가 정수를 나타내는 것으로 가정해야합니다 (음수를 명시 적으로 삽입하기 위해 구문을 구현할 필요는 없습니다). 귀하의 인터프리터는 것을 가정해야 true
하고 false
부울 값을 지정합니다. 함수는 사용자가 명시 적으로 정의 할 수 없으며 항상 단일 값 (모든 길이의 목록이 단일 값으로 계산 됨)을 리턴합니다.
기능
다음 기능을 구현해야하며 Function , Arity 형식으로 되어 있습니다. Arity n
가 더하기 부호로 진행 되면, 이는 n
하나 이상의 인수 를 나타냅니다 . 달리 명시되지 않는 한 함수에 제공된 모든 인수는 동일한 유형이라고 가정 할 수 있습니다. certian 유형에 대해 동작이 지정되지 않은 경우 해당 함수의 인수가 해당 유형의 인수가 아니라고 가정 할 수 있습니다. 인수는 다음 다이어그램에서 언급됩니다.
(func argument1 argument2 ... argumentn)
+ , 2+
- 모든 인수가 Integer 유형 인 경우 인수의 합계를 리턴해야합니다.
- 모든 인수가 List 유형 인 경우 인수의 연결을 오름차순 (
arg1+arg2+ ...
) 으로 리턴해야합니다. - 모든 인수가 Boolean 유형 인 경우 논리적 인 모든 인수 시퀀스를 리턴해야합니다.
(+ 1 2 3 4 5) -> 15
(+ (list 1 2) (list 3 4)) -> (list 1 2 3 4)
(+ true true true) -> true
- , 2+
- 모든 인수가 Integer 유형 인 경우 인수의 차이 (
arg1-arg2- ...
)를 리턴해야합니다. - 모든 인수가 Boolean 유형 인 경우 논리 인수의 모든 인수 를 리턴해야합니다.
(- 8 4 3) -> 1
(- 0 123) -> -123
(- true false false true false) -> true
- 모든 인수가 Integer 유형 인 경우 인수의 차이 (
* , 2+
- 모든 인수가 Integer 유형 인 경우 인수의 곱을 리턴해야합니다
- 하나의 인수가 List 유형 이고 다른 하나의 인수가 Integer 유형 인 경우 (주어진 인수 만 가정 할 수 있음) 반복 된 항목으로 항목과 함께 새 List 를 리턴해야합니다 .
arg1
arg2
(* 1 2 3 4 5) -> 120
(* (list 1 2 3) 2) -> (list 1 2 3 1 2 3)
/ , 2+
- 모든 인수가 Integer 유형 인 경우 인수의 몫을 리턴해야합니다 (
arg/arg2/ ...
) (분할이 순차적으로 수행되고 모든 단계에서 소수 부분이 잘 린다고 가정 할 수 있음) - 하나의 인수가 List 유형 이고 다른 인수가 Function 유형 인 경우 모든 값에 대해 맵핑 된 후 결과 List를 리턴해야합니다.
arg2
(/ 100 10 3) -> 3
(/ (list 1 2 3) inc) -> (list 2 3 4)
- 모든 인수가 Integer 유형 인 경우 인수의 몫을 리턴해야합니다 (
% , 2
- 모든 인수가 Integer 유형 인 경우 인수의 계수를 리턴해야합니다.
(% 4 2) -> 0
= , 2+
- 만약 두 모든 인수의 유형과 값이 같은, 당신은 진정한 반환해야합니다. 그렇지 않으면 false를 반환하십시오.
(= 0 0 0) -> true
(= 0 false (list)) -> false
list , 0+
- 유형에 관계없이 모든 인수 목록을 리턴해야합니다. 인수가 없으면 빈 목록을 반환해야합니다.
(list 3 4 (list 5)) -> (list 3 4 (list 5))
inc , 1
- 인수가 유형 인 경우 Integer 1 씩 증가한 Integer 를 리턴해야합니다.
- 인수가 List 유형 인 경우 시계 방향으로 한 번 회전 한 List를 단일 회전으로 반환해야합니다.
(inc 1) -> 2
(inc (list 1 2 3)) -> (list 3 1 2)
12 월 1 일
- 인수가 정수 유형 인 경우 1 씩 감소한 정수 를 리턴해야합니다.
- 인수가 List 유형 인 경우 시계 반대 방향으로 회전 한 List를 단일 회전으로 반환해야합니다.
(dec 1) -> 0
(dec (list 1 2 3)) -> (list 2 3 1)
만약 3
- 모든 유형의 인수가 세 개인 경우 :의
arg1
true 값 이 true이면 returnarg2
, 그렇지 않으면 returnarg3
(if (not (list 1)) 8 false) -> false
- 모든 유형의 인수가 세 개인 경우 :의
아니 , 1
- 임의의 유형의 인수가 제공되면 true 값
arg1
이 False이면 returntrue
, 그렇지 않으면 returnfalse
. (not (list)) -> true
- 임의의 유형의 인수가 제공되면 true 값
렌 , 1
- 형의 인수 주어진 경우 목록 의 길이를 반환
arg1
(len (list 4 2 true (list 3) (list))) -> 5
- 형의 인수 주어진 경우 목록 의 길이를 반환
진리표 :
0, (list), false -> false
여기서 (list)
빈 목록을 나타냅니다. 다른 모든 것입니다 true
.
인터프리터는 stdin 또는 파일에서 소스 입력을 읽는 전체 프로그램이거나 소스를 문자열로 가져 와서 출력 값을 반환하는 함수일 수 있습니다.
전자를 선택하는 경우 정수 의 출력 은 단순히 숫자이고 부울 은 true
또는의 경우 false
, 목록은 공백으로 구분 된 값의 대괄호로 묶인 일련의 값입니다 (예 : (1 2 3 4 (5 6 7))
표시 (list 1 2 3 4 (list 5 6 7))
).
후자를 선택하는 경우 구현 언어의 해당 유형으로, 또는 유사한 유형이없는 경우 사용자 정의 유형으로 값을 리턴해야합니다. 목록은 언어가없는 경우 배열 또는 벡터로 반환 할 수 있습니다 목록 유형을, 부울는 언어 부울 유형 또는 언어를 지원하지 않는 경우 사용자 정의 형식으로 반환해야합니다.
테스트 사례
(list 1 2 3 (list 4 5 true)) -> (1 2 3 (4 5 true))
(/ 4000 (+ 1 2 3 4 (* 5 8))) -> 80
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true) -> true
(if ( len (list ) ) 4 (if (+ (= 8 8 8) (not (list 4))) 8 5)) -> 5
설명
- 통역사는 선택한 방식으로 유효하지 않은 입력을 처리 할 수 있지만 예외를 발생 시키지 않아야합니다 (오류 메시지를 인쇄하고 부드럽게 종료 될 수 있음)
- 함수는 항상 왼쪽에서 오른쪽으로 인수를 평가합니다
- 유효하지 않은 입력은 구문 상 올바르지 않은 입력입니다. 여기에는 불일치 한 대괄호, 0으로 나누기 및 부분적으로 적용되는 기능이 포함되지만 이에 국한되지는 않습니다 (보너스 제외)
- 의 경우
=
, 값이 다르거 나 유형이 다른 경우false
보너스
- 부분적으로 적용된 기능을 지원하는 경우 * 0.8을 기록 하십시오. 예를 들어,
((+ 2) 3)
같은 것(+ 2 3)
,하지만 같은 것들을 할 수 있습니다(/ (list 1 2 3) (+ 2))
. 함수가 최소 인수 수보다 적은 수의 함수를 수신하면 부분적으로 적용되었다고 가정 할 수 있습니다. - 인수
if
가 반환되지 않는 한 적용된 인수를 평가하지 않으면 점수 * 0.85
이것은 코드 골프이므로 바이트 수가 가장 적은 인터프리터가 승리합니다!
(+ 3 (if false 5))
합니까? 일반적으로 "무언가를 돌려주는 것"은 무엇입니까? 재조정 할 단위 유형을 지정하지 않았습니다
(+ bool bool...)
논리 AND와 (- bool bool...)
논리 OR 이 다른 이유는 무엇 입니까? 표준 링 표기법은 +
OR 및 *
AND에 사용됩니다. 2. "유효하지 않은 입력" (/ 2 0)
은 구문 적으로 올바른 경우를 다루기위한 것 입니까? 에 대해 =
, 값이 모두 같지 않으면 false
?를 반환해야 합니까? 4. 정의는 not
거꾸로 나타납니다. 5. 토큰은 무엇입니까? 인터프리터는 여분의 공백을 처리해야하지만 어떤 공백을 사용할 수 있는지 말하지 않습니다. 이와 같은 복잡한 질문의 경우 사양을 확인할 수 있도록 샌드 박스를 사용해야합니다.
((+ 2 3) 4)
같 9
거나 오류입니까? 특히 var-arg 함수의 경우 언제 응용 프로그램을 부분적으로 고려해야하는지 명확하지 않습니다. 그것은 같은 것들로도 muddier를 얻을 수((if true (+ 2 3) (- 5)) 4)
(if (not (array 1)) 8 false) -> false
합니까?