오늘의 랜덤 아스키 아트 # 5 : 다이아몬드 타일링


21

매시업 시간!

이것은 오늘의 랜덤 골프 와 옵티마이 저의 ASCII Art of the Day 시리즈의 5 부입니다. 이 챌린지에서 제출 한 내용은 두 개의 리더 보드 (링크 된 게시물을 찾을 수 있음)에 반영됩니다. 물론, 이것을 다른 코드 골프 도전과 같이 취급하고 어느 시리즈에 대해 전혀 걱정하지 않고 대답 할 수 있습니다.

홀 5 : 다이아몬드 타일링

일반 육각형은 항상 다음과 같이 다이아몬드로 타일링 할 수 있습니다.

이 타일링의 ASCII 아트 표현을 사용합니다. 측면 길이가 2 인 육각형의 경우 20 개의 타일이 있습니다.

   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /\_\_\   /\_\_\   /\_\_\   /\_\_\   /_/\_\   /_/\_\   /\_\_\   /_/\_\   /_/\_\   /_/\_\ 
 /\/\_\_\ /\/_/\_\ /\/_/_/\ /\/_/\_\ /\_\/\_\ /\_\/_/\ /\/_/_/\ /\_\/\_\ /\_\/_/\ /_/\/\_\
 \/\/_/_/ \/\_\/_/ \/\_\_\/ \/_/\/_/ \/\_\/_/ \/\_\_\/ \/_/\_\/ \/_/\/_/ \/_/\_\/ \_\/\/_/
  \/_/_/   \/_/_/   \/_/_/   \_\/_/   \/_/_/   \/_/_/   \_\/_/   \_\/_/   \_\/_/   \_\/_/ 
   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /_/_/\   /\_\_\   /_/\_\   /_/_/\   /_/\_\   /_/\_\   /_/_/\   /_/_/\   /_/_/\   /_/_/\ 
 /\_\_\/\ /\/_/_/\ /_/\/_/\ /\_\_\/\ /\_\/_/\ /_/\/_/\ /_/\_\/\ /\_\_\/\ /_/\_\/\ /_/_/\/\
 \/\_\_\/ \/_/_/\/ \_\/\_\/ \/_/\_\/ \/_/_/\/ \_\/_/\/ \_\/\_\/ \/_/_/\/ \_\/_/\/ \_\_\/\/
  \/_/_/   \_\_\/   \_\/_/   \_\/_/   \_\_\/   \_\_\/   \_\/_/   \_\_\/   \_\_\/   \_\_\/ 

측면 길이가 주어지면 측면 길이 N가 6 각형 인 타일을 N임의로 생성해야합니다 . 정확한 분포는 중요하지 않지만 각 타일링은 0이 아닌 확률로 반환되어야합니다.

의 경우 N ≤ 4제출시 시간의 80 % 이상이 1 분 이내에 타일링을 생성하고 1 분 내에 타일링의 80 % 이상이 생성되어야합니다. 대부분의 접근법은이 규칙에 대해 걱정할 필요가 없습니다 (매우 관대합니다)-이것은 타일링이 될 때까지 임의의 문자열을 생성하는 매우 순진한 거부 기반 알고리즘을 배제하는 것입니다.

주어진 N에 가능한 총 타일 수는 OEIS A008793 에서 찾을 수 있습니다 .

전체 프로그램 또는 함수를 작성하고 STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 리턴 값 또는 함수 (out) 매개 변수를 통해 출력을 생성 할 수 있습니다.

육각형을 정렬하는 데 필요한 것보다 많은 선행 공백을 출력해서는 안됩니다 (육각형의 왼쪽 모서리에는 공백이 없어야 함). 각 선은 N후행 까지 포함 할 수 있습니다 (일관되게 반드시 정할 필요는 없으므로 육각형 경계 상자를 인쇄하여 직사각형 출력을 가질 수 있음).

이것은 코드 골프이므로 가장 짧은 제출 (바이트)이 이깁니다. 물론 사용자 당 가장 짧은 제출물도 시리즈의 전체 순위표에 들어갑니다.

리더 보드

