Hexagony 소스 코드 펼치기


52

소개

Hexagony에 익숙하지 않다면 Martin Büttner가 만든 난해한 언어입니다. 문제는이 언어가 프로그램에 여러 형식을 허용한다는 것입니다. 다음 프로그램은 모두 동일합니다.

abcdefg

 a b
c d e
 f g

기본적으로 코드는 일반 육각형으로 롤업되었습니다. 그러나 코드에 새 명령을 추가 abcdefgh하면 다음과 같은 프로그램이 생성됩니다.

  a b c
 d e f g
h . . . .
 . . . .
  . . .

보시다시피, 첫 번째 단계는 코드를 육각형으로 롤업 한 후 육각형이 .다음 중심 육각형 수에 op ( )로 채워지는 것입니다 .

문자열 (소스 코드)이 주어지면 전체 육각 소스 코드를 출력하면 작업이 간단합니다.

규칙

  • 프로그램이나 기능을 제공 할 수 있습니다.
  • 선행 공백은 허용되지만 육각형이 모양이 아닌 경우에만 허용됩니다.
  • 후행 공백이 허용됩니다.
  • 프로그램의 공백 은 무시 됩니다. 그래서 a b c동일abc
  • 인쇄 가능한 ASCII 문자 ( 32 - 126) 만 사용되므로 일반 Space문자 만 무시됩니다.
  • 문자열의 길이가 0보다 크다고 가정하십시오.
  • 이것은 이므로 바이트 수가 가장 적은 제출이 승리합니다!

테스트 사례

