나 피라미드 만들기


16

큐브에서 피라미드를 만들어야합니다. 큐브는 두 가지 각도에서 볼 수 있습니다.

  _____        _____
 /\    \      /    /\
/  \____\    /____/  \
\  /    /    \    \  /
 \/____/      \____\/

이것은 가능한 두 가지 각도에서 2 크기 큐브의 예입니다. 큐브의 높이는 $size슬래시 (또는 백 슬래시)이고 큐브의 너비는 2 * $size밑줄입니다. 최상위 너비에는 추가 밑줄 문자가 포함되어야합니다.

입력은 숫자 (입방체 크기), 슬래시 또는 백 슬래시 (방향 / 각도 표시) 및 다른 숫자 (피라미드 높이)를 포함하는 문자열로 제공됩니다.

예 :

입력:

1/1

산출:

 ___
/\__\
\/__/

입력:

1\1

산출:

 ___
/__/\
\__\/

입력:

2/1

산출:

  _____
 /\    \
/  \____\
\  /    /
 \/____/

입력:

1/2

산출:

     ___ 
 ___/\__\
/\__\/__/
\/__/\__\
    \/__/

입력:

2\2

산출:

  _____          
 /    /\         
/____/  \_____   
\    \  /    /\ 
 \____\/____/  \ 
 /    /\    \  /
/____/  \____\/ 
\    \  /        
 \____\/        

입력:

1/3

산출:

         ___  
     ___/\__\
 ___/\__\/__/
/\__\/__/\__\
\/__/\__\/__/
    \/__/\__\
        \/__/
  • 후행 / 선행 공백은 괜찮습니다.
  • 표준 허점은 허용되지 않습니다.
  • 입력이 항상 유효하다고 가정 할 수 있습니다.
  • 입력이 너무 큰 출력을 유발하지 않는다고 가정 할 수 있습니다. 즉, 출력이 터미널에 인쇄 될 때 줄 바꿈이 없습니다.
  • 큐브 크기 및 피라미드 높이가 양수 (예 : 1 이상)
  • 이것은 코드 골프이므로 바이트 단위의 가장 짧은 코드가 이깁니다.

현재 수상자 :

Julia 에서 270 바이트의 Glen O

도전은 열려 있습니다. 현재 최고를 이길 경우 허용 된 답변을 업데이트하겠습니다.


2
큐브는 최근 다이아몬드 패턴 문제의 큐브와 다릅니다. 맨 위 행에는 2s + 1 밑줄이 있고 다른 문제는 맨 위 행에는 2s 밑줄이 있고 다른 행에는 2s-1이 있습니다. 즉, 수평 피치는 3s + 1입니다. 나는 주변에 물건을 섞는 것이 좋다고 생각합니다. 누군가가 그것을 놓칠 경우를 대비하여 관찰하십시오.
Level River St

1
크기와 높이의 최대 값은 얼마입니까? 한 자리라고 가정 할 수 있습니까?
Level River St

아니요, 한 자리라고 가정 할 수는 없지만 제공된 입력으로 인해 출력이 "너무 큰"것으로 가정하지 않을 수 있습니다. 즉, 터미널에 줄 바꿈이 발생하지 않습니다.
gilad hoch

답변:


3

줄리아 - 503 455 369 346 313 270 바이트

f=A->(t=47A;h='/'+45t;(m,n)=int(split(A,h));W=2m*n+1;X=(l=3m+1)n+m+1;s=fill(' ',X,W);s[end,:]=10;for i=1:n,j=i:n,M=1:m s[M+i*l+[[L=[J=(2j-i)m,J,J-m]+M W-L]X.-[l,m,0] [0 m].+[1,m,m].+[J,J+m,J-m]X-l]]=[1,1,1]*[h 139-h 95 s[i*l,i*m-m+1]=95]end;print((t?s:flipud(s))...))

언 골프 드 :

function f(A)
  t=47A      # Determine if '/' is in A ('/' = char(47))
  h='/'+45t   # Set h to the appropriate slash ('\\' = char(92), 92=47+45)
  (m,n)=int(split(A,h)) # Get the two integers from A
  W=2m*n+1    # Get number of rows of output (vertical height of pyramid)
  X=(l=3m+1)n+m+1 # Get columns of output + 1 (for newlines)
  s=fill(' ',X,W) # Create 'canvas' of size X x W
  s[end,:]=10 # Put newlines at end of each output row
  for i=1:n, j=i:n, M=1:m
    # This is where the fun happens.
    # K and L represent the shifting points for '/' and '\\' in the
    # horizontal and vertical directions.
    # They are used to make the code neater (and shorter).
    K=M+i*l-[l,m,0]
    L=[J,J,J-m]+M
    # The next two assign the slashes to appropriate places
    s[K+L*X]=h
    s[K+(W-L)X]=139-h
    # This one puts the first 2m underscores in each of the underscore sets
    s[M+i*l-l+[0 m].+[1,m,m].+[J,J+m,J-m]X]=95
    # This places the final underscores on the top edges (repeatedly)
    s[i*l,i*m-m+1]=95
  end
  # The above produces the array orientation for backslash, but uses
  # the "wrong" slashes along the diagonals if there's a forward slash.
  # This line flips the matrix in that case, before printing it.
  print((t?s:flipud(s))...))