각 시리즈의 첫 번째 게시물은 리더 보드를 생성합니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 모든 답변을 헤드 라인으로 시작하십시오.

# Language Name, N bytes

N제출물의 크기는 어디에 있습니까 ? 당신이 당신의 점수를 향상시킬 경우에, 당신은 할 수 있습니다 를 통해 눈에 띄는에 의해, 헤드 라인에 오래된 점수를 유지한다. 예를 들어 :

# Ruby, <s>104</s> <s>101</s> 96 bytes

(언어는 현재 표시되어 있지 않지만 스 니펫은이를 요구하고 구문 분석하며 향후 언어 별 리더 보드를 추가 할 수 있습니다.)


3
3D로 예제 이미지를 계속 보는 사람이 나입니까?
LegionMammal978

3
아니, 완벽하게 정상입니다. ;) (그리고 아마 도전에 접근하는 좋은 방법입니다.)
Martin Ender

For N ≤ 4, your submission must produce a tiling within 1 minute at least 80% of the time.너무 쉽다 : 80 %의 시간이 같은 기본 타일링, 그렇지 않으면 내가 원하는 시간에 다른 타일링을 찾는다
edc65

@ edc65 좋은 지적이다.
마틴 엔더

답변:


10

CJam, 105 바이트

ri:A" __"e*A,2f*:B,[W1]{J+B:):B,{N1$S*"\/"J%A2*4$-:D*
0{;B{_1&!2mr+J*m1e>D(2*e<}%__:)&}g:B{'_t}/+@J+}*}fJ;

스크롤을 피하기 위해 줄 바꿈이 추가되었습니다. 온라인으로 사용해보십시오

설명:

이 솔루션은 각 줄을 지그재그로 시작한 다음 이전 줄에서의 위치와 몇 가지 규칙에 따라 N 밑줄을 그 위에 놓습니다. 출력을 평범한 2D 문자 행렬로 보면서 일련의 관찰에서 이것을 얻었습니다.

  • 각 줄에는 정확히 N 개의 밑줄이 있습니다.
  • 밑줄은 / 또는 \로 대체하여 완벽하게 반복되는 지그재그 패턴을 만들 수 있습니다 ( /\위쪽 절반, \/아래쪽 절반)
  • 밑줄은 측면을 만질 수 없으며 다른 밑줄과 인접 할 수 없습니다
  • 다음 줄로 갈 때 각 밑줄의 위치는 -1, 0 또는 1 씩 변경됩니다
  • 그보다 /_/-1 또는 0 \_\만 변경할 수 있으며 0 또는 1 만 변경할 수 있습니다
  • 초기 밑줄 위치에 대한 우리 중 하나 사용할 수있는 "_ "패턴 또는 " _"둘 다 괜찮, 패턴
  • 위의 규칙은 모든 타일을 얻기에 충분합니다.

따라서 이전 밑줄 위치를 유지하고 임의의 요소 (각 밑줄마다 2 가지 선택)로 수정하고 규칙이 충족 될 때까지 반복하여 구현하기로 결정했습니다. 최적화 과정에서 육각형의 왼쪽을 기준으로 밑줄 위치로 전환했습니다 (공백 제외).

ri:A" __"e*       read the input (A) and generate the top line
A,2f*:B           make an array [0 2 4 ... 2A-2] and store in B
                  these are the initial positions for the underscores
,                 B's length = A, used as the initial number of leading spaces
                  let's call it C
[W1]{…}fJ         for J in [-1 1] (top half, bottom half)
  J+              add J to C
  B:):B           increment the underscore positions (adjustment before each half)
  ,{…}*           repeat A times
    N1$S*         add a newline and C spaces
    "\/"J%        take "\/" and reverse it if J=-1 (zigzag pattern)
    A2*4$-:D*     calculate D=A*2-C and repeat the pattern
    0             dummy value (for the next loop)
    {…}g          do-while
      ;B          pop last value and push B
      {…}%        apply block to each item (say x)
        _1&!      duplicate x and calculate !(x&1) (for /_/ vs \_\)
        2mr+      randomly add 0 or 1
        J*m       multiply by J and subtract from x
        1e>       limit the minimum value to 1
        D(2*e<    and the maximum value to 2*(D-1)
      __:)&       check if the modified array has any adjacent values
    :B            store the new positions in B
    {'_t}/        place underscores over the zigzag pattern
    +@J+          bring C to the top and add J to it
;                 pop C

이전 "3D"버전, 189 바이트 :

ri:A" __"e*aA4*S*aA2**+[0-2XXW1]:C;"/\_\\\/_/":D;A3m*{{C2/.f*:.+~
A(2*+:V;A+:U;2{UI+1$1$=4{_V+D4/I=@=t}/t}fI}:F~}/[0Y1WWW]:C;
"/_/\\\_\/":D;AaA*:B;A{A[_{_BI=e<)mr}fI]:B;{BQ={[PQR]F}fR}fQ}fPN*

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


멋진 일을 위해 +1하고 또 한 번 더 투표하면 10k의 담당자가되지만 대부분은 멋진 일을합니다. (아, 저것 봐. 축하해. 10k :))
Alex A.

패턴에 대한 훌륭한 분석! 나는 그것을 나의 대답으로 사용할 것이다.
anatolyg 2016 년

6

파이썬 2, 337 335 324 318 311 300 296 바이트

from random import*
n=input()
R=range(n*2)
b=[]
l=[]
for i in R:o=abs(i-n)-(i<n);b+=[o];l+=[list(' '*o+'\//\\'[i<n::2]*(n*2-o))]
for i in R[:n]:
 o=1;p=n+i*2
 for j in R:r=randint(0,p<n*3+i*2-j);p+=(r or-1)*(o==r);q=p<=b[j];o=r|q;p+=q;l[j][p]='_';b[j]=p+1
for s in[' '*n+'__'*n]+l:print''.join(s)

아이디어는 먼저 다음과 같이 육각형의 다이아몬드를 만드는 것입니다.

  ____
 /\/\/\
/\/\/\/\
\/\/\/\/
 \/\/\/

그런 다음 아래와 같이 밑줄로 아래로 채우십시오.

  ____                          ____
 /_/\/\                        /\_\/\
/_/\/\/\    or maybe this:    /\/_/\/\
\_\/\/\/                      \/_/\/\/
 \_\/\/                        \_\/\/

모든 경로가 추가 된 최종 결과는 다음과 같습니다.

  ____                          ____  
 /_/\_\                        /\_\_\ 
/_/\/_/\    or maybe this:    /\/_/\_\
\_\/_/\/                      \/_/\/_/
 \_\_\/                        \_\/_/ 

이러한 경로가 경계를 벗어나거나 서로 교차하지 않도록 꽤 많은 코드가 사용됩니다.

ungolfed 코드 :

# Initialize l with all diamonds
blocked = []
l = [[] for _ in range(n*2)]
for i in range(n*2):
    offset = n-i-1 if i<n else i-n
    blocked.append(offset)
    l[i] += ' '*offset + ('/\\' if i<n else '\/')*(2*n - offset)

# Generate the random _'s
for i in range(n):
    oldright = True
    pos = n + i*2
    for j in range(n*2):
        # Go randomly right (true) or left (false), except when you out of bounds on the right side
        right = randint(0, 1) and pos < n*3 + i*2 - j
        if right == oldright:
            pos += 1 if right else -1
        if pos <= blocked[j]:
            right = True
            pos += 1
        l[j][pos] = '_'
        blocked[j] = pos + 1
        oldright = right

# Print the result
print ' '*n + '__'*n
for s in l:
    print ''.join(s)

1
방금 출력이 잘못 된 것으로 나타났습니다. 두 가지 결과 (오른쪽 위와 오른쪽 아래)에 삼각형이 있습니다.
Martin Ender

1
@MartinEnder 예제는 알고리즘의 아이디어를 보여주기 위해 하나의 '밑줄 경로'만 보여주었습니다. 최종 출력에는 모든 경로 (이 경우 2)가있어 삼각형을 제거합니다. 최종 출력의 예를 추가했습니다.
Matty

오, 알 겠어요. 설명해 주셔서 감사합니다.
Martin Ender

2
나는 당신이 단축 될 수 있습니다 생각 randint(0,1)*(p<n*3+i*2-j)randint(0,p<n*3+i*2-j).
12Me21

네, 고마워요!
Matty

4

174 168 166 161

#!perl -n
for$l(-$_..$_){$t=/_/?join'',map'/_'x($%=rand
1+(@z=/__?/g)).'/\\'.'_\\'x(@z-$%),split/\/\\/:__
x$_;$l>0&&$t!~s!^.(\\.*/).$!$1!?redo:print$"x abs$l-.5,$_=$t.$/}

저를 보십시오 .


항상 같은 타일링을 생성하는 것 같습니다 (적어도 이데온에서)
aditsu

@aditsu, Ideone은 링크를 클릭하면 캐시 된 결과를 보여줍니다. 실제로 다시 실행하려면 포크해야합니다.
nutki

2

자바 스크립트 ( ES6 ), 376416 494

그냥 거기에 ...

이렇게하면 모든 타일을 만든 다음 임의 타일을 선택합니다. N = 4의 232848 타일링 시간은 랩탑에서 ~ 45 초입니다. 나는 N = 5를 시도하지 않았다.

EcmaScript 6이므로 Firefox에서만 실행됩니다.

F=n=>{
  for(i=s=r=b='';i<n;i++)
    s='\n'+b+'/\\'[R='repeat'](n-i)+'_\\'[R](n)+s,
    r+='\n'+b+'\\/'[R](n-i)+'_/'[R](n),
    b+=' ';
  for(h=[t=0],x=[s+r];s=x[t];t++)
    for(d='';!d[n*3];d+='.')
      if(l=s.match(r=RegExp("(\n"+d+"/)\\\\_(.*\n"+d+"\\\\)/_","g")))
        for(j=2<<l.length;j-=2;h[z]||(h[z]=x.push(z)))
          z=s.replace(r,(r,g,h)=>(k+=k)&j?g+'_/'+h+'_\\':r,k=1);
  return b+'__'[R](n)+x[Math.random()*t|0]
}


function go()
{
  var n = N.value | 0,
  t0 = performance.now(),
  r = F(n),
  t1 = performance.now();
  
  O.innerHTML = r+'\n\nTime (msec): '+(t1-t0)
}
N: <input id=N value=3><button onclick="go()">GO</button>
<pre id=O></pre>


Chromium 42에서 "Uncaught SyntaxError : Unexpected token =>"및 "Uncaught ReferenceError : go is not defined"
aditsu

1
@aditsu ES6, Chrome입니다 : Firefox 없음 : 예. 잘 알려진 사실이 아닙니까?
edc65

나는 전혀 몰랐다. 나는 크롬이 최신의 가장 큰 것을 사용하기를 기대했다. 설명해 주셔서 감사합니다.
aditsu

지금 firefox (31.5.3)에서 실행했으며 N = 1, 2 또는 3에서 작동하지만 N = 4의 경우 약 10 초 동안 실행되고 완료되고 아무것도 표시하지 않습니다 (콘솔에 오류가 없습니다) )
aditsu

@aditsu 확인 ... 어쩌면 된 샌드 박스에 자바 스크립트를하지 조용히 시간 제한을 초과하면 사망 dom.max_script_run_time. about : config의 전역 환경 설정이며, 광산은 30으로 설정되어 있습니다.
edc65

1

SmileBASIC, 241 바이트

INPUT N
T=N*2CLS?" "*N;"__"*N
DIM B[T]FOR I=-1TO N-1O=1P=N+I*2FOR J=0TO T-1IF I<0THEN O=ABS(J0N+.5)<<0B[J]=O?" "*O;MID$("\/\",J<N,2)*(T-O)ELSE R=P<N*3+I*2-J&&RND(2)P=P+(R*2-1)*(O==R)A=P<=B[J]R=R||A:P=P+A:LOCATE P,J+1?"_"B[J]=P+1O=R
NEXT
NEXT

Matty의 답변에 크게 기초

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