Codewars Lösung | If you can read this...


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|12. August 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:If you can read this...
Level:6 kyu
Sprache:JavaScript

Beschreibung:

The idea for this kata came from 9gag today:

The lyrics to "Never gonna give you up" by Rick Astley encoded in the NATO phonetic alphabet

Task

You'll have to translate a string to Pilot's alphabet (NATO phonetic alphabet).

Input:

If, you can read?

Output:

India Foxtrot , Yankee Oscar Uniform Charlie Alfa November Romeo Echo Alfa Delta ?

Note:

  • There is a preloaded dictionary that you can use, named NATO. It uses uppercase keys, e.g. NATO['A'] is "Alfa". See comments in the initial code to see how to access it in your language.
  • The set of used punctuation is ,.!?.
  • Punctuation should be kept in your return string, but spaces should not.
  • Xray should not have a dash within.
  • Every word and punctuation mark should be seperated by a space ' '.
  • There should be no trailing whitespace
The NATO phonetic alphabet (A–Z) is preloaded:

```rust
use preloaded::NATO;

NATO[&'R']; // Romeo
NATO[&'U']; // Uniform
NATO[&'S']; // Sierra
NATO[&'T']; // Tango
```

<details>
<summary>Click to see the preloaded code</summary>

```rust
use std::collections::HashMap;
use once_cell::sync::Lazy;

#[rustfmt::skip]
pub static NATO: Lazy&gt; = Lazy::new(|| {
    [
        ('A', "Alfa"), ('B', "Bravo"), ('C', "Charlie"), ('D', "Delta"),
        ('E', "Echo"), ('F', "Foxtrot"), ('G', "Golf"), ('H', "Hotel"),
        ('I', "India"), ('J', "Juliett"), ('K', "Kilo"), ('L', "Lima"),
        ('M', "Mike"), ('N', "November"), ('O', "Oscar"), ('P', "Papa"),
        ('Q', "Quebec"), ('R', "Romeo"), ('S', "Sierra"), ('T', "Tango"),
        ('U', "Uniform"), ('V', "Victor"), ('W', "Whiskey"), ('X', "Xray"),
        ('Y', "Yankee"), ('Z', "Zulu"),
    ]
    .iter()
    .copied()
    .collect()       
});
```

</details>

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

Später soll zwischen jeden übersetzten Buchstaben ein Leerzeichen, darum können wir jetzt schon mal alle Spaces entfernen.

Schritt 2

Dann können wir alle Zeichen im Input-String in Großbuchstaben umwandeln.

Schritt 3

Jetzt können wir den Input-String in ein Array umwandeln.

Schritt 4

Dann brauchen wir einen Loop.

Schritt 5

Wir tauschen jeden Buchstaben durch das Wort im Nato-Alphabet; wenn es ein Satzzeichen ist, lassen wir es wie es ist.

Schritt 6

Zum Schluss nur noch wieder in einen String umwandeln und zurückgeben.

Code

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

Lösungsschritte
Meine erste Zeile (ich habe words in str umbenannt):
function toNato(str) {
Als Erstes also alle Leerzeichen entfernen:
return str.replace(/ /g, "");

Hier können wir wunderbar chainen. Darum platziere ich das return schon hier.

Was übrig bleibt wandeln wir in Großbuchstaben um:
    .toUpperCase()
Dann machen wir ein Array draus:
    .split("")
Jetzt das Herzstück - der Loop:
    .map((char) => (/[,.!?]/.test(char) ? char : NATO[char]))

Hier bietet sich ein .map() an, da wir genauso viele Zeichen zurückbekommen wollen, wie wir reingeben.

Mit der RegEx und dem Ternary testen wir, ob das aktuelle Zeichen ein Sonderzeichen ist. Wenn ja, geben wir es unverändert zurück. Ansonsten schlagen wir das entsprechende Wort im Nato-Alphabet mit dem Buchstaben als Key nach.

(Die Klammern haben VSCode und Prettier automatisch hinzugefügt.)

Zum Schluss nur noch das Array wieder zu einem String zusammenfügen:
    .join(" ");
}

Zurückgeben brauchen wir nichts mehr, das return hatten wir ja bereits direkt oben platziert.

Voilá! 💪

Fragen?

Komplettlösung
function toNato(str) {
  return str
    .replace(/ /g, "")
    .toUpperCase()
    .split("")
    .map((char) => (/[,.!?]/.test(char) ? char : NATO[char]))
    .join(" ");
}

Feedback

Schreib mir!