สร้างปิรามิดให้ฉัน


16

คุณต้องสร้างพีระมิดจากลูกบาศก์ ก้อนสามารถดูได้จาก 2 มุม:

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

นี่คือตัวอย่างสำหรับลูกบาศก์ขนาด 2 จากมุมที่เป็นไปได้ 2 มุม ความสูงของ$sizeคิวบ์คือสแลช (หรือแบ็กสแลช) และความกว้างของคิวบ์คือ2 * $sizeขีดล่าง ความกว้างระดับบนสุดควรมีอักขระขีดล่างพิเศษ

อินพุตจะถูกจัดเตรียมเป็นสตริงที่มีตัวเลข (ขนาดของคิวบ์), สแลชหรือแบ็กสแลช (เพื่อระบุทิศทาง / มุม) และตัวเลขอื่น (ความสูงของปิรามิด)

ตัวอย่าง:

การป้อนข้อมูล:

1/1

เอาท์พุท:

 ___
/\__\
\/__/

การป้อนข้อมูล:

1\1

เอาท์พุท:

 ___
/__/\
\__\/

การป้อนข้อมูล:

2/1

เอาท์พุท:

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

การป้อนข้อมูล:

1/2

เอาท์พุท:

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

การป้อนข้อมูล:

2\2

เอาท์พุท:

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

การป้อนข้อมูล:

1/3

เอาท์พุท:

         ___  
     ___/\__\
 ___/\__\/__/
/\__\/__/\__\
\/__/\__\/__/
    \/__/\__\
        \/__/
  • ช่องว่างต่อท้าย / นำหน้าช่องว่างตกลง
  • ช่องโหว่มาตรฐานไม่ได้รับอนุญาต
  • คุณสามารถสมมติว่าการป้อนข้อมูลจะถูกต้องเสมอ
  • คุณอาจสันนิษฐานว่าอินพุตจะไม่ก่อให้เกิดผลลัพธ์ที่ใหญ่เกินไปเช่น: ไม่มีการตัดบรรทัดเมื่อพิมพ์ผลลัพธ์ไปยังเทอร์มินัล
  • ขนาดของคิวบ์และความสูงของพีระมิดเป็นค่าบวก (เช่น≥ 1)
  • นี่คือ code-golf ดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

ผู้ชนะปัจจุบันคือ:

เกลนโอที่มี 270 ไบต์ในจูเลีย

ความท้าทายยังคงเปิดอยู่ หากคุณชนะได้ดีที่สุดฉันจะอัปเดตคำตอบที่ยอมรับได้


2
ก้อนของคุณแตกต่างจากก้อนหินในการท้าทายรูปแบบเพชรที่ผ่านมาซึ่งแถวบนสุดมีขีดล่าง 2s + 1 ขีดความท้าทายอื่น ๆ มีขีดล่าง 2s ที่แถวบนสุดและ 2s-1 ที่แถวอื่น นั่นหมายถึงระยะห่างระหว่างแนวนอนของคุณคือ 3s + 1 ฉันคิดว่ามันดีที่จะผสมสิ่งต่าง ๆ รอบ ๆ เพียงแค่ทำการสังเกตในกรณีที่มีคนคิดถึงมัน
เลเวลริเวอร์เซนต์

1
ค่าสูงสุดของขนาดและส่วนสูงคืออะไร เราคิดว่ามันเป็นเลขหนึ่งหลักได้ไหม?
Level River St

ไม่คุณอาจไม่คิดว่ามันเป็นหนึ่งหลัก แต่คุณอาจสันนิษฐานว่าอินพุตที่ให้มาจะไม่ทำให้ผลลัพธ์เป็น "ใหญ่เกินไป" นั่นคือจะไม่ทำให้เกิดการตัดบรรทัดในเทอร์มินัลของคุณ
gilad hoch

คำตอบ:


3

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

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

การใช้งาน:

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=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(k+1;z--;)อาจช่วยได้ แต่มีเล่ห์เหลี่ยม
เลเวลริเวอร์เซนต์

นอกจากนี้ฉันคิดว่าeสามารถเป็น int หากคุณเริ่มต้นเป็นศูนย์ sscanf จะเขียนทับไบต์ที่มีนัยสำคัญน้อยที่สุดเท่านั้นและอาจทิ้งขยะที่มีอยู่ในอีกสามไบต์
เลเวลริเวอร์เซนต์

ในที่สุดฉันคิดว่าโปรแกรมเต็มรูปแบบจะดีกว่าฟังก์ชั่นในกรณีนี้ คุณได้รับสามอักขระพิเศษจากmainแทนที่จะเป็นjแต่คุณไม่จำเป็นต้องผ่านพารามิเตอร์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เพิ่ม 1 พิเศษให้กับค่าลบของ i ซึ่งจะลดส่วนบนลง สำหรับi= 0 หนึ่งที่จำเป็นต้อง_มีการ overplotted ดังนั้นสตริงตัวเลือกมีทั้งสามสัญลักษณ์เลือกตามสัญลักษณ์ของ'\_/'i

ช่องว่างรอบ ๆ เอาต์พุตมีขนาดใหญ่ แต่ไม่มากเกินไป: 4 * p * n สูงและกว้าง 8 * p * n (หลังคือเปิดใช้คิวบ์ apex ให้อยู่ในกึ่งกลางของเอาต์พุต) ฉันเข้าใจ "การต่อท้าย / นำหน้า whitespaces "เพื่อรวมทั้งบรรทัด แต่สามารถแก้ไขได้ถ้าจำเป็น

รหัสไม่ได้รับการตอบ

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.