Codewars Lösung | Vowels Back


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|7. Juni 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:Vowels Back
Level:6 kyu
Sprache:TypeScript

Beschreibung:

You need to play around with the provided string (s).

Move consonants forward 9 places through the alphabet. If they pass 'z', start again at 'a'.

Move vowels back 5 places through the alphabet. If they pass 'a', start again at 'z'. For our Polish friends this kata does not count 'y' as a vowel.

Exceptions:

If the character is 'c' or 'o', move it back 1 place. For 'd' move it back 3, and for 'e', move it back 4.

If a moved letter becomes 'c', 'o', 'd' or 'e', revert it back to it's original value.

Provided string will always be lower case, won't be empty and will have no special characters.

Quelle: codewars.com

Lösung

Pseudo-Code

Es gibt wie immer viele Varianten, hier ist eine meiner.

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

Lösungsschritte
Schritt 1

Als Erstes definieren wir unser Alphabet

Schritt 2

Dann loopen wir durch die einzelnen Buchstaben

Schritt 3

Jetzt können wir jeden Buchstaben checken und die Anzahl Schritte je nach Buchstaben in einer Variablen speichern

Schritt 4

Dann suchen wir den neuen Buchstaben aus dem Alphabet raus

Schritt 5

Wenn der Buchstabe im “code” enthalten ist, geben wir den ursprünglichen Buchstaben zurück

Schritt 6

Ansonsten den Neuen

Code

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

Lösungsschritte
Meine erste Zeile (ich habe s in str umbenannt):
export function vowelBack(str: string): string {
Erst das Alphabet definieren:
const alphabet = "abcdefghijklmnopqrstuvwxyz";
Dann der Loop:
  return [...str]
    .map((letter) => {

Dazu spreaden wir erst den String in ein Array und verwenden dann .map(), da wir genauso viele Elemente zurückhaben wollen, wie wir reingeben.

Da wir nicht viel mehr brauchen bzw. das Ding hier komplett mit Method-Chaining lösen wollen, können wir das return direkt hier hinballern. Bäääm! 🤘

Der Übersichtlichkeit halber speichere ich mir den Index des aktuellen Buchstaben im Alphabet in einer Variablen ab. Außerdem definiere ich mir eine weitere Variable in der die Anzahl zu machender Schritte gespeichert wird.
const currIndex = alphabet.indexOf(letter);
let steps: number;
Jetzt können wir uns an die Logik für die Anzahl der Schritte machen:
if (letter === "c" || letter === "o") steps = -1;
else if (letter === "d") steps = -3;
else if (letter === "e") steps = -4;
else if ("aeiou".includes(letter)) steps = -5;
else steps = 9;
Mit der Anzahl der Schritte können wir den neuen Index berechnen:
const newIndex = (currIndex + 26 + steps) % 26;

Mit dem Modulo-Operator % sorgen wir dafür, dass wir auch den richtigen Index bekommen wenn er über 0 oder 26 hinausgeht. Damit der Modulo auch funktioniert, wenn der Index negativ wird, addieren wir vorsichtshalber 26 zum aktuellen Index hinzu.

Mit dem neuen Index können wir jetzt den neuen Buchstaben bestimmen:
const newLetter = alphabet[newIndex];
Der letzte Test. Wenn der neue Buchstabe in “code” enthalten ist, geben wir den alten Buchstaben zurück. Ansonsten den Neuen:
      if ("code".includes(newLetter)) return letter;
      return newLetter;
    })
Jetzt nur noch das Array wieder zu einem String zusammenfügen:
    .join("");
}
Voilá! 💪

Fragen?

Komplettlösung
export function vowelBack(str: string): string {
  const alphabet = "abcdefghijklmnopqrstuvwxyz";

  return [...str]
    .map((letter) => {
      const currIndex = alphabet.indexOf(letter);
      let steps: number;

      if (letter === "c" || letter === "o") steps = -1;
      else if (letter === "d") steps = -3;
      else if (letter === "e") steps = -4;
      else if ("aeiou".includes(letter)) steps = -5;
      else steps = 9;

      const newIndex = (currIndex + 26 + steps) % 26;
      const newLetter = alphabet[newIndex];

      if ("code".includes(newLetter)) return letter;
      return newLetter;
    })
    .join("");
}

Feedback

Schreib mir!