Eingebettete Sechsecke!

18

Ihre Aufgabe: Geben Sie eine Ganzzahl ein nund generieren Sie ein eingebettetes Sechseckmuster gemäß den folgenden Regeln bis zur n-ten Tiefe.

Ein eingebettetes Sechseck hat folgende Grundform: ( n=0)

 __      
/  \
\__/

Eingebettete Sechsecke n=1und n=2:

  ____    
 /  \ \
/\__/  \
\      /
 \____/

    ________    
   /  \ \   \
  /\__/  \   \
 /\      /    \
/  \____/      \
\              /
 \            /
  \          /
   \________/

Die Länge jeder Seite beträgt das Zweifache der Länge derselben Seite in der vorherigen Tiefe das Zweifache. Die obere und untere Seite haben eine Länge von 2 Zeichen, n=0der Rest beginnt mit einer Länge von 1 Zeichen. Die nicht von oben nach unten verlaufenden Seitenlängen sollten 2^nlang sein ( OEIS: A000079 ) und die Ober- und Unterseite sollten der Regel entsprechen 2^(n+1)(gleiches OEIS).

Die aktuellen Sechsecke sind 0-indiziert. Sie können auch 1-indiziert verwenden, wenn Sie möchten.

Das ist , also gewinnt die kürzeste Antwort!

Genosse SparklePony
quelle
@ LuisMendo Okay, ich werde den Namen ändern.
Genosse SparklePony
Es kann schwierig sein, große Eingaben zu verarbeiten (z. B. 64). Gibt es eine Grenze zu n?
Matthew Roh
@SIGSEGV Es gibt keine Begrenzung für n.
Genosse SparklePony
1
Wäre amüsiert, eine Antwort in Hexagony zu sehen :))
Mr. Xcoder
1
Heh, die Schildkrötengrafiken meiner Kochkurvenübermittlung können das auch (nur erste Funktion geändert). Auf jeden Fall zu lang dafür :)
Ørjan Johansen

Antworten:

10

Kohle , 40 29 Bytes

Dank @Neil konnten 11 Bytes gespart werden, indem die while-Schleife unter anderem in eine for-Schleife geändert wurde

FN«AX²ιβ×__β↓↘β←↙β↑←×__β↖β→↗β

Probieren Sie es online!

Erklärung (veraltet)

Dieses Programm beginnt mit der Generierung des größten Sechsecks und führt die kleineren nacheinander in einer while-Schleife (1-indiziert) aus. Als Referenz αdient die Eingabenummer, βdie Variable, die enthält, 2^(α-1)und ιdie sich wiederholende Variable in der Schleife.

Nα                        # Take input and store in α
Wα«                       # While α do:
 ×_X²ι                    #  Write "_"*(2**ι); this forms the top edge of the hexagon
 ↓                         #  Go down
 AX²⁻ι¹β                 #  Assign 2**(ι-1) to β
 ↘β←                       #  Write \ β times in a SE direction (top right edge) and then go left
 ↙β↑                       #  Write / β times in a SW direction (bottom right edge) and then go up
 ←×_X²ι                   #  Write the bottom edge
 ↖β→↗β                    #  Just like before, write the top and bottom left edges
 A⁻α¹α                    #  Decrement α
                          # Now the pointer is at the top left corner of the hexagon,
                          # from where the other smaller hexagons will soon be generated
Kritixi Lithos
quelle
Mir ist aufgefallen, dass es kein "Hallo Welt!" Programm für Holzkohle noch. Sie sollten es hinzufügen.
mbomb007
@ mbomb007 Wäre das nicht einfach ein Duplikat der trivialen Antwort "Diese Sprache druckt ihre Quelldatei, wenn sie keine Befehle enthält"?
Neil
Ich habe ein paar Bytes gespart, als mir klar wurde, dass dies ×_X²ιdasselbe ist wie ×__β, und ein paar weitere Bytes durch Konvertieren von your in a , wodurch auch vermieden wird, dass die eingegebene Nummer gespeichert werden muss. Probieren Sie es online! .
Neil
@ Neil Danke, das ist ziemlich ordentlich :)
Kritixi Lithos
5

Haskell , 230 217 207 Bytes

BEARBEITEN:

  • -13 bytes: @xnor hat gesehen, dass meine #gerecht sein könnte max.
  • -10 Bytes: Und auch das zipWithund pkönnte zu einem ?Operator zusammengeführt werden, und das würde ich (irgendwie!) Neu implementieren replicate.

mnimmt ein Integerund gibt ein zurück String.

m n=unlines.foldr1 o$((2^n)&).(2^)<$>[0..n]
l&t|a<-c[l,2*t]" _",b<-[c[l-i,1,2*t+2*i-2,1,l-i]" / \\ "|i<-[1..t]]=a:b++r(r<$>o[a]b)
c=(concat.).z replicate
o=max?' '?""
f?e=z f.(++repeat e)
r=reverse
z=zipWith

Probieren Sie es online!

