Inhalt
Die Fakten:
Plattform: | codewars.com |
Name: | Let's do a fun graph |
Level: | 6 kyu |
Sprache: | TypeScript |
Beschreibung:
You have done some data collection today and you want the data to be well presented by a graph so you have decided to make a quick diagram. Suppose that for this kata your data is presented by an array by their value eg [10,5,3,1,4]
, then you must present your data as follows:
for data = [10,5,3,1,4] :
____ ........................ ^ 10
| |........................ | 9
| |........................ | 8
| |........................ | 7
| |........................ | 6
| | ____ .................. | 5
| || |............ ____ | 4
| || | ____ ......| | | 3
| || || |......| | | 2
| || || | ____ | | | 1
| || || || || | | 0
GOOD TO KNOW :
-
Each bar is always of width
6
. -
The vertical axis must be surrounded with one space character on each side.
-
No trailing spaces on any line.
-
For this kata we use :
- the following characters :
'_', ' ', '|', '.', '^'
. - some numbers.
- the following characters :
-
Return type :
- Your code must return a
string
consisting of the lines joined by\n
. []
and[0]
has different returns""
and" ____ ^ 0"
- Your code must return a
CRITERIA :
- The length of the array is always less than
50
. - The numbers in
data
are always< 50
- The numbers in
data
are always positive
GOOD LUCK :)
Quelle: codewars.com
Lösung
Pseudo-Code
Wie immer gibt's reichlich Varianten, hier ist eine meiner.
Erst die Lösungsschritte in Pseudo-Code. Los geht’s:
Lösungsschritte
Schritt 1
Zuerst sollten wir herausfinden, welche Zahl im Input-Array die größte ist.
Schritt 2
Außerdem brauchen wir eine Variable für unser Ergebnis.
Schritt 3
Als Nächstes brauchen wir einen (vertikalen) Loop.
Schritt 4
Mit diesem loopen wir durch alle Zahlen bis zum Maximum, am besten rückwärts!
Schritt 5
Wir werden eine Variable brauchen, um die Zeichen jeder Ebene zu speichern.
Schritt 6
Dann brauchen wir einen zweiten (horizontalen) Loop.
Schritt 7
Mit dem zweiten Loop loopen wir durch die Zahlen im Input-Array.
Schritt 8
Für jede Zahl hängen wir die nötigen Zeichen an unsere Ebenen-Variable.
Schritt 9
Abhängig davon, ob die Zahl größer, kleiner oder gleich der aktuellen Ebenen-Zahl ist.
Schritt 10
Nach dem zweiten Loop noch die Achse: Wenn die aktuelle Ebene die oberste ist, hängen wir ein ^
an, sonst ein |
.
Schritt 11
Hinten noch die aktuelle Ebenen-Zahl anhängen.
Schritt 12
Dann können wir unsere fertige aktuelle Ebene an unser Ergebnis-Array anhängen.
Schritt 13
Nach dem zweiten Loop nur noch das Ergebnis als String mit "\n"
verbunden zurückgeben.
Code
Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:
Lösungsschritte
Meine erste Zeile (ich habe arr
in nums
umbenannt):
export function graph(nums: number[]): string {
Dann ermitteln wir das Maximum im Input-Array und initialisieren unser Ergebnis-Array:
const result: string[] = [];
const max = Math.max(...nums);
Dann der erste (vertikale) Loop:
for (let level = max; level >= 0; level--) {
Wir loopen hier rückwärts. Also vom Maximum bis zur 0
.
Jetzt können wir schon mal die Achse vorbereiten und unsere Variable für die aktuelle Zeile erstellen:
const axis = level === max ? " ^ " : " | ";
let row = "";
Dann der zweite (horizontale) Loop durch die Zahlen im Input-Array:
for (const num of nums) {
Jetzt die Bedingungen:
if (num === level) row += " ____ ";
if (num > level) row += "| |";
if (num < level) row += "......";
}
Ich finde if...elseif...else
und die ganzen geschweiften Klammern nicht besonders sexy. Darum erstelle ich hier für jeden Fall eine eigene if
-Bedingung.
Nach dem zweiten Loop noch die Achse an die aktuelle Zeile und die aktuelle Zeile ans Ergebnis anhängen:
row += axis + level;
result.push(row);
}
Zum Schluss das Ergebnis nach dem ersten Loop nur noch als String "\n"
-getrennt zurückgeben:
return result.join("\n");
}
Voilá! 💪
Komplettlösung
export function graph(nums: number[]): string {
const result: string[] = [];
const max = Math.max(...nums);
for (let level = max; level >= 0; level--) {
const axis = level === max ? " ^ " : " | ";
let row = "";
for (const num of nums) {
if (num === level) row += " ____ ";
if (num > level) row += "| |";
if (num < level) row += "......";
}
row += axis + level;
result.push(row);
}
return result.join("\n");
}