Codewars Lösung | Snail


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|21. Juni 2024
4 min.

Inhalt

  1. Die Fakten
  2. Beschreibung
  3. Lösung
    1. Pseudo-Code
    2. Code
  4. Feedback

Die Fakten:

Plattform:codewars.com
Name:Snail
Level:4 kyu
Sprache:JavaScript

Beschreibung:

Snail Sort

Given an n x n array, return the array elements arranged from outermost elements to the middle element, traveling clockwise.

array = [[1,2,3],
         [4,5,6],
         [7,8,9]]
snail(array) #=> [1,2,3,6,9,8,7,4,5]

For better understanding, please follow the numbers of the next array consecutively:

array = [[1,2,3],
         [8,9,4],
         [7,6,5]]
snail(array) #=> [1,2,3,4,5,6,7,8,9]

This image will illustrate things more clearly:

NOTE: The idea is not sort the elements from the lowest value to the highest; the idea is to traverse the 2-d array in a clockwise snailshell pattern.

NOTE 2: The 0x0 (empty matrix) is represented as en empty array inside an array [[]].

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 ein leeres Ergebnis-Array.

Schritt 2

Dann loopen wir solange durch die Input-Arrays, bis sie leer sind.

Schritt 3

Wir entfernen das jeweils das aktuell erste Element (die erste Zeile), (speichern es in einer Variablen) und fügen es zu unserem Ergebnis-Array hinzu.

Schritt 4

Danach entfernen wir die aktuell letzte Reihe und speichern sie in einer Variablen.

Schritt 5

Dann loopen wir durch die verbleibenden mittleren Zeilen.

Schritt 6

Wir entfernen von jeder mittleren Zeile das jeweils letzte Element und hängen es ans Ergebnis-Array.

Schritt 7

Jetzt können wir die letzte vom vorletzten Schritt umgedreht ans Ergebnis-Array anhängen.

Schritt 8

Dann wieder durch die mittleren Zeilen loopen.

Schritt 9

Diesmal das jeweils erste Element entfernen und ans Ergebnis-Array anhängen.

Schritt 10

Zum Schluss nur noch die Arrays im Ergebnis-Array auflösen und zurückgeben.

Code

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

Lösungsschritte
Meine erste Zeile:
function snail(arrays) {
Zuerst das Ergebnis-Array initialisieren:
const result = [];
Dann der äußere Loop durch die Arrays, solange bis sie leer sind:
  while (arrays.length) {
Jetzt schnappen wir uns die jeweils erste Zeile und hängen sie ans Ergebnis-Array:
const currFirstRow = arrays.shift();
result.push(currFirstRow);
Danach schnappen wir uns die letzte Zeile und speichern sie zwischen:
    const currLastRow = arrays.pop();
    if (!currLastRow) break;

Sollte es keine letzte Zeile geben, ist die Schnecke einzeilig und wir können den Loop direkt verlassen.

Ansonsten loopen wir dann durch die mittleren Zeilen:
    for (let i = 0; i < arrays.length; i++) {
Wir schnappen uns das jeweils letzte Element jeder Zeile und hängen es ans Ergebnis-Array:
      const currMiddleRow = arrays[i];
      const currLast = currMiddleRow.pop();
      result.push(currLast);
    }
Dann hängen wir unsere zuvor zwischengespeicherte letzte Zeile umgedreht ans Ergebnis an:
result.push(currLastRow.reverse());
Dann loopen wir noch mal durch die mittleren Zeilen:
    for (let i = 0; i < arrays.length; i++) {
Diesmal von unten nach oben. Und wir schnappen uns jetzt das jeweils erste Element:
      const currMiddleRow = arrays[arrays.length - 1 - i];
      const currFirst = currMiddleRow.shift();
      result.push(currFirst);
    }
  }
Wenn alle Loops durch sind, können wir unser Ergebnis zurückgeben:
  return result.flat();
}

Da ich hier einfach wild einen Mix aus Arrays und ordinären Zahlen ans Ergebnis angehangen habe, muss das noch ein Mal “geflatted” werden um ein sauberes eindimensionales Array zu erhalten.

Voilá! 💪

Fragen?

Komplettlösung
function snail(arrays) {
  const result = [];

  while (arrays.length) {
    const currFirstRow = arrays.shift();
    result.push(currFirstRow);

    const currLastRow = arrays.pop();
    if (!currLastRow) break;

    // add middle rows last elements
    for (let i = 0; i < arrays.length; i++) {
      const currMiddleRow = arrays[i];
      const currLast = currMiddleRow.pop();
      result.push(currLast);
    }

    result.push(currLastRow.reverse());

    // add middle rows first elements
    for (let i = 0; i < arrays.length; i++) {
      const currMiddleRow = arrays[arrays.length - 1 - i];
      const currFirst = currMiddleRow.shift();
      result.push(currFirst);
    }
  }

  return result.flat();
}

Feedback

Schreib mir!