end

용법:

f("3/2")

또는

f("2\\3")

9

펄, 343 바이트

$_=<>;$_=~/(\d+)(\S)(\d+)/;$v=$2eq'/';$w=$1*3+1;for$y(0..$1*2*$3){$k=$w*$3+$1-1;for$z(0..$k){$x=$v?$k-$z:$z;$q=($y+$1-1)/$1|0;$r=$x/$w|0;$d=$q+$r&1;$f=($y-1)%$1;$f=$1-$f-1if$d;$g=($x-$f)%$w;$u=$r;$q=2*$3-$q+1,$u++if$q>$3;print(($q>=$r&&$q&&$g==0)||($q>$r&&$g==$w-$1)?$d^$v?'/':'\\':$q>=$u&&$y%$1==0&&$g>0&&$g<($w-$1+($q==$r))?"_":$")}print$/}

주석이 포함 된 여러 줄 :

$_=<>;$_=~/(\d+)(\S)(\d+)/;$v=$2eq'/'; # read input
$w=$1*3+1; # compute width of each cube in chars
for$y(0..$1*2*$3){$k=$w*$3+$1-1;for$z(0..$k){ # iterate over rows, columns
    $x=$v?$k-$z:$z;   # flip x co-ordinate based on 2nd param
    $q=($y+$1-1)/$1|0;$r=$x/$w|0;   # parallelogram row and column index
    $d=$q+$r&1;  # flag parallelogram as left or right leaning
    $f=($y-1)%$1;$f=$1-$f-1if$d;  # compute a zig-zag offset
    $g=($x-$f)%$w;  # compute column position, offset by zig-zag
    $u=$r;$q=2*$3-$q+1,$u++if$q>$3; # vertical threshold for printing chars   
    print(($q>=$r&&$q&&$g==0)||($q>$r&&$g==$w-$1)?$d^$v?'/':'\\': # output slash
    $q>=$u&&$y%$1==0&&$g>0&&$g<($w-$1+($q==$r))?"_":$") # underscore or space
}print$/}   # print out newline at end of row

출력 예 :

2/3
                _____  
               /\    \ 
         _____/  \____\
        /\    \  /    /
  _____/  \____\/____/ 
 /\    \  /    /\    \ 
/  \____\/____/  \____\
\  /    /\    \  /    /
 \/____/  \____\/____/ 
       \  /    /\    \ 
        \/____/  \____\
              \  /    /
               \/____/ 

또한 단일 문자 변수 이름의 고급 스러움에서 바이트를 절약하기를 희망하면서 동일한 알고리즘을 사용하여 C 함수로 구현하려고 시도했지만 358 바이트에서 15 바이트 더 커졌습니다 ( -std=c89gcc에서 컴파일해야 합니다) void함수 헤더)

j(char*s){int c,p,v,x,y,k,z,u,g,w,r,d,q,f;char e;sscanf(s,"%d%c%d",&c,&e,&p);v=e=='/';w=c*3+1;for(y=0;y<=c*2*p;y++){k=w*p+c-1;for(z=0;z<=k;z++){x=v?k-z:z;q=(y+c-1)/c;r=x/w;d=q+r&1;f=(y+c-1)%c;if(d)f=c-f-1;g=(x-f)%w;u=r;if(q>p){q=2*p-q+1;u++;}printf("%c",(q>=r&&q&&g==0)||(q>r&&g==w-c)?d^v?'/':'\\':q>=u&&y%c==0&&g>0&&g<(w-c+(q==r))?'_':' ');}printf("\n");}}

: 그 15 바이트가 C 버전에 다시 모든 경우, 대부분을 얻을 수 있어야합니다 printf("%c" --> putchar(, printf("\n") --> puts("")다음, 당신은 제거 할 수 있습니다, 기능 이외의 모든 INT 선언을 이동 int (참조 meta.codegolf.stackexchange.com/q/5532/15599를 ), ASCII 코드의 모든 문자 리터럴을 변경하십시오 (예 :) ' ' --> 32. for 루프를 리팩토링하는 for(k+1;z--;)것도 도움이 될 수 있지만 더 까다 롭습니다.
Level River St

또한 e0으로 초기화하면 int가 될 수 있다고 생각 합니다. sscanf 가장 중요한 바이트 만 덮어 쓰고 다른 3 바이트에 기존 가비지를 남길 수 있습니다.
Level River St

마지막 으로이 경우 전체 프로그램이 함수보다 더 나을 것이라고 생각합니다. 당신은 3 명의 추가 캐릭터를 얻습니다main대신j 만 매개 변수를 전달할 필요가 없으며 s전역 변수의 자동 초기화를 활용할 수 있습니다.
Level River St

3

루비, 332

지금까지 행한 유일한 골프는 의견과 들여 쓰기를 제거하는 것입니다. 나는 나중에 골프를 할 것이다.

gets.match(/\D/)
d=$&<=>"@"
n=$`.to_i
m=2*n
p=$'.to_i
a=(0..h=4*n*p).map{' '*h*2}
(p*p).times{|j|
x=h-j/p*(3*n+1)*d
y=h/2+(j/p-j%p*2)*n
if j%p<=j/p
(-n).upto(n){|i|
a[y+i][i>0?x+m+1-i :x-m-i]=?/
a[y+i][i>0?x-m-1+i :x+m+i]='\\'
a[y+n][x+i]=a[y-n][x+i]=a[y][x-d*(n+i-1)]=?_
a[y+i+(i>>9&1)][x+d*i.abs]='\_/'[(0<=>i*d)+1]
}
end
}
puts a

공백 배열을 설정하고 개별 문자를 찌릅니다. 여분의 코드를 피하기 위해 하나의 큐브를 다른 큐브의 상단 (아래에서 위로)과 큐브 자체에서 모두 너무 많이 그릴 수 있습니다. 나는 마름모 ( /codegolf//a/54297/15599 와 유사 )를 그리고 상반부를 억압 하여 피라미드를 만듭니다 .

어려운 부분은 확장 가능한 큐브를 그리는 것이 었습니다. _수평면에 2n + 1 문자 가있는 둘레 육각형으로 시작했습니다 . 또한 + 1 2N를 확실하게 주도했습니다 /\나는 너무 많은 일이 있었다, 그러나 음모에 의해, 그래서 _그들을 덮어 쓰기 마지막 I를.

내부 선은 큐브가 향하는 방향에 따라 변경되는 유일한 선입니다. 나는 모든/\하나의 과제로. abs방향 i>>9&1을 바꾸고 i의 음수 값에 1을 더 추가하여 상단 부분을 내립니다. 위한 i요구 중 하나가 = 0 _overplotted이므로, 셀렉터 문자열 '\_/'의 기호에 따라 선택되는 세 개의 심볼들을 포함 i.

출력 주변의 공백은 충분하지만 과도하지는 않습니다. 4 * p * n 높이 및 8 * p * n 너비 (후자는 정점 큐브가 항상 출력의 중심에있게하는 것입니다.) "트레일 링 / 리딩 공백 "으로 줄 바꿈해야하지만 필요한 경우 수정할 수 있습니다.

Ungolfed 코드

gets.match(/\D/)                                   #find the symbol that is not a digit. it can be extracted from $&
d=$&<=>"@"                                         #direction, -1 or 1 depends if ascii code for symbol is before or after "@"
n=$`.to_i                                          #side length extracted from match variable $`
m=2*n
p=$'.to_i                                          #pyramid height extracted from match variable $'
a=(0..h=4*n*p).map{' '*h*2}                        #setup an array of h strings of h*2 spaces

(p*p).times{|j|                                    #iterate p**2 times
  x=h-j/p*(3*n+1)*d                                #calculate x and y coordinates for each cube, in a rhombus
  y=h/2+(j/p-j%p*2)*n                              #x extends outwards (and downwards) from the centre, y extends upwards 

  if j%p<=j/p                                      #only print the bottom half of the rhombus, where cube y <= cube x  
    (-n).upto(n){|i|                               #loop 2n+1 times, centred on the centre of the cube 
      a[y+i][i>0?x+m+1-i :x-m-i]=?/                #put the / on the perimeter of the hexagon into the array          
      a[y+i][i>0?x-m-1+i :x+m+i]='\\'              #and the \ also.
      a[y+n][x+i]=a[y-n][x+i]=a[y][x-d*(n+i-1)]=?_ #plot all three lines of _ overwriting the / and \ on the top line    
      a[y+i+(i>>9&1)][x+d*i.abs]='\_/'[(0<=>i*d)+1]#plot the internal / and \ overwriting unwanted _
    }
  end
}
puts a
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.