Codewars Lösung | The Vowel Code


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|3. Mai 2024
3 min.

Inhalt

  1. Die Fakten
  2. Beschreibung
  3. Lösung
    1. Pseudo-Code
    2. Code
  4. Feedback

Die Fakten:

Plattform:codewars.com
Name:The Vowel Code
Level:6 kyu
Sprache:TypeScript

Beschreibung:

Step 1: Create a function called encode() to replace all the lowercase vowels in a given string with numbers according to the following pattern:

a -> 1
e -> 2
i -> 3
o -> 4
u -> 5

For example, encode("hello") would return "h2ll4". There is no need to worry about uppercase vowels in this kata.

Step 2: Now create a function called decode() to turn the numbers back into vowels according to the same pattern shown above.

For example, decode("h3 th2r2") would return "hi there".

For the sake of simplicity, you can assume that any numbers passed into the function will correspond to vowels.

Quelle: codewars.com

Lösung

Pseudo-Code

Erst die Lösungsschritte in Pseudo-Code. Los geht’s:

Lösungsschritte
Schritt 1

Als Erstes kümmern wir uns um die Encode-Funktion

Schritt 2

Hier brauchen wir einen Loop

Schritt 3

Es gibt viele Möglichkeiten, hier ist was mir eingefallen ist:

Schritt 4

Für jeden Buchstaben im Input-String testen wir, ob er im String “aeiou” vorhanden ist

Schritt 5

wenn ja, geben wir dessen Index im Vokal-String + 1 zurück, sonst den Buchstaben

Schritt 6

Für die Decode-Funktion müssen wir den Loop leicht anpassen:

Schritt 7

Wenn das aktuelle Zeichen eine Zahl ist und ein Zeichen mit dieser Zahl minus 1 als Index im Vokal-String enthalten ist, geben wir genau dieses Zeichen/Vokal zurück

Schritt 8

Ansonsten geben wir das aktuelle Zeichen unverändert zurück

Klingt komplizierter als es ist...

Code

Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:

Lösungsschritte
Meine erste Zeile der Encode-Funktion (ich habe string in str umbenannt):
export function encode(str: string): string {
Den Rest kriege ich in eine Zeile:
  return [...str].map((char) => "aeiou".indexOf(char) + 1 || char).join("");
}

Da wir genauso viele Zeichen zurückgeben wie reinkommen, schreit’s nach einem .map()-Loop. Der Rest ist wie oben beschrieben, mit folgendem Trick: Wenn char nicht in ”aeiou” gefunden wird, gibt .indexOf() -1 zurück. Jetzt machen wir uns zunutze, dass wir sowieso den Index + 1 brauchen. Denn wenn wir -1 zurück bekommen und + 1 rechnen, bekommen wir 0. 0 ist falsy. Damit wird der Code nach dem logischen Oder || ausgeführt und wir geben den unveränderten char zurück. Sweet!

Weiter geht’s mit der Decode-Funktion:

Meine erste Zeile der Decode-Funktion (ich hab wieder string in str umbenannt):

export function decode(str: string): string {
Auch hier passt der Rest wieder in eine Zeile:
  return [...str].map((char) => "aeiou"[Number(char) - 1] || char).join("");
}

Das Prinzip ist ähnlich. Nur hier prüfen wir, ob char eine Zahl ist. Wenn nicht, bekommen wir Murks (NaN) zurück. Murks (NaN) ist falsy und damit wird in diesem Fall auch hier wieder einfach der Ausgangs-char zurückgegeben. Ist char eine Zahl, aber größer als die Länge von “aeiou” kriegen wir undefined zurück. Ebenfalls falsy und wir springen wieder auf die rechte Seite des logischen Oders. Wenn char eine Zahl kleiner oder gleich der Länge des Vokal-Strings ist, z.B. 3, wird aus dem Ausdruck in der eckigen Klammer ein Zahl. Hier z.B. 2 (3 - 1). Also haben wir dann “aeiou”[2]. Es wird also das Zeichen mit dem Index 2, hier der Vokal i, zurückgegeben.

Bääm! 💪

Fragen?

Komplettlösung
export function encode(str: string): string {
  return [...str].map((char) => "aeiou".indexOf(char) + 1 || char).join("");
}

export function decode(str: string): string {
  return [...str].map((char) => "aeiou"[Number(char) - 1] || char).join("");
}

Feedback

Schreib mir!