Codewars Lösung | Last Survivor


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|23. Januar 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:Last Survivor
Level:7 kyu
Sprache:TypeScript

Beschreibung:

You are given a string of letters and an array of numbers.
The numbers indicate positions of letters that must be removed, in order, starting from the beginning of the array.
After each removal the size of the string decreases (there is no empty space).
Return the only letter left.

Example:

```
let str = "zbk", arr = [0, 1]
    str = "bk", arr = [1]
    str = "b", arr = []
    return 'b'
```
```java
    str = "zbk", arr = {0, 1}
    str = "bk", arr = {1}
    str = "b", arr = {}
    return "b"
```

Notes

  • The given string will never be empty.
  • The length of the array is always one less than the length of the string.
  • All numbers are valid.
  • There can be duplicate letters and numbers.

If you like this kata, check out the next one: Last Survivors Ep.2

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

Solange das Input Array (coords) nicht leer ist...

Schritt 3

entferne den Buchstaben im Input String mit dem Index gleich des jeweils ersten Elements des Arrays.

Code

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

Lösungsschritte
Meine erste Zeile:
export function lastSurvivor(letters: string, coords: number[]): string {
Unsere Buchstaben können wir schon mal in ein Array umwandeln:
let lettersArr = letters.split("");
Das coords-Array können wir kopieren, damit das Ursprungs-Array intakt bleibt:
const remainingCoords = [...coords];

Für die Kopie verwende ich hier den Spread-Operator.

Jetzt der Loop:
  while (remainingCoords.length) {

Ich entscheide mich hier für eine while-Schleife. Hier wird solange geloopt, wie das Array eine Länge hat. Hat es keine Länge mehr (also 0), ist die Bedingung false und der Loop ist beendet.

Jetzt entfernen wir das erste Element im remainingCoords Array und speichern es in einer Variablen:
const nextIndexToBeRemoved = remainingCoords.shift();

Das speichern in der Variable ist hier nicht zwingend notwendig, erhöht aber die Lesbarkeit!

Dann können wir den Buchstaben mit dem gleichen Index wie die Zahl in nextIndexToBeRemoved entfernen:
    lettersArr = lettersArr.filter((_, i) => i !== nextIndexToBeRemoved);
  }

Das mache ich hier mit .filter. Das erste Argument der Callback-Function interessiert uns nicht. Darum nennen wir es _. Das zweite Argument ist der Index des jeweiligen aktuellen Elements. Wir wollen nur die Elemente behalten, die nicht diesen Index haben. .filter gibt uns ein neues Array zurück, das wir wieder in lettersArr speichern.

Nach dem Loop nur noch unsere übrigen Buchstaben als String zurückgeben:
  return lettersArr.join("");
}
Voilá! 💪

Fragen?

Komplettlösung
export function lastSurvivor(letters: string, coords: number[]): string {
  let lettersArr = letters.split("");
  const remainingCoords = [...coords];

  while (remainingCoords.length) {
    const nextIndexToBeRemoved = remainingCoords.shift();

    lettersArr = lettersArr.filter((_, i) => i !== nextIndexToBeRemoved);
  }

  return lettersArr.join("");
}

Feedback

Schreib mir!