Codewars Lösung | Unflatten a list (Easy)


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|29. Dezember 2023
3 min.

Inhalt

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

Die Fakten:

Plattform:codewars.com
Name:Unflatten a list (Easy)
Level:7 kyu
Sprache:TypeScript

Beschreibung:

#Unflatten a list (Easy)

There are several katas like "Flatten a list". These katas are done by so many warriors, that the count of available list to flattin goes down!

So you have to build a method, that creates new arrays, that can be flattened!

#Shorter: You have to unflatten a list/an array.

You get an array of integers and have to unflatten it by these rules:

- You start at the first number.
- If this number x is smaller than 3, take this number x direct 
  for the new array and continue with the next number.
- If this number x is greater than 2, take the next x numbers (inclusive this number) as a 
  sub-array in the new array. Continue with the next number AFTER this taken numbers.
- If there are too few numbers to take by number, take the last available numbers.

The given array will always contain numbers. There will only be numbers > 0.

Example:

 [1,4,5,2,1,2,4,5,2,6,2,3,3] -> [1,[4,5,2,1],2,[4,5,2,6],2,[3,3]]

Steps: 
1. The 1 is added directly to the new array.
2. The next number is 4. So the next 4 numbers (4,5,2,1) are added as sub-array in the new array.
3. The 2 is added directly to the new array.
4. The next number is 4. So the next 4 numbers (4,5,2,6) are added as sub-array in the new array.
5. The 2 is added directly to the new array.
6. The next number is 3. So the next 3 numbers would be taken. There are only 2, 
   so take these (3,3) as sub-array in the new array.

There is a harder version of this kata!
Unflatten a list (Harder than easy)

Have fun coding it and please don't forget to vote and rank this kata! :-)

I have created other katas. Have a look if you like coding and challenges.

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 müssen durch das Input-Array loopen.

Schritt 2

Zuerst prüfen wir, ob das aktuelle Element kleiner 3 ist. Wenn ja, fügen wir es zu einem Output-Array hinzu.

Schritt 3

Dann schauen wir, ob es größer 2 ist. Wenn ja,

Schritt 4
  1. dann erstellen wir ein neues Sub-Array
  2. und fügen die nächsten x Elemente hinzu
Schritt 5

Das Sub-Array fügen wir dann zum Output Array hinzu.

Schritt 6

Weiter zum nächsten Element.

Schritt 7

Und zum Schluss das Output-Array ausgeben.

Code

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

Lösungsschritte
Meine erste Zeile:
export function unflatten(flatArray: number[]): number[] | number[][] {
Durch das Input-Array loopen:
for (let i = 0; i < flatArray.length; i++) {
Der Übersichtlichkeit halber speichere ich das aktuelle Element in einer Variablen (optional):
const curr = flatArray[i];
Ist das aktuelle Element kleiner als 3 (also 0, 1 oder 2), fügen wir es direkt zu einem Output-Array hinzu:
if (curr < 3) output.push(curr);
Ist dieses Element größer als 2, fügen wir die nächsten x Elemente zu einem Sub-Array hinzu. Das geht z.B. mit einem for...of-Loop:
    if (curr > 2) {
      const subArray: number[] = [];

      for (let j = 0; j < curr; j++) {
        const subCurr = flatArray[j + i];
        if (subCurr) subArray.push(subCurr);
      }

Das aktuelle Sub-Element speichere ich wieder der Übersichtlichkeit halber in einer Variablen (optional). Das aktuelle Sub-Element hat immer den Index i + j.

Dann noch das Sub-Array zum Output-Array hinzufügen:
output.push(subArray);
Jetzt müssen wir noch i korrigieren, da wir ja nun ein paar Schritte im Input-Array gesprungen sind:
      i += curr - 1;
    }
  }
Als letztes nur noch das Output-Array ausgeben:
return output;
Voilá! 💪

Fragen?

Komplettlösung
export function unflatten(flatArray: number[]): number[] | number[][] {
  const output: any[] = [];

  for (let i = 0; i < flatArray.length; i++) {
    const curr = flatArray[i];

    if (curr < 3) output.push(curr);

    if (curr > 2) {
      const subArray: number[] = [];

      for (let j = 0; j < curr; j++) {
        const subCurr = flatArray[j + i];
        if (subCurr) subArray.push(subCurr);
      }

      output.push(subArray);
      i += curr - 1;
    }
  }

  return output;
}

Feedback

Schreib mir!