Hexagony 자기 통역의 처음 3 %를 여러분 께 소개합니다.
|./...\..._..>}{<$}=<;>'<..../;<_'\{*46\..8._~;/;{{;<..|M..'{.>{{=.<.).|.."~....._.>(=</.\=\'$/}{<}.\../>../..._>../_....@/{$|....>...</..~\.>,<$/'";{}({/>-'(<\=&\><${~-"~<$)<....'.>=&'*){=&')&}\'\'2"'23}}_}&<_3.>.'*)'-<>{=/{\*={(&)'){\$<....={\>}}}\&32'-<=._.)}=)+'_+'&<
온라인으로 사용해보십시오! 자체적으로 실행할 수도 있지만 약 5-10 초가 걸립니다.
원칙적으로 이것은 길이가 9 인 217 (이하 217 이하)에 맞을 수 있습니다. 왜냐하면 이것은 201 개의 명령 만 사용하고 처음으로 작성한 ungolfed 버전 (측 길이 30)은 178 개의 명령 만 필요했기 때문입니다. 그러나 실제로 모든 것을 실제로 적용하는 데 영원히 걸릴 것이라고 확신하므로 실제로 시도할지 확실하지 않습니다.
또한 마지막 1 개 또는 2 개의 행을 사용하지 않도록하여 크기가 10 인 비트를 골프화 할 수 있어야합니다. 따라서 후행 no-ops를 생략 할 수 있지만 첫 번째 경로 중 하나로서 상당한 재 작성이 필요합니다. 조인은 왼쪽 하단을 사용합니다.
설명
코드를 펼치고 제어 흐름 경로에 주석을 달아 보자.
그것은 여전히 꽤 지저분합니다. 그래서 여기에 제가 처음 쓴 "ungolfed"코드에 대한 동일한 다이어그램이 있습니다. 가독성을 전혀 향상시키지 않으므로 크기를 조금 더 합리적으로 만들기 위해 조금 압축했습니다.
더 큰 버전을 보려면 클릭하십시오.
색상은 몇 가지 아주 작은 세부 사항을 제외하고는 정확히 동일하며 비 제어 흐름 명령도 동일합니다. 골프 용 버전을 기준으로 어떻게 작동하는지 설명하겠습니다. 골프가 작동하는 방식을 실제로 알고 싶다면 큰 육각형의 어느 부분에 해당하는지 확인할 수 있습니다. (골치 코드는 미러로 시작하여 실제 코드는 왼쪽의 오른쪽 모서리에서 시작합니다.)
기본 알고리즘은 내 CJam 답변 과 거의 동일합니다 . 두 가지 차이점이 있습니다.
- 중심 6 각형 방정식을 푸는 대신 입력의 길이와 같거나 클 때까지 연속 중심 6 각형 숫자를 계산합니다. Hexagony에는 제곱근을 계산하는 간단한 방법이 없기 때문입니다.
- 입력없이 바로 입력을 채우는 대신 나중에 입력의 명령을 모두 사용했는지 확인하고
.
대신 입력을 인쇄합니다 .
즉, 기본 아이디어는 다음과 같이 요약됩니다.
- 길이를 계산하면서 입력 문자열을 읽고 저장하십시오.
- 전체 입력을 수용 할 수 있는 가장 작은 측면 길이
N
(및 해당 중심 육각형 숫자 hex(N)
)를 찾으십시오 .
- 직경을 계산합니다
2N-1
.
- 각 줄에 대해 들여 쓰기 및 셀 수 (합산
2N-1
) 를 계산합니다 . 들여 쓰기를 인쇄하고 셀이 인쇄되고 ( .
입력이 이미 소모 된 경우 사용 ) 줄 바꿈을 인쇄하십시오.
실제 코드가 왼쪽 모서리에서 시작하므로 (-는 $
건너 뛰 >
므로 어두운 회색 경로에서 실제로 시작됩니다 ,
).
초기 메모리 그리드는 다음과 같습니다.
따라서 메모리 포인터는 input 이라고 표시된 가장자리에서 시작하여 북쪽을 가리 킵니다. ,
STDIN에서 바이트를 읽거나 -1
EOF를 그 가장자리에 쳤다면. 따라서 <
바로 다음은 모든 입력을 읽었는지 여부에 대한 조건입니다. 지금은 입력 루프를 유지합시다. 우리가 실행하는 다음 코드는
{&32'-
이렇게하면 space 레이블이 지정된 가장자리에 32를 쓴 다음 diff 레이블이 지정된 가장자리의 입력 값에서 32를 뺍니다 . 입력에 인쇄 가능한 ASCII 만 포함되어 있기 때문에이 값은 음수 일 수 없습니다. 입력이 공백이면 0이됩니다. (Timwi가 지적했듯이, 입력에 줄 바꿈이나 탭이 포함될 수있는 경우에도 여전히 작동하지만 32 미만의 문자 코드로 인쇄 할 수없는 모든 문자를 제거합니다.)이 경우 <
명령 포인터 (IP)가 왼쪽으로 편향됩니다. 밝은 회색 경로가 사용됩니다. 이 경로는 단순히 MP로 위치를 재설정 {=
한 후 다음 문자를 읽으므로 공백을 건너 뜁니다. 그렇지 않으면 캐릭터가 공백이 아닌 경우
=}}})&'+'+)=}
관통 육각형 주변이 먼저 이동 길이 의 대향 에지까지 DIFF 와 가장자리 =}}}
. 그럼 복사 반대의 값을 길이 으로 에지 길이 와 가장자리와 간격을 )&'+'+)
. 왜 이것이 의미가 있는지 두 번째로 살펴 보겠습니다. 마지막으로 다음과 같이 새로운 엣지를 움직입니다 =}
.
(특정 에지 값은 챌린지에서 주어진 마지막 테스트 사례에서 나온 것입니다.)이 시점에서 루프는 반복되지만 모든 것이 북동쪽으로 1 육각형 씩 이동합니다. 따라서 다른 문자를 읽은 후에는 다음을 얻습니다.
이제 우리는 점차 다른 모든 가장자리에 문자로, 동북 대각선을 따라 입력 (마이너스 공간)를 작성하고, 그 문자 길이 최대 가장자리 표시에 평행하게 저장되는 것을 볼 수 있습니다 길이 .
입력 루프가 끝나면 메모리는 다음과 같습니다 (이미 다음 부분에 대해 몇 가지 새로운 모서리를 표시했습니다).
우리 %
가 마지막으로 읽은 문자이고, 29
비 공백 문자의 수입니다. 이제 육각형의 측면 길이를 찾고 싶습니다. 먼저 짙은 녹색 / 회색 경로에 선형 초기화 코드가 있습니다.
=&''3{
여기서 =&
길이 (이 예에서는 29)를 length 레이블이 지정된 가장자리에 복사합니다 . 그런 다음 3으로''3
표시된 모서리로 이동 하고 값을 계산에 상수로 설정합니다. 마지막으로 N (N-1)으로 표시된 가장자리로 이동합니다 .3
{
이제 파란색 루프로 들어갑니다. 이 루프가 증가하고 N
( N 이라는 셀에 저장 됨 ) 중심이되는 육각형 수를 계산하여 입력 길이에서 뺍니다. 이를 수행하는 선형 코드는 다음과 같습니다.
{)')&({=*'*)'-
여기서 N으로{)
이동하고 증가 합니다. N-1 이라고 표시된 모서리로 이동하여 복사 한 후 감소시킵니다. N (N-1) 의 곱을 계산합니다 . 상수에 곱하고 hex (N)으로 표시된 가장자리에서 결과를 증가시킵니다 . 예상 한대로 이것은 N 번째 중심 육각형 숫자입니다. 마지막으로 입력 길이와 그 차이를 계산합니다. 결과가 양수이면 측면 길이가 아직 충분히 크지 않고 루프가 반복됩니다 ( MP를 N (N-1)으로 표시된 가장자리로 다시 이동 ).')&(
N
{=*
'*)
3
'-
}}
측면 길이가 충분히 크면 차이가 0 또는 음수가되고 다음과 같이됩니다.
먼저 출력 루프에 필요한 초기화를 수행하는 매우 긴 선형 녹색 경로가 있습니다.
{=&}}}32'"2'=&'*){=&')&}}
{=&
에 결과를 복사하여 시작 DIFF 에 가장자리 길이 우리가 나중에이 아닌 긍정적 인 무언가를 필요로하기 때문에, 가장자리. space}}}32
레이블이 지정된 가장자리에 32를 씁니다 . diff 위의 레이블이없는 가장자리에 상수 2를 씁니다 . 같은 라벨로 두 번째 가장자리에 복사 합니다. 이 값에 2를 곱하고 증가 시켜 상단의 2N-1으로 표시된 가장자리에 올바른 값을 얻습니다 . 이것은 육각형의 직경입니다. 직경을 2N-1 이라고 표시된 다른 모서리에 복사합니다 . 마지막으로 상단에 2N-1 로 표시된 가장자리로 돌아갑니다 .'"2
'=&
N-1
'*)
{=&')&
}}
가장자리의 레이블을 다시 지정하겠습니다.
현재 켜져있는 가장자리 (여전히 육각 직경을 유지)는 출력 라인을 반복하는 데 사용됩니다. 들여 쓰기로 표시된 가장자리 는 현재 줄에 필요한 공간 수를 계산합니다. 가장자리 레이블이 지정된 셀 은 현재 줄의 셀 수를 반복하는 데 사용됩니다.
이제 indent 를 계산하는 분홍색 경로에 있습니다. 줄 반복자를 ('-
감소시키고 N-1 에서 들여 쓰기 가장자리 까지 뺍니다 . 코드의 짧은 파란색 / 회색 분기는 단순히 결과의 계수를 계산합니다 ( 음수 또는 0이면 값을 무시하고 양수이면 아무 것도 발생하지 않습니다). 나머지 분홍색 경로는 직경 에서 들여 쓰기 를 셀 가장자리 로 빼고 들여 쓰기 가장자리 로 다시 이동 하는 경로입니다 .~
"-~{
더러운 노란색 경로는 이제 들여 쓰기를 인쇄합니다. 루프 내용은 정말
'";{}(
어디 '"
받는 이동 공간 가장자리, ;
그것을 인쇄, {}
이동 백업하려면 들여 과 (
를 감소시킵니다.
완료되면 (두 번째) 어두운 회색 경로는 다음에 인쇄 할 문자를 검색합니다. =}
합니다 (상 수단, 위치 이동 셀 가장자리 남쪽을 가리키는). 그런 다음 {}
저장된 문자열의 끝에 도달 할 때까지 남북 방향으로 두 가장자리를 아래로 간단히 이동 하는 매우 단단한 루프가 있습니다 .
EOF의 한쪽 가장자리에 라벨을 붙였습니다 . . 이 문자를 처리 한 후에는 해당 모서리를 음수로 만들어 {}
다음 반복 대신 루프가 종료 되도록합니다 .
코드에서 우리는 어두운 회색 경로의 끝에 '
있으며 입력 문자로 한 단계 뒤로 이동합니다. 상황이 마지막 두 다이어그램 중 하나 인 경우 (즉, 아직 인쇄하지 않은 입력의 문자가 여전히 존재하는 경우) 녹색 경로를 사용하고 있습니다 (아래 쪽은 녹색이 좋지 않은 사람들을 위해 푸른). 그것은 매우 간단 ;
합니다. 문자 자체를 인쇄합니다. 이전부터 32를 유지하고 '
해당 공간 을 인쇄하는 해당 공간 가장자리 로 이동 ;
합니다. 그렇다면 {~
우리 EOF를 만드 나요? 다음 반복에 대해 음수이면 '
, 다시 한 단계 뒤로 이동하여 다른 단단한 }{
루프 를 사용하여 문자열의 북서쪽 끝으로 돌아갈 수 있습니다 . 길이로 끝나는세포 ( hex (N) 아래의 비 양성 세포 . 마지막으로 세포 가장자리 }
로 돌아갑니다 .
우리가 이미 입력을 다 써 버렸다면 EOF를 찾는 루프? 실제로 여기에서 종료됩니다 :
이 경우 길이 셀로 '
이동하고 대신 밝은 파란색 (상단) 경로를 사용하여 no-op를 인쇄합니다. 이 분기의 코드는 선형입니다.
{*46;{{;{{=
이 {*46;
태그는 no-op 라고 표시된 가장자리에 46을 쓰고 인쇄합니다 (예 : 마침표). 그런 다음 공간 가장자리로 {{;
이동하여 인쇄합니다. 받는 뒤로 이동 세포는 다음 반복 가장자리.{{=
이 시점에서 경로는 다시 함께 가입 (
감소 세포의 가장자리. 반복자가 아직 0이 아닌 경우 밝은 회색 경로를 사용하여 MP의 방향을 반대로 바꾸고 =
다음 인쇄 할 문자를 찾습니다.
그렇지 않으면 현재 행의 끝에 도달했으며 IP가 대신 자주색 경로를 사용합니다. 그 시점에서 메모리 그리드는 다음과 같습니다.
자주색 경로에는 다음이 포함됩니다.
=M8;~'"=
는 =
다시 MP의 방향을 반전시킵니다. is 의 문자 코드가 현재 값에 추가 되기 때문에 M8
값을로 설정합니다 . 이것은로 발생 하므로로 인쇄 하면 줄 바꿈 이 발생합니다 . 그런 다음 가장자리를 다시 음수 로 만들고 선 가장자리 로 다시 이동 하여 MP를 한 번 더 반전시킵니다.778
M
77
10 (mod 256)
;
~
'"
=
이제 선 가장자리가 0이면 끝났습니다. IP는 (매우 짧은) 빨간색 경로를 사용 @
하여 프로그램을 종료합니다. 그렇지 않으면, 우리는 다른 경로를 인쇄하기 위해 분홍색 경로로 다시 돌아가는 자주색 경로를 계속합니다.
Timwi의 HexagonyColorer로 작성된 제어 흐름도 . Esoteric IDE 의 비주얼 디버거로 작성된 메모리 다이어그램 .
abc`defg
실제로 될 것 pastebin.com/ZrdJmHiR