Baue mir eine Pyramide


16

Sie müssen eine Pyramide aus Würfeln bauen. Würfel können aus 2 Blickwinkeln betrachtet werden:

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

Dies ist ein Beispiel für Würfel der Größe 2 aus den 2 möglichen Winkeln. Die Höhe der Würfel ist ein $sizeSchrägstrich (oder ein umgekehrter Schrägstrich), und die Breite des Würfels ist ein 2 * $sizeUnterstrich. Die Breite der obersten Ebene sollte einen zusätzlichen Unterstrich enthalten.

Die Eingabe erfolgt als Zeichenfolge, die eine Zahl (Würfelgröße), einen Schrägstrich oder einen umgekehrten Schrägstrich (zur Angabe von Richtung / Winkel) und eine andere Zahl (Höhe der Pyramide) enthält.

Beispiele:

Eingang:

1/1

Ausgabe:

 ___
/\__\
\/__/

Eingang:

1\1

Ausgabe:

 ___
/__/\
\__\/

Eingang:

2/1

Ausgabe:

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

Eingang:

1/2

Ausgabe:

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

Eingang:

2\2

Ausgabe:

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

Eingang:

1/3

Ausgabe:

         ___  
     ___/\__\
 ___/\__\/__/
/\__\/__/\__\
\/__/\__\/__/
    \/__/\__\
        \/__/
  • Nachgestellte / führende Leerzeichen sind in Ordnung.
  • Standardlücken sind nicht zulässig.
  • Sie können davon ausgehen, dass Eingaben immer gültig sind.
  • Sie können davon ausgehen, dass die Eingabe keine zu große Ausgabe verursacht, z. B .: kein Zeilenumbruch, wenn die Ausgabe auf dem Terminal gedruckt wird.
  • Größe des Würfels & Höhe der Pyramide ist positiv (dh ≥ 1)
  • Das ist Code-Golf, also gewinnt der kürzeste Code in Bytes.

Aktueller Gewinner ist:

Glen O mit 270 Bytes in Julia

Herausforderung bleibt offen. Wenn Sie die aktuelle Bestleistung erzielen, aktualisiere ich die akzeptierte Antwort.


2
Ihre Würfel unterscheiden sich von denen in den letzten Diamantmuster-Herausforderungen, da die oberste Reihe 2s + 1-Unterstriche aufweist, während die anderen Herausforderungen 2s-Unterstriche in der obersten Reihe und 2s-1 in den anderen Reihen aufwiesen. Das bedeutet, dass Ihre horizontale Tonhöhe 3s + 1 beträgt. Ich denke, es ist gut, Dinge zu mischen. Nur die Beobachtung machen, falls jemand sie verpasst.
Level River St

1
Was sind die Maximalwerte für Größe und Höhe? Können wir annehmen, dass sie eine Ziffer sind?
Level River St

nein, Sie können davon ausgehen, dass es sich nicht um eine Ziffer handelt, aber Sie können davon ausgehen, dass die Eingabe nicht dazu führt, dass die Ausgabe "zu groß" ist, dh dass in Ihrem Terminal kein Zeilenumbruch auftritt.
Gilad Hoch

Antworten:


3

Julia - 503 455 369 346 313 270 Bytes

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

Verwendung:

f("3/2")

oder

f("2\\3")

9

Perl, 343 Bytes

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

Mehrzeilig mit Kommentaren:

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

Beispielausgabe:

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

Ich habe auch versucht, es mit dem gleichen Algorithmus als C-Funktion zu implementieren, in der Hoffnung, Bytes aus dem Luxus von Variablennamen mit einzelnen Zeichen zu sparen, aber es endete 15 Bytes größer, bei 358 Bytes (muss mit -std=c89unter gcc kompiliert werden , um aufzuhören) das voidim Funktionsheader):

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

Sie sollten in der Lage sein , die meisten zu bekommen, wenn nicht alle diese 15 Bytes auf der C - Version zurück: printf("%c" --> putchar(, printf("\n") --> puts(""), alle int Erklärungen außerhalb der Funktion bewegen, dann kann man das beseitigen int (siehe meta.codegolf.stackexchange.com/q/5532/15599 ), ändern Sie alle Zeichenliterale für ihre ASCII-Codes, z ' ' --> 32. Das Refactoring von for-Schleifen for(k+1;z--;)kann ebenfalls hilfreich sein, ist jedoch schwieriger.
Level River St

Ich denke auch, ekann ein Int sein, vorausgesetzt, Sie initialisieren es auf Null. sscanf überschreibt nur das niederwertigste Byte und hinterlässt eventuell vorhandenen Müll in den anderen drei Bytes.
Level River St

Schließlich denke ich, dass ein vollständiges Programm in diesem Fall besser als eine Funktion ist. Sie erhalten mainstattdessen drei zusätzliche Zeichen j, müssen aber keine Parameter übergeben s, und Sie können die automatische Initialisierung globaler Variablen nutzen.
Level River St

3

Ruby, 332

Das einzige, was bisher gemacht wurde, ist das Eliminieren von Kommentaren und Einrückungen. Ich werde später Golf spielen.

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

Ich richte eine Reihe von Leerzeichen ein und stecke die einzelnen Zeichen hinein. Es gibt eine Menge Überzeichnungen von einem Würfel auf den anderen (Arbeiten von unten nach oben) und innerhalb des Würfels selbst, um zusätzlichen Code zu vermeiden. Ich mache die Pyramide, indem ich eine Raute zeichne (ähnlich wie /codegolf//a/54297/15599 ) und die obere Hälfte unterdrücke.

Der schwierige Teil war das Zeichnen des skalierbaren Würfels. Ich habe mit einem Perimeter-Sechseck mit 2n + 1 _Zeichen an den horizontalen Seiten begonnen. Ich hatte auch 2n + 1 /und \, also hatte ich eine zu viele, aber indem _ich die letzte geplottet habe, habe ich sie überschrieben.

Die internen Linien sind die einzigen, die abhängig von der Richtung, in die der Würfel zeigt, geändert werden. Ich zeichne alles /und \mit einer einzigen Aufgabe. absDies hilft, die Richtung umzukehren, und i>>9&1fügt den negativen Werten von i eine zusätzliche 1 hinzu, wodurch der obere Teil nach unten abgesenkt wird. Für i= 0 ist eines der erforderlichen Symbole _überzeichnet, sodass die Auswahlzeichenfolge '\_/'alle drei Symbole enthält, die nach dem Vorzeichen von ausgewählt wurden i.

Der Leerraum um die Ausgabe ist groß, aber nicht zu groß: 4 * p * n hoch und 8 * p * n breit (letzteres soll ermöglichen, dass sich der Apex-Würfel immer in der Mitte der Ausgabe befindet.) Leerzeichen ", um ganze Zeilen einzuschließen, kann aber bei Bedarf überarbeitet werden.

Ungolfed Code

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.