Inhalt
Die Fakten:
Plattform: | codewars.com |
Name: | Cryptanalysis Word Patterns |
Level: | 7 kyu |
Sprache: | TypeScript |
Beschreibung:
In cryptanalysis, words patterns can be a useful tool in cracking simple ciphers.
A word pattern is a description of the patterns of letters occurring in a word, where each letter is given an integer code in order of appearance. So the first letter is given the code 0, and second is then assigned 1 if it is different to the first letter or 0 otherwise, and so on.
As an example, the word "hello" would become "0.1.2.2.3". For this task case-sensitivity is ignored, so "hello", "helLo" and "heLlo" will all return the same word pattern.
Your task is to return the word pattern for a given word. All words provided will be non-empty strings of alphabetic characters only, i.e. matching the regex "[a-zA-Z]+".
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
Wir brauchen einen Loop!
Schritt 2
Zuerst wandeln wir jeden Buchstaben in einen Kleinbuchstaben um.
Schritt 3
Bereits gefundene Buchstaben können wir in einem String oder Array speichern.
Schritt 4
Wenn der aktuelle Buchstabe noch nicht im Gefunden-Array enthalten ist, ergänzen wir ihn.
Schritt 5
Dann speichern wir seinen Index im Gefunden-Array in einem neuen Array.
Schritt 6
Zum Schluss geben wir das neue Array mit den Indices als punkt-getrennten String zurück.
Code
Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:
Lösungsschritte
Meine erste Zeile:
export function wordPattern(word: string): string {
Dann unser Gefunden-Array initialisieren:
const foundChars: string[] = [];
Jetzt der Loop:
word
.split("")
.map((char) => {
Erst wandeln wir den String mit .split("")
in ein Array um. Dann können wir durch das Array loopen.
Weil wir genauso viele Elemente ändern/zurückgeben wollen wie drin sind, bietet sich hier .map()
an.
Dann den aktuellen Buchstaben in einen Kleinbuchstaben umwandeln:
char = char.toLowerCase();
Jetzt prüfen wir, ob der aktuelle Buchstabe bereits im Gefunden-Array enthalten ist. Wenn nicht, ergänzen wir ihn:
if (!foundChars.includes(char)) foundChars.push(char);
Alternative:
Wir könnten hier den jeweiligen Buchstaben auch in einem String speichern. Das sähe dann so aus:
if (!foundChars.includes(char)) foundChars += char;
Dazu müssten wir oben statt des Arrays einen leeren String initialisieren.
Dann geben wir dem Array den Index im Gefunden-Array zurück:
return foundChars.indexOf(char);
})
Dann nur noch die Elemente des Arrays mit einem Punkt zu einem String verbinden:
.join(".");
}
Zum Schluss noch das return
-Keyword. Unser kompletter method-gechainter Loop sieht dann so aus:
return word
.split("")
.map((char) => {
char = char.toLowerCase();
if (!foundChars.includes(char)) foundChars.push(char);
return foundChars.indexOf(char);
})
.join(".");
Voilá! 💪
Komplettlösung
export function wordPattern(word: string): string {
const foundChars: string[] = [];
return word
.split("")
.map((char) => {
char = char.toLowerCase();
if (!foundChars.includes(char)) foundChars.push(char);
return foundChars.indexOf(char);
})
.join(".");
}