이 문서가 여기저기 알려짐에 따라, 이곳에 여러가지 댓글이 달리고 있습니다. 개인적으로는 댓글창을 없애버리고 싶지만 그럴 수 없는 터라, 댓글을 달기 전에 한번씩만 더 생각해주셨으면 합니다.
- 개인적인 감상은 이곳이 아닌 다른 곳에 적어주세요.
- 동성애 혐오적인 댓글을 달지 마세요.
- 기타 "난해한 혀엉... 언어"와 관련없는 댓글을 달지 말아주세요.
위 사항들을 포함해 제 마음에 안 드는 댓글들은 임의로 삭제하고 있습니다. 양해 부탁드립니다.
…
(U+2026),⋯
(U+22EF),⋮
(U+22EE)는 모두.
(U+002E)가 3번 연속으로 나열된 것과 같은 것으로 봅니다.- "한글 음절 문자"는 가(U+AC00) 이상 힣(U+D7A3) 이하의 유니코드 문자들을 의미합니다.
- 스택의 모든 원소는 유리수 또는
NaN
으로 이루어져 있습니다. 분모가 1인 유리수를 편의상정수
라고 칭합니다.NaN
은 특수한 숫자처럼 취급됩니다. 어떠한 연산을 하더라도 그 연산에NaN
이 있을 경우 그 연산의 값은NaN
이 됩니다.
- 0번 스택은 입력된 문자들의 유니코드 문자값들의 나열입니다. (stdin). 먼저 입력된 문자가 먼저 뽑힙니다. 기본적으로 빈 스택이며 이 스택이 빈 스택일 때 뽑기 연산이 일어날 시 프로그램에서 필요한 만큼 문자 입력을 받아 스택에 저장합니다. 프로그램이 입력값을 더 이상 받을 수 없는 경우 빈 스택에서 뽑기 연산이 일어날 시
NaN
을 제공합니다. 넣기 연산이나 뽑을 값이 충분할 때의 뽑기 연산은 일반 스택처럼 작동합니다. - 1번 스택으로 넣어지는 값들은 출력됩니다. (stdout). 항상 빈 스택이며, 뽑기 연산이 일어날 경우 프로그램을 정상적으로 종료합니다.
- 이 스택에 넣어지는 모든 0보다 크거나 같은 정수들은 그에 해당하는 유니코드 문자로 출력됩니다.
- 이 스택에 넣어지는 모든 음의 정수들은 부호를 제외하고
0
(U+0030) 이상9
(U+0039) 이하에 있는 문자들을 사용하여 10진수 숫자로 출력합니다. - 이 스택에 넣어지는 모든 정수가 아닌 유리수들은 자신보다 작은 정수 중 가장 큰 정수를 택하여 위의 과정을 처리합니다.
- 이 스택에
NaN
이 넣어지는 경우너무 커엇...
을 출력합니다.
- 2번 스택으로 넣어지는 값들은 에러 문자로 출력됩니다. (stderr). 출력 규칙은 1번 스택과 동일합니다. 항상 빈 스택이며, 뽑기 연산이 일어날 경우 프로그램을 비정상적으로 종료합니다.
- 3번 스택부터는 특별한 기능을 하지 않는 일반 스택이며, 모두 기본적으로 빈 스택입니다. 프로그램 시작 시 현재 스택은 3번 스택이 됩니다. 빈 스택에서 뽑기 명령을 실행할 경우
NaN
을 제공합니다.
명령어는 연속적인 한글 음절 문자들과 뒤따라 나오는 마침표 .
(U+002E)들로 이루어져 있습니다. 전자의 문자 수를 글자 수
라고 하고, 후자의 문자 수를 마침표 개수
라고 합니다. 명령어 끝에 바로 뒤따라 하트, 물음표, 느낌표들이 나올 수 있으며 이것 역시 해당 명령어의 일부입니다. 이는 후술합니다. 프로그램은 이 명령어들의 나열로 되어 있으며, 먼저 나오는 명령어부터 순차적으로 실행됩니다. 더 이상 읽을 명령어가 없을 경우 맨 처음 명령어로 돌아옵니다. 명령어 해석에 대해선 추가적으로 후술합니다.
형
,혀엉
,혀어엉
,혀어어엉
… : 글자 수와 마침표 개수를 곱한 값을 현재 스택에 저장합니다.- 예를 들어
혀어엉....
은12
를 현재 스택에 넣습니다. 혀
와엉
사이에엉
을 제외한 한글 음절 문자를 추가적으로 넣어 글자 수를 늘릴 수 있습니다.
- 예를 들어
항
,하앙
,하아앙
,하아아앙
… : 현재 스택에서 글자 수만큼 뽑아 모두 더하여 마침표 개수에 해당하는 스택에 넣습니다.- 예를 들어
하아앙....
은 원소 세 개를 뽑아 모두 더한 다음 그 값을 4번 스택에 넣습니다. 하
와앙
사이에앙
을 제외한 한글 음절 문자를 추가적으로 넣어 글자 수를 늘릴 수 있습니다.
- 예를 들어
핫
,하앗
,하아앗
,하아아앗
… : 현재 스택에서 글자 수만큼 뽑아 모두 곱하여 마침표 개수에 해당하는 스택에 넣습니다.- 예를 들어
하아앗....
은 원소 세 개를 뽑아 모두 곱한 다음 그 값을 4번 스택에 넣습니다. 하
와앗
사이에앗
을 제외한 한글 음절 문자를 추가적으로 넣어 글자 수를 늘릴 수 있습니다.
- 예를 들어
흣
,흐읏
,흐으읏
,흐으으읏
… : 스택의 위쪽에서 글자 수만큼의 원소들의 부호를 바꾼 후 그 합을 마침표 개수에 해당하는 스택에 넣습니다.- 예로 스택이
1 0 -3 4
순으로 있고4
가 다음에 뽑힐 원소인 상태에서흐읏...
을 하면 스택은1 0 3 -4
가 되고, 3번 스택에-1
을 넣습니다. 흐
와읏
사이에읏
을 제외한 한글 음절 문자를 추가적으로 넣어 글자 수를 늘릴 수 있습니다.- 이 명령은 현재 스택에서 글자 수만큼의 뽑기 동작과 넣기 동작을 수행하는 명령입니다. 글자 수만큼 뽑아 모두 부호를 바꾼 뒤 나중에 뽑은 원소가 먼저 넣어지게 합니다. 그 후 합을 마침표 개수에 해당하는 스택에 넣습니다.
- 예로 스택이
흡
,흐읍
,흐으읍
,흐으으읍
… : 스택의 위쪽에서 글자 수만큼의 원소들을 역수로 바꾼 후 그 곱을 마침표 개수에 해당하는 스택에 넣습니다.- 예로 스택이
1 6 (-3/2) (4/7)
순으로 있고4/7
가 다음에 뽑힐 원소인 상태에서흐으읍...
을 하면 스택은1 (1/6) (-2/3) (7/4)
가 되고, 3번 스택에-7/36
을 넣습니다. 0
의 역수는NaN
이 됩니다.흐
와읍
사이에읍
을 제외한 한글 음절 문자를 추가적으로 넣어 글자 수를 늘릴 수 있습니다.- 이 명령은 현재 스택에서 글자 수만큼의 뽑기 동작과 넣기 동작을 수행하는 명령입니다. 글자 수만큼 뽑아 모두 역수로 바꾼 뒤 나중에 뽑은 원소가 먼저 넣어지게 합니다. 그 후 곱을 마침표 개수에 해당하는 스택에 넣습니다.
- 예로 스택이
흑
,흐윽
,흐으윽
,흐으으윽
… : 현재 스택에서 값을 하나 뽑아, 마침표 개수에 해당하는 스택에 글자 수만큼 복제해서 넣고, 현재 스택에 뽑았던 값을 하나 넣은 뒤, 마침표 개수에 해당하는 스택으로 이동합니다.- 예를 들어
흐윽....
은 현재 스택 맨 위에 있는 값을 4번 스택에 두 개 넣고 4번 스택으로 이동합니다.
- 예를 들어
명령어 맨 끝에 하트, 물음표 ?
(U+003F), 느낌표 !
(U+0021) 문자가 여러 개 올 수 있습니다. 이것 역시 명령어의 구성 중 하나이며, 명령어 사이를 오가게 할 수 있습니다. 이 하트, 물음표, 느낌표가 나열된 부분을 구역
이라고 부르겠습니다. 이 구역은 이전의 명령어 부분이 실행된 후 실행됩니다. 실행될 구역이 비었을 경우 실행하지 않고 다음 명령어로 넘어갑니다.
-
♥
,❤
,💕
,💖
,💗
,💘
,💙
,💚
,💛
,💜
,💝
: 글자 수와 마침표 개수를 곱한 값과 하트의 모양에 해당하는 명령어로 넘어간 뒤 그 위치에서 코드를 차례대로 실행합니다. 해당하는 명령어가 없으면 현재 명령어를 등록한 뒤 코드를 진행합니다. 만약 넘어갈 명령어가 자기 자신을 뜻하는 경우 넘어가지 않습니다.- 명령어는 등록될 수 있습니다. 예로 이전에 등록된 명령어가 없는 상태에서
흐읏...♥
을 실행할 경우 이 명령어는(6, ♥)
에 등록됩니다. 이후하앙...♥
등을 실행하면 이 위치로 돌아옵니다. - 하트는 몇 번째에 위치한 명령어로 가는 것이 아니라, 이미 정해진 명령어로 가는 동작입니다. 예를 들어,
(6, ❤)
에 명령어가 등록되어 있지 않은 경우,혀엉...❤
은 현재 명령어를(6, ❤)
에 등록합니다. 이후 어디서든지하앙...❤
을 실행할 경우(6, ❤)
에 있는혀엉...❤
으로 넘어간 뒤 명령어를 실행하게 됩니다. 이후 다음 명령어로 가면서 순차적으로 프로그램을 실행합니다. - 넘어간다는 건 코드가 읽고 있던 위치를 바꾼다는 뜻입니다. 해당하는 위치의 명령어로 간 다음, 그 명령어를 실행한 후, 코드 상으로 그 명령어 바로 다음에 있는 명령어들을 순차적으로 실행합니다.
- 명령어는 등록될 수 있습니다. 예로 이전에 등록된 명령어가 없는 상태에서
-
♡
: 등록된 명령어로 넘어가게 한 명령어 중 가장 최근에 실행된 명령어로 넘어갑니다. 없을 경우 넘어가지 않습니다.- 예로
형...♥ 혀어엉..♡ 하읏 흑...♥
은형...♥
혀어엉..♡
하읏
흑...♥
형...♥
혀어엉..♡
흑...♥
순으로 실행됩니다.형...♥
:(3, ♥)
에 자기 자신을 등록합니다.혀어엉..♡
: 넘어가게 한 명령어가 아직 없으므로 그대로 진행합니다.하읏
흑...♥
:(3, ♥)
에형...♥
이 등록되어 있으므로, 그곳으로 넘어갑니다.형...♥
:(3, ♥)
는 자기 자신을 뜻하므로, 넘어가지 않습니다.혀어엉..♡
: 가장 최근에 넘어가게 한 명령어는흑...♥
입니다. 그곳으로 넘어갑니다.흑...♥
:(3, ♥)
에형...♥
이 등록되어 있으므로, 그곳으로 넘어갑니다. 즉 이 코드는 무한히 실행될 것으로 예상됩니다.
- 위의 예제에서
형...♥
혀어엉..♡
하읏
흑...♥
형...♥
혀어엉..♡
까지 실행된 이후엔,혀어엉..♡
은 특정 명령어로 넘어가는 명령어지만,혀어엉..♡
은 등록되지 못하는 명령어이므로♡
로 인해 이 위치로 곧바로 넘어오지 못합니다.
- 예로
-
?
와!
는 구역을 나눕니다. 예로구역
이abcd?efgh
였다면, 이는abcd
구역과efgh
구역을?
로 연결시킨 것으로 해석됩니다.?
와!
는 이 두 구역 중 한 구역을 선택하는 동작을 하게 됩니다. 구역이 선택되면, 그 구역을 해석한 뒤 실행합니다. -
?
: 현재 스택에서 값을 하나 뽑아 글자 수와 마침표 개수를 곱한 값보다 작으면 물음표보다 앞부분 구역을 실행하고, 그렇지 않거나NaN
일 경우 뒷부분 구역을 실행합니다. 뽑은 값은 버려집니다.- 예를 들어,
혀엉...💗?💕
는💕
를 실행합니다.혀엉...
으로 스택에6
을 집어넣습니다.- 스택에서 값을 뽑습니다. 아까
6
을 넣었으므로 값은6
입니다. 혀엉...
에서 글자 수와 마침표 개수를 곱하면6
이 됩니다. 따라서 오른쪽 부분인💕
를 실행합니다.
- 구역 내 물음표가 여러 개일 경우, 맨 왼쪽의 물음표부터 계산됩니다.
a?b?c
는a
,?
,b?c
로 나뉩니다. - 물음표는 구역 안에서 가장 먼저 계산됩니다.
a!b?c!d
는a!b
와c!d
를?
로 연결시킨 것으로 해석됩니다.
- 예를 들어,
-
!
: 현재 스택에서 값을 하나 뽑아 글자 수와 마침표 개수를 곱한 값과 같으면 느낌표보다 앞부분 구역을 실행하고, 그렇지 않거나NaN
일 경우 뒷부분 구역을 실행합니다. 뽑은 값은 버려집니다.- 예를 들어,
혀엉...💗!💕
는💗
를 실행합니다.혀엉...
으로 스택에6
을 집어넣습니다.- 스택에서 값을 뽑습니다. 아까
6
을 넣었으므로 값은6
입니다. 혀엉...
에서 글자 수와 마침표 개수를 곱하면6
이 됩니다. 따라서 왼쪽 부분인💗
를 실행합니다.
- 구역 내 느낌표가 여러 개일 경우, 맨 왼쪽의 느낌표부터 계산됩니다.
a!b!c
는a
,!
,b!c
로 나뉩니다. - 느낌표는 구역 안에서 물음표 다음으로 먼저 계산됩니다.
- 예를 들어,
명령어 문단에서 알 수 있듯이, 명령어는 형항핫흣흡흑혀하흐
의 총 9글자 중 하나로 시작됩니다. 아래는 한 개의 명령어를 해석하는 방법을 서술합니다. 한글 글자 해석 단계부터 시작됩니다. 예상하지 못한 문자나 해석할 수 없는 문자는 모두 무시합니다. 문자가 해석이 된 후엔 바로 다음 문자로 이동합니다. 한 명령어의 해석이 끝나면 바로 다음 명령어를 해석합니다. 코드의 끝에 도달하면 더 이상 명령어를 해석할 수 없으므로 해석을 끝냅니다.
형항핫흣흡흑
의 6글자 중 하나를 만나면, 해당 글자를 해석하고 말줄임표 해석 단계로 이동합니다.혀
를 만나면 이 위치 다음엉
이 처음으로 나오는 곳까지 해석하고 말줄임표 해석 단계로 이동합니다.엉
이 나오지 않는다면 이 위치의혀
를 해석할 수 없는 문자로 처리합니다.
하
를 만나면 이 위치 다음앙
또는앗
이 처음으로 나오는 곳까지 해석하고 말줄임표 해석 단계로 이동합니다.앙
,앗
이 나오지 않는다면 이 위치의하
를 해석할 수 없는 문자로 처리합니다.- 둘 다 나온다면 둘 중 먼저 나오는 곳까지 해석합니다.
흐
를 만나면 이 위치 다음읏읍윽
세 글자 중 하나가 처음으로 나오는 곳까지 해석하고 말줄임표 해석 단계로 이동합니다.읏
,읍
,윽
이 나오지 않는다면 이 위치의흐
를 해석할 수 없는 문자로 처리합니다.- 셋 다 나온다면 셋 중 가장 먼저 나오는 곳까지 해석합니다.
- 해석할 글자들 중 한글 음절 문자가 아닌 문자는 모두 무시합니다.
- 해석할 글자들 중 한글 음절 문자만
글자 수
로 카운트합니다.
i
를0
으로 잡습니다. 아래의 과정을 진행하는 중 명령어 해석이 끝나거나 다른 해석 단계로 넘어갈 경우i
는마침표 개수
가 됩니다.- 코드의 끝에 도달하면 명령어 해석을 끝냅니다.
- 현재 위치에서부터 한글 글자 해석 단계에 의해 해석이 가능하다면 명령어 해석을 끝냅니다.
- 하트, 물음표, 느낌표 소개 문단에서 쓰이는 하트들과
?
,!
중 하나를 만나면 하트 구역 해석 단계로 갑니다. .
을 만나면i
에 1을 더해 넣고 과정2.
로 돌아갑니다. 이 문자는 해석되었다고 봅니다.…
,⋯
,⋮
중 하나를 만나면i
에 3을 더해 넣고 과정2.
로 돌아갑니다. 이 문자는 해석되었다고 봅니다.
- 현재 위치에서부터, 코드의 끝 또는 한글 글자 해석 단계에 의해 해석이 가능하기 직전까지의 구간 중 가장 짧은 문자열 구간을 잡습니다.
- 구간 내에서 하트, 물음표, 느낌표 소개 문단에서 쓰이는 하트들과
?
,!
를 제외한 모든 문자를 제거합니다. - 이 구간을
구역
으로 해석합니다.- 구역의 해석에 관해서는 하트, 물음표, 느낌표 소개 문단에 언급됩니다.
- 명령어 해석을 끝냅니다.
혀어어어어어어어엉........ 핫. 혀엉..... 흑... 하앗... 흐윽... 형. 하앙.
혀엉.... 하앙... 흐윽... 항. 항. 형... 하앙. 흐으윽... 형... 흡... 혀엉..
하아아앗. 혀엉.. 흡... 흐읍... 형.. 하앗. 하아앙... 형... 하앙... 흐윽...
혀어어엉.. 하앙. 항. 형... 하앙. 혀엉.... 하앙. 흑... 항. 형... 흡 하앗.
혀엉..... 흑. 흣
TODO
- 테스트 케이스 모음: https://github.com/xnuk/hyeong-testcases
- 웹에서 돌려보기: https://xnuk.github.io/elmhyeong/
.... 당신의 창의력에 건배