Input: ?({{&2'2':{):!/)'*/

Output:
  ? ( {
 { & 2 '
2 ' : { )
 : ! / )
  ' * /


Input: H;e;l;d;*;r;o;Wl;;o;*433;@.>;23<\4;*/

Output:
   H ; e ;
  l ; d ; *
 ; r ; o ; W
l ; ; o ; * 4
 3 3 ; @ . >
  ; 2 3 < \
   4 ; * /


Input: .?'.) .@@/'/ .!.>   +=(<.!)}    (  $>( <%

Output:
   . ? ' .
  ) . @ @ /
 ' / . ! . >
+ = ( < . ! )
 } ( $ > ( <
  % . . . .
   . . . .

6
또한, 당신이 그 까다 롭고 싶어하는지 확실하지 않지만, 다음 문자에 주석을 달기 때문에 코드 너비를 결정하는 과정에서 백틱이 무시됩니다. 그래서 abc`defg실제로 될 것 pastebin.com/ZrdJmHiR
마틴 청산

2
@ MartinBüttner 아, 나는 그것을 몰랐다 :). 이 문제의 경우, 백틱은 무시되지 않습니다.
Adnan

18
이 질문에 대한 Hexagony의 답변을 정말로보고 싶습니다.
Arcturus

2
@Adnan 아마도 더 나은 응답은 "입력에 디버그 플래그 ( `문자) 가 없다고 가정 할 수 있습니다" 입니다.
Riking

4
@Ampora Ask 그리고 당신은받을 것이다.
Martin Ender

답변:


13

피스, 57 54 50 49 48 46

V+UJfgh*6sUTlK-zd1_UtJ+*d-JNjd:.[K\.^TJZ=+Z+JN

테스트 스위트

각 줄에 선행 공간을 인쇄합니다.

이 버전은 모든 n> = 1에 대해 10 ^ n> = 3n (n-1) + 1 이라는 증명이 필요합니다 . 증거를 제공 한 ANerdIErickWong 에게 감사합니다 .

다음과 같은 불평등을 따르는 경우 : 10 ^ n> (1 + 3) ^ n = 1 + 3n + 9n (n-1) + ...> 3n (n-1) + 1 이것은 n에 대해 올바른 것을 쉽게 볼 수 있습니다 > = 2 . n = 1 사례를 조사하는 것은 사소한 일로 10> 1을 제공 합니다.

대안 적으로, 이들 방정식의 도함수를 두 번 취하면 10 ^ n 은 모든 n> = 1에 대해 더 큰 2 차 도함수를 가짐 을 알 수 있으며, 이는 1 차 도함수로 그리고 마지막으로 원래 식까지 연속 될 수 있습니다.

설명

              ##  Implicit: z=input(); Z=0
Jf...1        ##  Save to J the side length of the hexagon the code fills up
              ##  by finding the first number such that:
gh*6sUT       ##  the the T'th hexagonal number is greater than...
              ##  Computes 6 * T'th triangular number (by using sum 1..T-1) + 1
    lK-zd     ##  ...the length of the code without spaces (also save the string value to K)
V+UJ_UtJ      ##  For loop over N = [0, 1, ..., J-1, ..., 0]:
+*d-JN        ##  append J - N spaces to the front of the line
jd            ##  riffle the result of the next operation with spaces
:.[K\.yJ      ##  slice the string given by K padded to be the length of the Jth hexagon
              ##  number with noops
Z=+Z+JN       ##  from Z to Z + J + N, then set Z to be Z + J + N

2
먼저 n> = 1에 대해 ln (10) * 10 ^ n> 6n-3 (미분)임을 증명해야합니다. 이 식의 미분 값이 ln (10) ^ 2 10 ^ n 및 6이므로 쉬워집니다. 10 ^ n은 단조 증가하고 10 ^ 1> 6 * 1이므로 10 ^ n은 모두 6n-3보다 큽니다. n> = 1. 동일한 논리를 사용하여 10 ^ n 및 3n (n-1) +1에 대한 증명을 완료 할 수 있습니다.
Arcturus

@Ampora 감사합니다. 파생 상품 사용을 고려했지만 부정한 것 같습니다. 그래도 더 좋은 방법을 찾지 못했습니다. 대단히 감사합니다!
FryAmTheEggman

기쁘다. 캘 크는 때때로 간혹 추악해질 수 있습니다.
Arcturus

위 링크 pyth.herokuapp.com/?code=etc 에서 컴파일러가 실행되지 않는 것을 발견했습니다 ...
RosLuP

1
@FryAmTheEggman n> = 1에 대해 훨씬 더 강한 바운드 4 ^ n> 3n (n-1) + 1을 보여주는 매우 쉬운 방법이 있으며, 계산법이 필요하지 않습니다. 이항 확장에 의해 (1 + 3) ^ n = 1 + 3n + 9n (n-1) / 2 + ...라는 사실을 사용하십시오. 첫 번째와 세 번째 항은 직접적으로 1 + 3n (n-1)을 나타내므로 세 번째 항이 존재하는 경우 (즉, n> = 2 인 경우) 부등식은 즉시입니다. 이는 RHS가 1이기 때문에 n = 1 인 경우 만 사소한 것입니다.
Erick Wong

90

헥사 고니 , 271 바이트

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에서 바이트를 읽거나 -1EOF를 그 가장자리에 쳤다면. 따라서 <바로 다음은 모든 입력을 읽었는지 여부에 대한 조건입니다. 지금은 입력 루프를 유지합시다. 우리가 실행하는 다음 코드는

{&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를 한 번 더 반전시킵니다.778M7710 (mod 256);~'"=

이제 가장자리가 0이면 끝났습니다. IP는 (매우 짧은) 빨간색 경로를 사용 @하여 프로그램을 종료합니다. 그렇지 않으면, 우리는 다른 경로를 인쇄하기 위해 분홍색 경로로 다시 돌아가는 자주색 경로를 계속합니다.


Timwi의 HexagonyColorer로 작성된 제어 흐름도 . Esoteric IDE 의 비주얼 디버거로 작성된 메모리 다이어그램 .


19
나는 육각형 답변에 대해 이것을 많이 말하고 있습니다 : 그냥 우와.
Conor O'Brien

5
불어 허 ...하지만 .. 와트 ... 마음 =
아드 난

나는 누군가가 이것을하기를 바랐다. 내가 말을 해요. 대단해.
Arcturus

19
2 단계-다른 97 %를 쓰십시오. :)
ASCIIThenANSI

3 단계-가장 적은 바이트를 가진 답으로.
Tom M

19

CJam, 56 52 50 48 바이트

내 생각은 "이미 코드가 이미 있습니다!"였습니다. 그러나 루비 코드에서 필요한 부분을 모으는 데 신경 쓰지 못했습니다. 특히 골프에 적합하지 않기 때문에 특히 그렇습니다. 그래서 CJam에서 다른 것을 시도했습니다 ...

lS-{_,4*(3/mq:D1%}{'.+}wD{D(2/-z_S*D@-@/(S*N@s}/

여기에서 테스트하십시오.

설명

중심에있는 육각형 숫자에 대한 약간의 수학이 먼저 있습니다. 정규 육각형의 측면 길이가 있으면 소스 코드 길이와 같은 셀 N이 포함됩니다 . 간단한 2 차 방정식이기 때문에이를 해결할 수 있습니다 .3N(N-1)+1kN

N = 1/2 ± √(1/4 + (k-1)/3)

우리는 음의 근을 무시할 수 있습니다. 음의 N을 제공하기 때문입니다. 이것이 해를 갖기 위해서는, 제곱근이 정수 여야합니다. 즉, √(1 + 4(k-1)/3) = √((4k-1)/3)정수 여야합니다 (행운 적으로이 정수 D = 2N-1는 육각형 의 직경 이되므로 어쨌든 필요합니다). 따라서 .조건이 충족 될 때까지 단일 항목을 반복해서 추가 할 수 있습니다 .

나머지는 육각형을 배치하는 간단한 루프입니다. 이 부분에 대한 유용한 관찰은 들여 쓰기의 공백과 각 줄의 코드에서 공백이 아닌 직경을 더한 것입니다.

lS-     e# Read input and remove spaces.
{       e# While the first block yields something truthy, evaluate the second...
  _,    e#   Duplicate the code and get its length k.
  4*(   e#   Compute 4k-1.
  3/    e#   Divide by 3.
  mq    e#   Take the square root.
  :D    e#   Store this in D, just in case we're done, because when we are, this happens
        e#   to be the diameter of the hexagon.
  1%    e#   Take modulo 1. This is 0 for integers, and non-zero for non-integers.
}{      e# ...
  '.+   e#   Append a no-op to the source code.
}w
D{      e# For every i from 0 to D-1...
  D(2/  e#   Compute (D-1)/2 = N, the side length.
  -z    e#   Subtract that from the current i and get its modulus. That's the size of the
        e#   indentation on this line.
  _S*   e#   Duplicate and get a string with that many spaces.
  D@-   e#   Subtract the other copy from D to get the number of characters of code
        e#   in the current line.
  @/    e#   Pull up the source code and split into chunks of this size.
  (S*   e#   Pull off the first chunk and riffle it with spaces.
  N     e#   Push a linefeed character.
  @s    e#   Pull up the remaining chunks and join them back into a single string.
}/

우리는 이중 산술을 전혀 사용할 필요가 없다는 것이 판명되었습니다 (제곱근 제외). 4의 곱셈으로 인해 3으로 나눌 때 충돌이 없으며 k, 정수 제곱근을 가장 먼저 얻는 것이 좋습니다.


8

203 200 198

포함 + 1 -p

s/\s//g;{($l=y///c)>($h=1+3*++$n*($n-1))&&redo}$s=$_.'.'x($h-$l);for($a=$n;$a<($d=2*$n-1);$a++){$s=~s/.{$a}/$&\n/,$s=reverse($s)for 0..1}$_=join$/,map{(' 'x abs($n-$i++-1)).$_}$s=~/\S+/g;s/\S/ $&/g

다음과 같이 실행하십시오. echo abc | perl -p file.pl

매우 순진한 접근 방식 :

#!/usr/bin/perl -p

s/\s//g;                            # ignore spaces and EOL etc.
{                                   # find the smallest hex number:
    ($l=y///c)                      # calc string length
    > ($h=1+3*++$n*($n-1))          # 
    && redo                         # (should use 'and', but..)
}

$s = $_                             # save $_ as it is used in the nested for
   . '.' x ($h-$l);                 # append dots to fill hexagon

for ( $a = $n; $a < ($d=2*$n-1); $a++ )
{
        $s=~s/.{$a}/$&\n/,          # split lines
        $s=reverse($s)              # mirror
    for 0..1                        # twice
}

$_ = join$/,                        # join using newline
map {                               # iterate the lines
    (' 'x abs($n-$i++-1)) .$_       # prepend padding
} $s=~/\S+/g;                       # match lines

s/\S/ $&/g                          # prepend spaces to characters
                                    # -p takes care of printing $_

  • 업데이트 200 은 바이트 이동 변수 할당을 저장하고 final을 생략하여 다른 2 개를 저장합니다 ;. 이제 200 바이트 미만으로 코드를 작성하십시오!
  • 업데이트 198$s=~/\S+/g 대신 2 바이트를 사용하여 저장split/\n/,$s

7

자바 스크립트 (ES6) 162 172

익명 함수

육각형 크기는 Wikipedia 의 방정식을 푸는 것으로 밝혀졌습니다.

3*n*(n-1)-1 = l

해결 공식은 기본적으로

n = ceil(3+sqrt(12*l-3))/6)

대수와 근사치 (@ user18655도 마찬가지)로

n = trunc(sqrt(l/3-1/12)+1.4999....)
s=>eval("s=s.match(/\\S/g);m=n=Math.sqrt(s.length/3-1/12)+1.49999|0;p=o=``;for(i=n+n;--i;i>n?++m:--m)for(o+=`\n`+` `.repeat(n+n-m),j=m;j--;o+=` `)o+=s[p++]||`.`")

더 읽기

s=>{
  s=s.match(/\S/g);
  m=n=Math.sqrt(s.length/3-1/12)+1.49999;
  p=o='';
  for(i=n+n; --i; i>n?++m:--m)
    for(o += '\n'+' '.repeat(n+n-m), j=m; j--; o += ' ')
      o+=s[p++]||'.';
  return o
}

테스트 스 니펫 (전체 페이지 개선-실행 시간 ~ 1 분)

f=s=>eval("s=s.match(/\\S/g);m=n=Math.sqrt(s.length/3-1/12)+1.49999|0;p=o=``;for(i=n+n;--i;i>n?++m:--m)for(o+=`\n`+` `.repeat(n+n-m),j=m;j--;o+=` `)o+=s[p++]||`.`")

t=0;
r='0';
(T=_=>t++<816?(O.innerHTML=f(r=t%10+r),setTimeout(T,20)):0)()
pre { font-size: 66% }
<pre id=O></pre>


1
n=...+1-1e-9|0대신 n=Math.ceil(...)2 바이트를 절약 할 수 있습니다 . ES7로 가서 **0.5대신 사용할 수도 Math.sqrt있지만 그것은 당신에게 달려 있습니다. 나는 내 브라우저에서 작동하기 때문에 보통 ES6 답변을 유지합니다.
user81655

@ user81655 좋은 힌트, 감사
edc65

5

Pyth, 52 51 바이트

Jfgh**3TtTl=H-zd1=+H*\.*lHTV+UJt_UJAcH]+JN+*-JNdjdG

온라인으로 사용해보십시오. 테스트 스위트.

OP에 의해 허용 된대로 각 라인에는 하나의 추가 선행 공간이 있습니다.

설명

 f              1          |   find first number n for which
             -zd           |           remove spaces from input
           =H              |         put result in H
          l                |       length of input without spaces
  g                        |     is less than or equal to
   h**3TtT                 |       nth centered hexagonal number
J                          | put result (hexagon side length) in J
                           |
      *lHT                 |      ten times length of input without spaces
   *\.                     |   that amount of dots
=+H                        | append to H
                           |
  UJ                       |    numbers 0 up to side length - 1
 +  t_UJ                   |   add numbers side length - 2 down to 0
V                          | loop over result
            +JN            |       current loop number + side length
         cH]               |     split to two parts at that position
        A                  |   put parts to G and H
                 -JN       |       side length - current loop number - 1
                *   d      |     that many spaces
                     jdG   |     join code on the line (G) by spaces
               +           |   concatenate parts and print

5

레티 나 161 바이트

2 바이트를 절약 한 FryAmTheEggman에게 감사합니다.

이 답변은 경쟁이 아닙니다. Retina는이 도전 이후 몇 가지 업데이트를 보았으며 새로운 기능 중 일부를 사용하고 있다고 확신합니다 (확인하지는 않았지만).

바이트 수는 ISO 8859-1 인코딩을 가정합니다. 첫 번째 줄에는 단일 공백이 있습니다. 대부분 ·은 실제로 가운데 점 (0xB7)입니다.

 

^
$._$*·¶
^·¶
¶
((^·|\2·)*)·\1{5}·+
$2·
^·*
$.&$* ·$&$&$.&$* 
M!&m`(?<=(?= *(·)+)^.*)(?<-1>.)+(?(1)!)|^.+$
+m`^( *·+)· *¶(?=\1)
$& 
·
 ·
O$`(·)|\S
$1
·
.
G-2`

온라인으로 사용해보십시오!

잘...

설명

먼저 단일 문자 ( ·이 경우)를 사용하여 레이아웃을 작성한 다음 결과 레이아웃을 입력 문자로 채우는 것이 가장 쉬운 것 같습니다 . 이것의 주된 이유는 단일 문자를 사용하면 역 참조 및 문자 반복을 사용할 수 있기 때문입니다. 입력을 직접 배치하면 값 비싼 밸런싱 그룹이 필요합니다.

 

많이 보이지는 않지만이 첫 번째 단계는 입력에서 공백을 제거합니다.

^
$._$*·¶

시작점 (공백을 제거한 후)의 M중심점 을 포함하는 추가 선을 추가하여 시작합니다 M.

^·¶
¶

입력이 단일 문자 인 경우 해당 중심점을 다시 제거합니다. 다음 단계에서는 다루지 않은 불행한 특수 사례입니다.

((^·|\2·)*)·\1{5}·+
$2·

필요한 측면 길이 N에서 1을 뺀 값을 계산합니다 . 작동 방식은 다음과 같습니다. 중심 육각형 숫자는 형식 3*N*(N-1) + 1입니다. 삼각 숫자는이므로 N*(N-1)/2, 육각형 숫자는 삼각 수의 6 배에 1을 더한 것을 의미 1 + 2 + 3 + ... + N합니다. 정규 표현식에서 삼각 숫자를 일치시키는 것은 정방향 참조로 상당히 쉽습니다. (^·|\2·)*경기가 할 수있는 가장 큰 삼각형의 수. 좋은 보너스 $2로이 삼각형 숫자의 인덱스를 보유합니다. 6을 곱하기 위해 그룹으로 캡처하고 15 번 더 일치시킵니다. 우리는 적어도 두 개 더 확인이되어 있는지 확인 ··와를·+. 이 방법으로 찾은 삼각형 숫자의 색인은 중심 6 각 숫자보다 한 문자 이상이 될 때까지 증가하지 않습니다.

결국,이 일치는 그룹에서 필요한 육각형의 측면 길이보다 두 배 더 짧아 $2지므로, 다시 한 번 더 중심점과 함께 쓰면 N-1됩니다.

^·*
$.&$* ·$&$&$.&$* 

이것은 우리의 N-1중심점 줄 을 N-1공백, 2N-1중심점 및 다른 N-1공백 으로 바꿉니다 . 이것은 최대 들여 쓰기, 육각형의 직경, 다시 들여 쓰기로 이어집니다.

M!&m`(?<=(?= *(·)+)^.*)(?<-1>.)+(?(1)!)|^.+$

이것은 불쾌하게 길지만 기본적으로 a) 첫 번째 줄의 문자 또는 b) 두 번째 줄의 모든 겹치는 일치 항목을 제공 2N-1합니다. 이것은 이전 단계의 결과를 완전하지만 이상하게 들여 쓴 육각형으로 확장합니다. 예를 들어 다음과 같은 입력 12345678을 얻을 수 있습니다.

  ···
 ····
·····
···· 
···  
12345678

그렇기 때문에 이전 단계에서 공백을 추가해야했습니다.

+m`^( *·+)· *¶(?=\1)
$& 

이렇게하면 중심보다 뒤에있는 줄의 들여 쓰기가 수정됩니다. 이전 줄보다 짧은 줄을 반복해서 들여 쓰면 (후행 공백 무시) 다음과 같이됩니다.

  ···
 ····
·····
 ···· 
  ···  
12345678

이제 우리는 공백을 약간 삽입합니다.

·
 ·

우리에게주는 것 :

   · · ·
  · · · ·
 · · · · ·
  · · · · 
   · · ·  
12345678

휴, 끝났어.

O$`(·)|\S
$1

입력 문자열을 중앙 점으로 채울 시간입니다. 이것은 정렬 단계의 도움으로 수행됩니다. 마지막 줄의 모든 중심점과 각 문자를 일치시키고 주어진 대체 결과에 따라 정렬합니다. 마지막 줄의 문자와 ·가운데 점 에 대한 대체는 비어 있으므로 정렬이 안정적이므로 가운데 점이 끝까지 간단히 정렬됩니다. 입력 문자가 제자리로 이동합니다.

   1 2 3
  4 5 6 7
 8 · · · ·
  · · · · 
   · · ·  
········

지금 두 가지만 남았습니다.

·
.

이렇게하면 중앙 점이 정기적으로 바뀝니다.

G-2`

그리고 이것은 마지막 줄을 버립니다.


1

자바 스크립트 (ES6), 144 바이트

(s,n=1,l=0,p=0,m=s.match(/\S/g))=>m[n]?f(s,n+6*++l,l):[...Array(l+l+1)].map((_,i,a)=>a.map((_,j)=>j<l-i|j<i-l?``:m[p++]||`.`).join` `).join`\n`

어디 \n리터럴 개행 문자를 나타냅니다. 이전에 여러 다른 답변 에 사용한 육각형을 만드는 기술을 사용 합니다. ES7의 경우 제곱근을 재귀 접근법보다 약간 짧게 만듭니다.

(s,p=0,m=s.match(/\S/g),l=(~-m.length/3)**.5+.5|0)=>[...Array(l+l+1)].map((_,i,a)=>a.map((_,j)=>j<l-i|j<i-l?``:m[p++]||`.`).join` `).join`\n`

1

파이썬 3 , 144 바이트

c=input().replace(' ','')
n=x=1
while x<len(c):x+=n*6;n+=1
c=c.ljust(x,'.')
while c:print(' '*(x-n)+' '.join(c[:n]));c=c[n:];n-=(len(c)<x/2)*2-1

온라인으로 사용해보십시오!

이것은 크기가 다른 육각형에 대해 다소 다른 양의 선행 공백을 사용하지만 일반적인 모양은 유지됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.