Xây dựng cho tôi một Kim tự tháp


16

Bạn cần xây dựng một kim tự tháp từ các hình khối. Hình khối có thể được nhìn từ 2 góc độ:

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

Đây là một ví dụ cho hình khối 2 kích thước từ 2 góc có thể. Chiều cao của hình khối là $sizedấu gạch chéo (hoặc dấu gạch chéo ngược) và chiều rộng của hình khối là 2 * $sizedấu gạch dưới. Độ rộng cấp cao nhất phải chứa thêm một ký tự gạch dưới.

Đầu vào sẽ được cung cấp dưới dạng một chuỗi chứa một số (kích thước của hình khối), dấu gạch chéo hoặc dấu gạch chéo ngược (để chỉ hướng / góc) và một số khác (chiều cao của hình chóp).

Ví dụ:

Đầu vào:

1/1

Đầu ra:

 ___
/\__\
\/__/

Đầu vào:

1\1

Đầu ra:

 ___
/__/\
\__\/

Đầu vào:

2/1

Đầu ra:

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

Đầu vào:

1/2

Đầu ra:

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

Đầu vào:

2\2

Đầu ra:

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

Đầu vào:

1/3

Đầu ra:

         ___  
     ___/\__\
 ___/\__\/__/
/\__\/__/\__\
\/__/\__\/__/
    \/__/\__\
        \/__/
  • Trailing / khoảng trắng hàng đầu là OK.
  • Sơ hở tiêu chuẩn là không được phép.
  • Bạn có thể cho rằng đầu vào sẽ luôn hợp lệ.
  • Bạn có thể cho rằng đầu vào sẽ không gây ra đầu ra quá lớn, tức là: không bao bọc dòng khi đầu ra được in tới thiết bị đầu cuối.
  • Kích thước của hình khối & chiều cao của hình chóp là dương (tức là ≥ 1)
  • Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte thắng.

Người chiến thắng hiện tại là:

Glen O với 270 byte trong julia

thách thức vẫn mở nếu bạn đánh bại tốt nhất hiện tại, tôi sẽ cập nhật câu trả lời được chấp nhận.


2
Các hình khối của bạn khác với các hình khối trong các thử thách mô hình kim cương gần đây, trong đó hàng trên cùng có 2s + 1 gạch dưới, trong đó các thử thách khác có 2s ở dưới hàng đầu và 2s-1 ở các hàng khác. Điều đó có nghĩa là sân ngang của bạn là 3 giây + 1. Tôi đoán thật tốt khi trộn mọi thứ xung quanh. Chỉ cần làm cho quan sát trong trường hợp ai đó bỏ lỡ nó.
Cấp sông St

1
các giá trị tối đa của kích thước và chiều cao là gì? chúng ta có thể giả sử chúng là một chữ số không?
Cấp sông St

không, bạn có thể không cho rằng đó là một chữ số, nhưng bạn có thể cho rằng đầu vào được cung cấp sẽ không khiến đầu ra "quá lớn", tức là sẽ không gây ra sự bao bọc dòng trong thiết bị đầu cuối của bạn.
gilad hoch

Câu trả lời:


3

Julia - 503 455 369 346 313 270 byte

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))...))

Ung dung:

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

Sử dụng:

f("3/2")

hoặc là

f("2\\3")

9

Perl, 343 byte

$_=<>;$_=~/(\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$/}

Multiline với ý kiến:

$_=<>;$_=~/(\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

Ví dụ đầu ra:

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

Tôi cũng đã thử triển khai nó như là một hàm C sử dụng cùng một thuật toán, hy vọng sẽ tiết kiệm được byte từ sự xa xỉ của các tên biến ký tự đơn, nhưng nó đã kết thúc lớn hơn 15 byte, ở mức 358 byte (cần được biên dịch với -std=c89gcc để loại bỏ các voidtrong tiêu đề chức năng):

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");}}

Bạn sẽ có thể nhận được hầu hết, nếu không nói là tất cả những 15 byte sao trên phiên bản C: printf("%c" --> putchar(, printf("\n") --> puts(""), di chuyển tất cả các tờ khai int ngoài chức năng, sau đó bạn có thể loại bỏ int (xem meta.codegolf.stackexchange.com/q/5532/15599 ), thay đổi tất cả các ký tự bằng chữ cho mã ascii của họ, vd ' ' --> 32. Tái cấu trúc các vòng lặp của bạn, ví dụ for(k+1;z--;)cũng có thể giúp nhưng khó hơn.
Cấp sông St

Ngoài ra tôi nghĩ ecó thể là một int miễn là bạn khởi tạo nó bằng không. sscanf sẽ chỉ ghi đè lên byte có ý nghĩa nhỏ nhất và có thể để lại bất kỳ rác hiện có trong ba byte khác.
Cấp sông St

cuối cùng tôi nghĩ rằng một chương trình đầy đủ sẽ tốt hơn một chức năng trong trường hợp này. Bạn nhận được thêm ba ký tự mainthay vì jnhưng bạn không phải truyền tham số sxung quanh và bạn có thể tận dụng việc khởi tạo tự động các biến toàn cục.
Cấp sông St

3

Ruby, 332

Việc chơi golf duy nhất được thực hiện cho đến nay là loại bỏ các bình luận và thụt lề. Tôi sẽ chơi gôn sau.

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

Tôi thiết lập một mảng các khoảng trắng và chọc các ký tự riêng lẻ vào đó. Có khá nhiều việc rút cả hai khối này lên trên một khối khác (làm việc từ dưới lên trên) và trong chính khối đó, để tránh thêm mã. Tôi tạo ra kim tự tháp bằng cách vẽ một hình thoi (tương tự /codegolf//a/54297/15599 ) và thay thế nửa trên.

Phần khó là vẽ khối có thể mở rộng. Tôi bắt đầu với một hình lục giác chu vi với 2n + 1 _ký tự ở các cạnh ngang. Tôi cũng đã có 2n + 1 /\vì vậy tôi có quá nhiều, nhưng bằng cách vẽ âm mưu _cuối cùng tôi đã ghi đè lên chúng.

Các đường bên trong là những đường duy nhất được thay đổi tùy theo hướng mà khối lập phương phải đối mặt. Tôi vẽ tất cả /\với một nhiệm vụ duy nhất. absgiúp đảo ngược hướng và i>>9&1thêm 1 vào các giá trị âm của i, làm giảm phần trên xuống. for i= 0 một trong những yêu cầu _được đặt quá mức, do đó, chuỗi chọn '\_/'chứa tất cả ba ký hiệu, được chọn theo dấu của i.

Khoảng trắng xung quanh đầu ra rộng rãi nhưng không quá lớn: cao 4 * p * n và rộng 8 * p * n (cái sau là để cho khối lập phương đỉnh luôn ở giữa tâm đầu ra.) Tôi hiểu "theo dõi / dẫn đầu khoảng trắng "để bao gồm toàn bộ dòng, nhưng có thể sửa đổi nếu cần thiết.

Mã mã

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.