Codewars Lösung | New Cashier Does Not Know About Space or Shift


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|14. Juli 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:New Cashier Does Not Know About Space or Shift
Level:6 kyu
Sprache:JavaScript

Beschreibung:

Some new cashiers started to work at your restaurant.

They are good at taking orders, but they don't know how to capitalize words, or use a space bar!

All the orders they create look something like this:

"milkshakepizzachickenfriescokeburgerpizzasandwichmilkshakepizza"

The kitchen staff are threatening to quit, because of how difficult it is to read the orders.

Their preference is to get the orders as a nice clean string with spaces and capitals like so:

"Burger Fries Chicken Pizza Pizza Pizza Sandwich Milkshake Milkshake Coke"

The kitchen staff expect the items to be in the same order as they appear in the menu.

The menu items are fairly simple, there is no overlap in the names of the items:

1. Burger
2. Fries
3. Chicken
4. Pizza
5. Sandwich
6. Onionrings
7. Milkshake
8. Coke

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 erstellen wir uns unsere Speisekarte

Schritt 2

Dann brauchen wir noch ein Ergebnis-Array (und eine Variable für das, was von der Bestellung jeweils übrig bleibt)

Schritt 3

Dann loopen wir durch die Speisekarte

Schritt 4

Wir entfernen alle Vorkommnisse des jeweils aktuellen Elements der Speisekarte im Bestell-String

Schritt 5

Dann vergleichen wir die Länge des Bestell-Strings vor dem Entfernen und danach (so kriegen wir raus, wie oft das Element im Bestell-String vorkam)

Schritt 6

Jetzt können wir die aktuellen Entfernungen in der richtigen Anzahl an unser Ergebnis-Array anhängen

Schritt 7

Zum Schluss nur noch das Ergebnis als String zurückgeben

Code

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

Lösungsschritte
Meine erste Zeile (ich habe input in order umbenannt):
function getOrder(order) {
Meine Speisekarte:
const menu =
  "Burger,Fries,Chicken,Pizza,Sandwich,Onionrings,Milkshake,Coke".split(",");

Ich war zu faul für jedes Element Gänsefüßchen zu tippen. Du kannst die Speisekarte hier natürlich auch manuell als Array erstellen.

const menu = [“Burger”, “Fries”, ... ]
Jetzt Ergebnis-Array- und temporäre Restliche-Bestellung-Variablen initialisieren:
let remainingOrder = order;
let readableOrder = [];
Und schon geht’s los mit dem Loop durch die Speisekarte:
  menu.forEach((item) => {
Dann speichern wir uns die aktuelle Länge der übrigen Bestellung in einer Variablen ab:
const curr = item.toLowerCase();
const orderLenBefore = remainingOrder.length;

Der Übersichtlichkeit halber speichere ich mir auch das aktuelle Element in einer Variablen ab.

Jetzt können wir alle Vorkommnisse des jeweils aktuellen Elements der Speisekarte im Bestell-String entfernen:
remainingOrder = remainingOrder.replaceAll(curr, "");
Danach können wir die Länge des Bestell-Strings vor dem Entfernen und danach vergleichen:
const orderLenAfter = remainingOrder.length;
const numItems = (orderLenBefore - orderLenAfter) / curr.length;

Indem wir durch die Länge des aktuellen Elements teilen, kriegen wir raus, wie oft das Element im Bestell-String vorkam.

Diese Elemente können wir dann an das Ergebnis-Array anhängen:
    readableOrder.push(...Array(numItems).fill(item));
  });

Mit Array() erstelle ich neues Array mit der Länge numItems. Dann setze ich an jede Stelle, das aktuelle Element der Speisekarte ein. Das Ganze wird dann mit ... gespreadet, damit wir die Elemente einzeln an das Ergebnis-Array anhängen können.

Zum Schluss nur noch das Ergebnis als String zurückgeben:
  return readableOrder.join(" ");
}
Voilá! 💪

Fragen?

Komplettlösung
function getOrder(order) {
  const menu =
    "Burger,Fries,Chicken,Pizza,Sandwich,Onionrings,Milkshake,Coke".split(",");

  let remainingOrder = order;
  let readableOrder = [];

  menu.forEach((item) => {
    const curr = item.toLowerCase();
    const orderLenBefore = remainingOrder.length;

    remainingOrder = remainingOrder.replaceAll(curr, "");

    const orderLenAfter = remainingOrder.length;
    const numItems = (orderLenBefore - orderLenAfter) / curr.length;

    readableOrder.push(...Array(numItems).fill(item));
  });

  return readableOrder.join(" ");
}

Feedback

Schreib mir!