Wie es funktioniert

  • mist die Hauptfunktion. Es verwendet &, um die Sechsecke mit der richtigen Polsterung zu erzeugen, und faltet sie dann zusammen mit o.
  • l&tErzeugt ein kleines Sechseck mit Seitenlänge t, das innerhalb eines großen Sechsecks mit Seitenlänge gepolstert ist l, als Liste von StringLinien.
    • a ist die oberste Linie des Sechsecks mit den Unterstrichen.
    • bist eine Liste der anderen Zeilen in der oberen Hälfte des Sechsecks. Die Linien von bsind in der rechteckigen Polsterung zentriert. So kann der nächste Schritt ausgeführt werden.
    • Die untere Hälfte des Sechsecks ist a überlagerte oben auf bmit o, dann umgekehrt (um sowohl von Linien und innerhalb jeder Zeile).
  • cNimmt zwei Argumente, eine Liste von Längen und eine Zeichenfolge, und generiert eine Zeichenfolge, die so viele Kopien jedes Zeichens im Original enthält wie die entsprechende Länge, z c[1,3,2]"abc" == "abbbcc". Es wird verwendet &, um die Zeilen zu generieren.
  • o Nimmt zwei Argumente, die Bilder als Zeilenlisten darstellen, und überlagert das erste, kleinere Argument mit dem zweiten.
    • Es wird sowohl zum Kombinieren von Sechsecken als auch zum Hinzufügen des Bodens zu jedem Sechseck verwendet.
    • Es funktioniert im Wesentlichen, indem Sie ?das erste Bild zweimal mit unendlich vielen Leerzeichen nach unten und rechts auffüllen und dann die entsprechenden Zeichen mit zusammenzippen max, wodurch das Nicht-Leerzeichen ausgewählt wird, falls es eines gibt.
  • (f?e)l mfüllt eine Liste lmit unendlich vielen 'e'-Elementen auf und komprimiert dann die resultierende Liste und die Liste mmit der fFunktion.
Ørjan Johansen
quelle
1
Schöne lösung! Ich denke (#)kann sein max.
xnor
1
Das Zuziehen ist kombinierbar mit pzu speichern Bytes: o=max?' '?"";f?e=z f.(++repeat e). Könnte auch kürzer sein.
xnor
2
(\n->(<$[1..n]))ist replicate.
xnor
@xnor replicate? Das ist nur peinlich. Ich bin es einfach zu gewohnt <$[1..n]oder [1..n]>>gewinne fast immer. Ich verstehe jedoch nicht, wie ich ?weiter kürzen soll . Ich habe bereits versucht, ppointfree zu machen, und der ++ist einfach am falschen Ort und sprengt Dinge mit flip.
Ørjan Johansen
3

JavaScript (ES6), 258 Byte

f=(n,s=` `.repeat(1<<n),p=(n?f(n-1):`


`).replace(/(.*)\n/g,s+`$1 `+s)+s,t=`_`.repeat(2<<n))=>(s+t+s+`
`+s.replace(/ /g,"$'/$'$'  $`$`$`$`\\$'\n")).replace(/ /g,(c,i)=>p[i+(1<<n>>1)])+s.replace(/ /g,"$`\\$`$`  $'$'$'$'/$`\n").replace(/ +\/( *)\n$/,t+`/$1
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Erläuterung: Bei Sechsecken nach dem ersten wird zuerst das vorherige Sechseck generiert und auf jeder Seite aufgefüllt (dies setzt voraus, dass die Ausgabe ein Rechteck ist). (Für die erste Überschrift wird ein Teil des Platzhalters erzeugt.) Die oberen und oberen Seiten des Sechsecks werden generiert und alle Leerzeichen mit dem vorherigen Sechseck zusammengeführt. (Es gibt einige Tricks, um die Sechsecke in eine Linie zu bringen. Dies wäre einfacher, wenn zusätzliche Ränder zulässig wären.) Die unteren Seiten des Sechsecks werden analog zu den oberen Seiten erzeugt, und der Boden des Sechsecks wird dann ausgefüllt. Es muss darauf geachtet werden, dass rechteckige Ausgaben, einschließlich einer nachgestellten Newline, zurückgegeben werden, damit die Rekursion funktioniert.

Neil
quelle
Sie demonstrieren also, dass dieses, das Teflon-Modell und das Deep Dish Pizza-Modell, alle wirklich ähnlich aufgebaut sind? Das ist irgendwie ordentlich.
AdmBorkBork
1
@AdmBorkBork Ich habe ein paar andere Antworten, die das tun; Diese Diagonalen /sind in der ASCII-Kunst sehr beliebt, und die replaceMethode ist eine relativ kostengünstige Möglichkeit, sie in JavaScript zu generieren.
Neil
1<<n>>1: Schöne Symmetrie ;-)
Luke
@ Luke Ich könnte die Variable beispielsweise in ändern, vaber leider 1ist sie in keiner meiner üblichen Schriftarten symmetrisch.
Neil
2

PHP, 337 Bytes

0 Indizierung

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v));for(;1+$c;$c--)for($i=0;$i<$e=2**$c*2+1;$i++){$z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1;$h[$i]=substr_replace($h[$i],$s=str_pad(!$y?$z|$x?"\\":"":"/",$e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),$z|!$i?"_":" ").(!$y?$z|$x?"/":"":"\\"),$v-$z-$y*$i-$x*($e-$i),strlen($s));}echo join("\n",$h);

Probieren Sie es online!

Erweitert

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v)); # fill array with maximal width
for(;1+$c;$c--)  # greatest hexagon to lowest
for($i=0;$i<$e=2**$c*2+1;$i++){ # loop through the rows
    $z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1; # booleans last first ad second half
    $h[$i]=substr_replace($h[$i], # replace substring
    $s=str_pad(
        $z?"\\":($y?"/":($x?"\\":"")),
        $e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),
        $z|!$i?"_":" "
        ).(!$z?!$y?$x?"/":"":"\\":"/"), # with string for smaller hexagon
    $v-$z-$y*$i-$x*($e-$i), # at offset
    strlen($s));
}
echo join("\n",$h); # Output
Jörg Hülsermann
quelle