Bana Bir Piramit İnşa Et


16

Küplerden bir piramit inşa etmeniz gerekiyor. Küpler 2 açıdan görüntülenebilir:

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

Bu, 2 olası açıdan 2 boyutlu küpler için bir örnektir. Küplerin yüksekliği $sizeeğik çizgilerdir (veya ters eğik çizgilerdir) ve küpün genişliği2 * $size alt . Üst düzey genişlik fazladan bir alt çizgi karakteri içermelidir.

Giriş, bir sayı (küplerin boyutu), eğik çizgi veya ters eğik çizgi (yönü / açıyı belirtmek için) ve başka bir sayı (piramidin yüksekliği) içeren bir dize olarak sağlanacaktır.

Örnekler:

Giriş:

1/1

Çıktı:

 ___
/\__\
\/__/

Giriş:

1\1

Çıktı:

 ___
/__/\
\__\/

Giriş:

2/1

Çıktı:

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

Giriş:

1/2

Çıktı:

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

Giriş:

2\2

Çıktı:

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

Giriş:

1/3

Çıktı:

         ___  
     ___/\__\
 ___/\__\/__/
/\__\/__/\__\
\/__/\__\/__/
    \/__/\__\
        \/__/
  • İzleyen / önde gelen boşluklar sorun değil.
  • Standart boşluklara izin verilmez.
  • Girişin her zaman geçerli olacağını varsayabilirsiniz.
  • Girişin çok büyük bir çıktıya neden olmayacağını varsayabilirsiniz, yani: çıktı terminale yazdırıldığında hiçbir satır sarma yoktur.
  • Küpün boyutu ve piramidin yüksekliği pozitiftir (yani ≥ 1)
  • Bu kod golf, bayt en kısa kod kazanır.

Mevcut Kazanan:

Glen O 270 bayt ile

meydan okuma açık kalır. mevcut olanı geçerseniz, kabul edilen cevabı güncelleyeceğim.


2
Küpleriniz son elmas desen zorluklarından farklıdır, üst sıra 2s + 1 alt çizgilere sahipken, diğer zorlukların üst sırada 2s alt çizgi ve diğer satırlarda 2s-1 vardı. Bu yatay adımınızın 3s + 1 olduğu anlamına gelir. Sanırım bir şeyleri karıştırmak güzel. Sadece birinin gözden kaçırması durumunda gözlem yapmak.
Level River St

1
maksimum boyut ve yükseklik değerleri nelerdir? bunların bir basamak olduğunu varsayabilir miyiz?
Level River St

hayır, bir basamak olduğunu varsaymayabilirsiniz, ancak sağlanan girdinin çıktının "çok büyük" olmasına, yani terminalinizde satır kaydırmasına neden olmayacağını varsayabilirsiniz.
gilad hoch

Yanıtlar:


3

Julia - 503 455 369 346 313 270 bayt

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

Ungolfed:

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

Kullanımı:

f("3/2")

veya

f("2\\3")

9

Perl, 343 bayt

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

Yorumlu çok satırlı:

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

Örnek çıktı:

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

Ayrıca, tek karakterli değişken adlarının lüksünden baytları kaydetmeyi umarak aynı algoritmayı kullanarak bir C işlevi olarak uygulamayı denedim, ancak 358 baytta 15 bayt daha büyük oldu ( -std=c89ayrılmak için gcc altında derlenmesi gerekiyor) voidfonksiyon başlığında):

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

: Bu 15 bayt C sürümüne desteklemeyeceğini tüm eğer, en iyi şekilde mümkün olmalıdır printf("%c" --> putchar(, printf("\n") --> puts("")o zaman ortadan kaldırabilir, fonksiyonu dışında tüm int bildirimleri taşımak int (bkz meta.codegolf.stackexchange.com/q/5532/15599 ), ascii kodları için tüm karakter değişmez değerlerini değiştirin ' ' --> 32. Döngüler için yeniden düzenleme for(k+1;z--;)de yardımcı olabilir ancak daha zordur.
Level River St

Ayrıca esıfır olarak başlatmak koşuluyla bir int olabilir düşünüyorum . sscanf yalnızca en az anlamlı baytın üzerine yazar ve diğer üç baytta mevcut çöpleri bırakabilir.
Level River St

Son olarak, tam bir programın bu durumda bir işlevden daha iyi olacağını düşünüyorum. Bunun mainyerine üç ekstra karakter kazanırsınız , jancak parametrenin setrafından geçmeniz gerekmez ve global değişkenlerin otomatik olarak başlatılmasından faydalanabilirsiniz.
Level River St

3

Yakut, 332

Şimdiye kadar yapılan tek golf yorumların ve girintilerin ortadan kaldırılmasıdır. Daha sonra golf oynayacağım.

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

Bir dizi boşluk ayarladım ve karakterleri içine soktum. Ekstra koddan kaçınmak için bir küpün her ikisini de diğerinin üzerine (aşağıdan yukarıya doğru) ve küpün içinde aşırı miktarda çekiyor. Piramidi bir eşkenar dörtgen çizerek ( /codegolf//a/54297/15599 benzeri ) ve üst yarıyı bastırarak yapıyorum .

Zor kısım ölçeklenebilir küpü çiziyordu. _Yatay kenarlarda 2n + 1 karakterli bir çevre altıgeni ile başladım . Ayrıca 2n + 1 vardı /ve \bu yüzden çok fazla vardı, ama _son çizerek onları üzerine yazdım.

İç çizgiler, küpün baktığı yöne bağlı olarak değiştirilen tek çizgilerdir. Ben tüm /ve \tek bir ödev ile arsa . absyönü tersine çevirmeye yardımcı olur ve i>>9&1i'nin negatif değerlerine üst kısmı aşağı indiren fazladan bir 1 ekler. for i= 0 için gerekli olanlardan biri fazla _çizilir, bu nedenle seçici dize '\_/', işaretine göre seçilen üç simgenin tümünü içerir i.

Çıktının etrafındaki boşluk geniş ama aşırı değil: 4 * p * n yüksek ve 8 * p * n geniş (ikincisi, apeks küpünün her zaman çıktının merkezinde olmasını sağlamaktır.) whitespaces ", tüm satırları içermesine karşın, gerekirse revize edilebilir.

Kod çözülmemiş kod

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.