Prindeal (발음 인쇄용 - 디 - 알은 )는 새로운 비전 : 네 개의 명령이 프로그래밍 언어 홍보 INT를 , 에 crement , 드 crement , 그리고 알 IAS . 미니멀리즘에도 불구하고 복잡한 수학 연산은 Prindeal에서 4 가지 명령을 영리하게 결합하여 수행 할 수 있습니다.
이 코드 골프 도전 과제는 Prindeal 코드를 실행할 수있는 가장 짧은 프로그램을 작성하는 것입니다.
사양은 길지만 가능한 한 명확하게 만들려고 노력했으며 Prindeal을 배우려고 노력하면 매우 우아하다고 생각합니다!
이해하기 어려운 Prindeal
전처리
Prindeal 프로그램을 해석하기 전에 다음 사항을 순서대로 제거해야합니다.
#
줄 끝의 부호 뒤에 나오는 것 외에 그#
자체. (이것은 의견입니다.)- 모든 줄에서 후행 공백.
- 완전히 빈 줄.
예를 들어 Prindeal 프로그램
p cat #The next line has 7 trailing spaces.
p dog
#p mouse
전처리 될 것
p cat
p dog
여기에서이 전처리 단계가 완료되었다고 가정합니다.
변수
사용 방법을 보여주기 전에 변수를 신속하게 정의해야합니다.
변수 (및 변수에 대한 참조)는 Prindeal 명령의 인수로 전달되는 것입니다. 변수는 항상 전역 변수 이므로 변수에 대한 수정 사항은 위치에 관계없이 모든 곳에 반영됩니다.
각 변수에는 음 이 아닌 임의 정밀도 정수 (0, 1, 2, 3, ...)가 있습니다. 변수는 사전 초기화 할 필요가 없습니다. 변수는 처음 사용하거나 호출 할 때 항상 값 0으로 시작 합니다.
- 변수의 이름은 숫자로 시작하지 않는 영숫자와 밑줄이 아닌 빈 문자열이 될 수 있습니다 [a-zA-Z_][0-9a-zA-Z_]*
에서 정규 표현식 . 그들은 대소 문자를 구분하므로 spiny_lumpsuck3r
및 Spiny_lumpsuck3r
다른 변수입니다.
실행
Prindeal은 명령형 프로그래밍 언어입니다. Prindeal 프로그램이 실행될 때 명령문 은 위에서 아래로 순서대로 실행 된 다음 프로그램이 종료됩니다.
Prindeal 프로그램의 들여 쓰기되지 않은 모든 줄은 인수를 받거나받지 않을 수있는 단일 명령의 실행을 포함하는 명령문입니다.
들여 쓰기 된 줄은 별칭 명령 뒤에 만 나타납니다 . 특히, 단일 공백으로 들여 쓰기 된 정확히 세 줄 은 모든 별명 명령 후에 발생 하며 그 일부로 간주됩니다. 그래서 별명 문은 긴 네 줄은 정말입니다. (그들은 한 줄이 될 수 있고, 4는 더 읽기 쉽습니다.)
별칭이 아닌 문장
alias를 제외 하고 Prindeal 프로그램의 모든 명령문은 다음과 같은 형식을 갖습니다.
[command name] [argument 1] [argument 2] [argument 3] ...
임의의 수의 인수가있을 수 있습니다 (아무 것도 포함하지 않음). 각 인수는 항상 변수 이거나 ( 별명을 논의 할 때 알 수 있듯이 ) 변수에 대한 참조 입니다.
실행이 완료되면 각 문은 오류 발생 여부 에 따라 실패 또는 성공 으로 표시됩니다 . (이것은 alias 사용을 할 때만 중요 합니다.)
내장 print , increment 및 decrement 는 위 형식의 명령문입니다. 그들이하는 일은 다음과 같습니다.
print 는 명령 이름을
p
가지며 하나의 인수를 취합니다. 전달 된 변수의 이름과 값 (10 진수)을 "="로 구분 한 다음 줄 바꿈을 인쇄합니다. 그것은 항상 성공으로 표시됩니다 .예를 들어 Prindeal 프로그램
p _MyVariable_321 p screaming_hairy_armadillo
출력 할 것이다
_MyVariable_321 = 0 screaming_hairy_armadillo = 0
모든 변수는 0에서 시작하기 때문에 (등호 앞뒤 공백이 필요합니다.)
incremental 에는 명령 이름이
i
있으며 하나의 인수를 사용합니다. 1에 의해 전달 된 변수의 값을 증가시킵니다. 항상 성공으로 표시됩니다 .예를 들어, 프로그램
i alpaca p alpaca i alpaca p alpaca
출력 할 것이다
alpaca = 1 alpaca = 2
alpaca
이전에 액세스 한 적이 없어도 0에서 1로 증가한 방법 에 유의하십시오 .감소 는 명령 이름을
d
가지며 하나의 인수를 취합니다. 전달 된 변수가 0이 아닌 경우 값은 1 씩 감소하고 명령문은 성공으로 표시됩니다 . 전달 된 변수가 0이면 아무 것도 수행되지 않고 명령문이 실패 로 플래그됩니다 .예를 들어, 프로그램
i malamute p malamute d malamute #success p malamute d malamute #failure p malamute d akita #failure p akita
출력 할 것이다
malamute = 1 malamute = 0 malamute = 0 akita = 0
값이 0 인 변수를 줄이는 것이 실패 를 일으키는 유일한 방법 입니다.
별명 성명 및 별칭 명령
별칭 명령은 특수 구문을 가지고 있으며,이 새 명령을 정의하는 데 사용할 수 있기 때문에 가장 강력하다. 별명 명령 이름입니다 a
및 별칭 문장의 형식은 다음과 같습니다
a [name of new command]
[statement A]
[statement B]
[statement C]
여기서 각각 [statement X]
은 별칭이 아닌 문장, 즉 형식이있는 문장을 나타냅니다 [command name] [argument 1] [argument 2] [argument 3] ...
.
별명으로 된 명령의 이름 [name of new command]
은 비어 있지 않은 영숫자 및 밑줄로, 숫자로 시작하지 않습니다 ( [a-zA-Z_][0-9a-zA-Z_]*
정규식에서).
(이것은 변수와 동일한 이름 세트이지만 별명 명령과 변수는 다른 위치에서 사용되는 것과 다릅니다 . 변수는 아무런 결과없이 명령과 동일하게 이름을 지정할 수 있습니다.)
별칭 문이 실행될 때 새 명령이 원래 네 개의 p
i
d
a
명령 과 함께 추가 됩니다. 새 명령은 [command name]
in 문 으로 사용될 수 있으며 다른 별칭이 아닌 명령 과 마찬가지로 인수와 함께 호출 될 수 있습니다 .
별명이 지정된 명령 이름을 가진 명령문이 실행될 때 원래 별명 명령문 에서 정확히 두 개의 명령문이 더 실행됩니다.
[statement A]
항상 실행[statement B]
경우 실행[statement A]
이었다 성공[statement C]
경우 실행[statement A]
했다 실패
명령문 A, B 및 C는 항상 느리게 실행됩니다 . 즉, 실행시 즉시 평가됩니다.
실행이 완료되면, 별명 지정된 명령은 명령문 B 또는 C 와 동일한 성공 또는 실패 플래그로 플래그 가 지정 됩니다 (실행 된 명령 중 하나) . ( 별명 문장 자체는 내부에서 발생할 수 없으므로 플래그를 지정할 필요가 없습니다.)
별명 예 1
변수를
frog
두 번 증가시키는 새로운 명령을 원한다고 가정 해보십시오 . 이 별명은 다음을 달성합니다.a increment_frog_twice i frog i frog d frog
명령문 A (
i frog
)는 항상 실행되고 항상 성공으로 플래그 지정 되므로 명령문 B (i frog
)도 항상 실행frog
되므로 변수 는 2 씩 증가합니다. 명령문 B는 항상 실행되고 B는 항상 a이므로increment_frog_twice
명령은 항상 성공으로 플래그됩니다 성공 . 명령문 C (d frog
)는 실행되지 않습니다.출력은
a increment_frog_twice i frog i frog d frog p frog increment_frog_twice p frog
될 것이다
frog = 0 frog = 2
그래서 우리는이 예제를 일반화 할 수 있는 변수가 앨리어스 명령을 인수함으로써 두 배 증가 할 수 있습니다.
별칭 문 내 에서 양의 정수 1, 2, 3 등은 별칭 명령에 전달 된 1, 2, 3 등의 인수를 나타냅니다. (이 인수는 일반 변수이거나 변수 자체에 대한 참조 일 수 있습니다.)이 숫자는 별명 명령문 의 명령문 A, B 및 C의 인수 내에서만 나타날 수 있습니다 . 그들이 다른 곳에 나타나는 것은 의미가 없습니다.
별명 예 2
이것은 마지막 예제를 일반화합니다. 전달 된 모든 변수는 전달 된 첫 번째 인수에 대한 참조
increment_twice
이므로 2 씩 증가합니다1
.a increment_twice i 1 i 1 d 1 #never reached p toad increment_twice toad p toad
이 프로그램의 출력은
toad = 0 toad = 2
그런 다음 두 개의 인수를 사용하여 두 명령을
increment_twice
모두 호출하는 다른 명령의 별명을 지정할 수 있습니다.a increment_twice i 1 i 1 d 1 #never reached a increment_both_twice increment_twice 1 increment_twice 2 d 1 #never reached increment_both_twice platypus duck p platypus p duck
여기서 출력은
platypus = 2 duck = 2
앨리어싱 된 명령은 재귀적일 수 있다는 점을 명심해야합니다. 예를 들어, 전달 된 변수를 0으로 설정하는 명령을 만들 수 있습니다.
별명 예 3
이
set_to_zero
명령은 하나의 인수를 사용하여 변수를 0으로 설정하고 완료되면 성공으로 표시됩니다.a set_to_zero d 1 set_to_zero 1 i _dummy_ i oryx i oryx i oryx p oryx set_to_zero oryx p oryx
이 프로그램의 출력은
oryx = 3 oryx = 0
일어나는 일은 성공적으로
set_to_zero oryx
실행되면 3에서 2로d 1
성공적으로 감소oryx
한 다음 다시set_to_zero 1
호출하는 것과 같습니다set_to_zero oryx
. 따라서 프로세스는 실패d 1
가 될 때까지 반복 되어 재귀를 중지하고 변수를 증가시켜 성공 합니다._dummy_
도전
위에서 설명한대로 정확하게 Prindeal 코드를 실행할 수있는 프로그램을 작성하십시오. 표준 코드, 명령 행 또는 텍스트 파일을 통해 Prindeal 코드를 가져옵니다. Prindeal 프로그램의 출력물을 stdout 또는 가장 가까운 언어로 인쇄하십시오.
또는 코드를 문자열로 받아서 출력 문자열을 인쇄하거나 반환하는 함수를 작성할 수 있습니다.
또한 다음과 같이 가정 할 수 있습니다.
- 입력 Prindeal 코드에는 줄 바꿈 및 인쇄 가능한 ASCII 만 포함 되며 선택적으로 빈 줄로 끝납니다.
- 입력 코드는 유효한 Prindeal이며 형식이 정확하고 구문 적으로 정확합니다.
- 코드를 실행하면 정의되지 않은 명령이나 제공되지 않은 인수에 대한 무한 루프 나 유효하지 않은 참조가 생성되지 않습니다.
- 명령 이름은
p
,i
,d
, 및a
이상 별명되지 않습니다. 변수에 이러한 이름이 없다고 가정 하지 않을 수 있습니다 .
또한 약 1000 미만의 숫자 만 테스트되므로 변수 값이 실제로 임의의 정밀도가 아닌지 여부는 중요하지 않습니다. 아래의 테스트 프로그램이 작동하는 한 더 복잡한 Prindeal 프로그램이 발생할 수있는 언어에 Python 과 같은 재귀 제한이 있으면 괜찮습니다 .
테스트 프로그램
다음은 더미 변수 ( _
규칙으로 시작 )와 많은 도우미 별명을 사용하여 더하기, 곱하기 및 지수화 작업을 작성하는 대규모 Prindeal 프로그램입니다 .
#Command Definitions:
a s #flag as a success
i _
d _
d _
a f #flag as a failure
d _
d _
d _
a z #1 = zero
d 1
z 1
s
a n #1 = one
z 1
i 1
s
a move #2 += 1, 1 = zero
moveH 1 2
move 1 2
s
a moveH #move helper
d 1
i 2
f
a dupe #2 += 1, 3 += 1, 1 = zero
dupeH1 1 2 3
dupe 1 2 3
s
a dupeH1 #dupe helper
d 1
dupeH2 2 3
f
a dupeH2 #dupe helper
i 1
i 2
s
a copy #2 = 1
z 2
copyH 1 2
s
a copyH #copy helper
dupe 1 2 _copy
move _copy 1
s
a addTo #1 += 2
copy 2 _add
#testing comments #
move _add 1#in weird places # just because #
s
#it's a g##d idea
###
a add #1 = 2 + 3
#its a good idea
z 1
addH 1 2 3
s
##
#
a addH #add helper
#this is a comment
addTo 1 2 #as is this
addTo 1 3
s
a mul #1 = 2 * 3
mulH1 1 2
mulH2 1 3
s
a mulH1 #mul helper
z 1
copy 2 _mul
s
a mulH2 #mul helper
mulH3 1 2
mulH2 1 2
s
a mulH3 #mul helper
d _mul
addTo 1 2
f
a mulBy #1 *= 2
mul _mulBy 1 2
copy _mulBy 1
s
a pow #1 = 2^3
powH1 1 3
powH2 1 2
s
a powH1 #pow helper
n 1
copy 2 _pow
s
a powH2 #pow helper
powH3 1 2
powH2 1 2
s
a powH3 #pow helper
d _pow
mulBy 1 2
f
#Running Tests:
p A
p B
p C
n A #A = 1
n B #B = 1
add C A B #C = A + B = 1 + 1 = 2
p ____
p A
p B
p C
add B A C #B = A + C = 1 + 2 = 3
p ____
p A
p B
p C
mul d B C #d = B * C = 3 * 2 = 6
p ____
p d
mulBy d B #d = d * B = 6 * 3 = 18
p ____
p d
d A #A = A - 1 = 1 - 1 = 0
mulBy d A #d = d * A = 18 * 0 = 0
p ____
p d
pow A C B #A = C ^ B = 2 ^ 3 = 8
p ____
p A
p B
p C
pow A B C #A = B ^ C = 3 ^ 2 = 9
p ____
p A
p B
p C
pow C A B #C = A ^ B = 9 ^ 3 = 729
p ____
p A
p B
p C
(이 코드를 가지고 놀고 있다면 같은 변수가 인수로 여러 번 주어지면 많은 명령이 실패한다는 것을 알고 있습니다. 이것은 쉽게 고칠 수 있지만 결과 코드는 더 길다.)
Prindeal 통역사가 정확한 결과를 산출 할 수 있어야합니다.
A = 0
B = 0
C = 0
____ = 0
A = 1
B = 1
C = 2
____ = 0
A = 1
B = 3
C = 2
____ = 0
d = 6
____ = 0
d = 18
____ = 0
d = 0
____ = 0
A = 8
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 729
채점
바이트 단위의 가장 짧은 코드가 이깁니다. Tiebreaker는 이전 제출로 이동합니다.
브라우니 보너스 : Prindeal에서 멋진 프로그램을 작성하십시오. 덧셈과 곱셈을 구현했습니다. 뺄셈이나 나눗셈을 할 수 있습니까?
p
다음p p
1을 인쇄 할 수 있습니다.