Codewars Lösung | Spinning Rings


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|5. 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:Spinning Rings
Level:7 kyu
Sprache:TypeScript

Beschreibung:

Imagine two rings with numbers on them. The inner ring spins clockwise (decreasing by 1 each spin) and the outer ring spins counter clockwise (increasing by 1 each spin). We start with both rings aligned on 0 at the top, and on each move we spin each ring one increment. How many moves will it take before both rings show the same number at the top again?

The inner ring has integers from 0 to innerMax and the outer ring has integers from 0 to outerMax, where innerMax and outerMax are integers >= 1.

e.g. if innerMax is 2 and outerMax is 3 then after
1 move: inner = 2, outer = 1
2 moves: inner = 1, outer = 2
3 moves: inner = 0, outer = 3
4 moves: inner = 2, outer = 0
5 moves: inner = 1, outer = 1
Therefore it takes 5 moves for the two rings to reach the same number
Therefore spinningRings(2, 3) = 5
e.g. if innerMax is 3 and outerMax is 2 then after
1 move: inner = 3, outer = 1
2 moves: inner = 2, outer = 2
Therefore it takes 2 moves for the two rings to reach the same number
spinningRings(3, 2) = 2

for a bigger challenge, check out the Performance Version of this kata by @Voile

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

Als Erstes kreieren wir uns 2 Variablen um den aktuellen Stand der Ringe zu tracken. Dieser ist beim Start für beide Ringe 0.

Schritt 2

Dann brauchen wir einen Loop.

Schritt 3

In jeder Runde wird der äußere Ring um 1 größer, der innere um 1 kleiner. So weit, so gut.

Schritt 4

Wenn aber der innere Ring kleiner als 0 wird, müssen wir ihn wieder auf das innerMax setzen.

Schritt 5

Wenn der äußere Ring das outerMax überschreitet, müssen wir ihn wieder auf 0 setzen.

Schritt 6

Wenn beide Ringe den selben Stand haben, geben wir die Anzahl der Runden zurück, die es gebraucht hat.

Code

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

Lösungsschritte
Meine erste Zeile:
export function spinningRings(innerMax: number, outerMax: number): number {

Wir stellen sicher, dass unsere Funktion am Ende eine Zahl (number) zurück gibt.

Dann initialisieren wir die Counter für die Stände der Ringe:
let outer = 0;
let inner = 0;
Jetzt der Loop:
for (let i = 1; ; i++) {

Ich entscheide mich hier für einen ordinären for-Loop, ohne Condition/Bedingung.

Dann den äußeren Ring um 1 erhöhen und den inneren um 1 verringern:
outer++;
inner--;
Wenn der äußere Ring das outerMax überschreitet, setzen wir ihn wieder auf 0:
if (outer > outerMax) outer = 0;
Wenn der innere Ring 0 unterschreitet, setzen wir ihn auf das innerMax:
if (inner < 0) inner = innerMax;
Zum Schluss noch prüfen, ob inner und outer den gleichen Stand haben:
if (inner === outer) return i;

Wenn ja, geben wir die Anzahl Runden aus.

Voilá! 💪

Fragen?

Komplettlösung
export function spinningRings(innerMax: number, outerMax: number): number {
  let outer = 0;
  let inner = 0;

  for (let i = 1; ; i++) {
    outer++;
    inner--;

    if (outer > outerMax) outer = 0;
    if (inner < 0) inner = innerMax;

    if (inner === outer) return i;
  }
}

Feedback

Schreib mir!