Schade, dass du aufgibst. Ist eigentlich eine wirklich nette Aufgabe
Hiermal meine Lösung inklusive Kommentare. Es wäre bestimmt für manch andere Anfänger hilfreich, wenn du kurz kommentierst, woran genau du bei dem Problem (im Vergleich zur Lösung) gescheitert bist.
Für mich wäre es auch interessant, damit ich weiß, womit Anfänger eher Probleme haben.
Ist sehr "sprechend" programmiert. Das kann man bis zur absolute Unkenntlichkeit kürzen und optimieren, aber darum gehts hier eher weniger denke ich.
Hiermal meine Lösung inklusive Kommentare. Es wäre bestimmt für manch andere Anfänger hilfreich, wenn du kurz kommentierst, woran genau du bei dem Problem (im Vergleich zur Lösung) gescheitert bist.
Für mich wäre es auch interessant, damit ich weiß, womit Anfänger eher Probleme haben.
PHP-Code:
<?php
function replaceCharsAtRow($line, $rowNum, $char) {
// Erstmal brauchen wir die Länge der zu verarbeitenden Zeile.
// Die ist zwar eigentlich immer gleich, aber damit die Funktion schön
// dynamisch bleibt, sollte davon erstmal nicht ausgegangen werden
$length = strlen($line);
// Nun berechnen wird, wo wir etwas ersetzen müssen, abhänging von
// der Länge der Stufe. Zunächst brauchen wir den Mittelpunkt.
// Da wir von einem 0-Index ausgehen, ist dieser mit der unten
// stehenden Formel direkt berechnet. Nehmen wir z.B. an, dass die Zeile
// 5 lang ist, so ist die "mitte" der Index "2". Also ziehen wir eins ab
// und halbieren den Rest. Somit kommen wir zuverlässig auf den Mittelpunktindex
$positionCenter = ($length - 1) / 2;
// Nun brauchen wir noch die Indizes der rechten und linken Ersetzungen.
// Diese hängen natürlich vom Mittelpunkt ab, denn dieser "wandert" ja,
// je länger die Zeile wird, immer weiter nach rechts.
// Da wir den Index der aktuellen Stufe haben (rowNum), können wir
// diesen relativ schön dafür benutzen, um je nach Stufe und je nach
// Mittelpunkt den genauen Index zu erhalten, an dem wir links (minus)
// und rechts (plus) ersetzen müssen
$positionLeft = $positionCenter - $rowNum;
$positionRight = $positionCenter + $rowNum;
// Wenn die aktuelle Stufe die erste ist (Index 0) müssn wir nur eine
// Ersetzung durchführen, da dort ja nur ein Pyramidenzeichen vorhanden ist
if ($rowNum == 0) {
return substr_replace($line, $char, $positionCenter, 1);
} else {
// Sind wir aber irgendwo mitten in der Pyramide, müssen wir sowohl links
// als auch rechts ersetzen
$tmp = substr_replace($line, $char, $positionLeft, 1);
return substr_replace($tmp, $char, $positionRight, 1);
}
}
function pyramid($amount, $filler, $char) {
// Da wir nur mit ungeraden Anzahlen umgehen können, prüfen wir zunächst darauf
// und steigen ansonsten sofort aus dem Skript aus
if ($amount % 2 == 0)
throw new \Exception("Only odd numbers of characters are supported!");
// Dies berechnet die Höhe der Pyramide. Diese ergibt sich aus der Überlegung,
// dass auf jeder Stufe (ausgenommen der ersten) genau zwei Zeichen vorhanden sind.
// Will man also die Gesamthöhe der Pyramide mit X Zeichen, braucht man mindestens
// einmal X / 2 Stufen. Die + 1 bringt dann die erste Stufe mit, da diese ja nur
// ein Zeichen braucht. Um Rundungsfehler (ungerade Zahlen) auszugleichen, ziehen
// wir dieses eine Zeichen vorher ab.
$height = 1 + (($amount - 1) / 2);
// Die Breite der Pyramide ergibt sich dann daraus, dass mit jeder neuen Stufe
// (Höhe) der Pyramide, zwei neue Zeichen hinzukommen. Die - 1 zieht wieder
// die erste Stufe ab, da diese ja bereits in der Höhe berechnet wurde
$width = $height * 2 - 1;
// Hier wird die gesamte Pyramide reingeschrieben und später zurückgegeben
$pyramid = '';
// Nun erstellen wir die eigentliche Pyramide, indem alle Stufen der Pyramide
// nacheinander "gebaut" werden und einzeln verarbeitet werden
for ($currentRow = 0; $currentRow < $height; $currentRow++) {
// Zunächst erstellen wir eine "leere" Zeile, die nur das Füllzeichen enthält
// und zwar genau so oft, wie die Breite der Pyramide angibt
$currentLine = str_repeat($filler, $width);
// Nun ersetzen wir, abhänging von der aktuellen Stufe, die Pyramidenzeichen
// in dieser leeren Stufe mit einer eigenen Funktion
$pyramid .= replaceCharsAtRow($currentLine, $currentRow, $char);
// Dann noch ein Zeilenumbruch, damit es auch eine Pyramide wird ;-)
$pyramid .= '<br/>';
}
// Und zurück damit
return $pyramid;
}
echo pyramid(5, '-', '#');
Kommentar