Inhalt
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á! 💪
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;
}
}