给我建一个金字塔


16

您需要从多维数据集构建金字塔。多维数据集可以从2个角度查看:

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

这是从2个可能角度的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。我想把事情混在一起是件好事。只是进行观察,以防有人错过。
水平河圣

1
尺寸和高度的最大值是多少?我们可以假设它们是一位数字吗?
Level St

不,您可能不会假设它是一位数字,但是您可能会假设提供的输入不会导致输出“太大”,即不会在终端中引起换行。
吉拉德·霍奇

Answers:


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

Perl,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函数,希望从单字符变量名称的奢侈中节省字节,但最终它增加了15个字节,为358个字节(需要-std=c89在gcc下进行编译,以免删除)的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--;)也可以帮助但更棘手。
水平河圣

我也认为e可以是一个int,只要将其初始化为零即可。sscanf 只会覆盖最低有效字节,并可能在其他三个字节中保留任何现有的垃圾。
水平河圣

最后,我认为在这种情况下,完整的程序会比功能更好。您可以从那里获得三个额外的字符mainj但不必传递参数s,并且可以利用全局变量的自动初始化功能。
水平河圣

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个字符的周边六角形开始。我也有2n + 1 /\,所以我有一个太多,但是通过绘制_最后一个,我将它们覆盖了。

内部线是唯一根据立方体面对的方向而更改的线。我通过一次分配来绘制所有/\abs有助于反转方向,并i>>9&1在i的负值上增加1,从而降低顶部。对于i= 0,必填项之一将_被过度绘制,因此选择器字符串'\_/'包含所有三个符号,这些符号根据的符号选择i

输出周围的空白足够但不多余:高4 * p * n,宽8 * p * n(后者用于使顶点立方体始终位于输出的中心。)我理解“尾随/前导空白”以包含整行,但如有必要可以进行修改。

非高尔夫代码

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.