Du schreibst Funktionen mit Schleifen: Sie zählen, summieren, füllen Listen und suchen, bis sie fertig sind. Von der Summe bis eins über Fakultät und Fibonacci bis zu den Primzahlen.
Eine Schleife wiederholt, was in ihr steht. Diese Funktion zählt, wie viele
Zahlen von 1 bis n durch 7 teilbar sind:
def sevens(n) count = 0 (1..n).each do |i| count += 1 if i % 7 == 0 end count end puts sevens(50)
(1..n).each do |i| läuft mit i von 1 bis n; mit drei Punkten, 1...n,
hört es vor n auf. n.downto(0) zählt herunter, und while wiederholt,
solange eine Bedingung gilt. Eine Variable wie count, die vor der Schleife
anfängt und in ihr wächst, sammelt das Ergebnis.
def sevens(n): count = 0 for i in range(1, n + 1): if i % 7 == 0: count += 1 return count print(sevens(50))
for i in range(1, n + 1): läuft mit i von 1 bis n: Die zweite Zahl ist
die erste, die nicht mehr dabei ist. range(n, -1, -1) zählt herunter, und
while wiederholt, solange eine Bedingung gilt. Eine Variable wie count,
die vor der Schleife anfängt und in ihr wächst, sammelt das Ergebnis.
function sevens(n) { let count = 0; for (let i = 1; i <= n; i++) { if (i % 7 === 0) { count++; } } return count; } console.log(sevens(50));
for (let i = 1; i <= n; i++) fängt mit i bei 1 an, läuft, solange
i <= n gilt, und zählt nach jedem Durchlauf eins weiter. i-- zählt
herunter, und while wiederholt, solange eine Bedingung gilt. Eine Variable
wie count, die vor der Schleife anfängt und in ihr wächst, sammelt das
Ergebnis; let erlaubt, sie zu ändern, const nicht.
Schon das erste veröffentlichte Programm, 1843 für eine Rechenmaschine, die nie fertig wurde, hatte eine Schleife.
Ada Lovelace (1815–1852), englische Mathematikerin, Tochter des Dichters Lord Byron. 1843 übersetzte sie einen Aufsatz über die Analytical Engine, eine Rechenmaschine, die Charles Babbage entworfen hatte, und schrieb Anmerkungen dazu, etwa dreimal so lang wie der Aufsatz. In der letzten, Note G, steht Schritt für Schritt, wie die Maschine die Bernoulli-Zahlen ausrechnen soll: das erste veröffentlichte Programm. Für jede weitere Zahl wiederholen sich darin die Schritte 13 bis 23, eine Schleife. Lovelace nannte so etwas einen »cycle of operations«, eine Folge von Schritten, die mehr als einmal ausgeführt wird, und kannte auch schon die Schleife in der Schleife: »a cycle of cycles«.
Die Maschine wurde nie fertig gebaut, und das Programm lief nie. Lovelace sah aber schon, dass sie mehr kann als rechnen: Stünden die Zahlen für Töne, könnte sie Musik komponieren. Die Programmiersprache Ada ist nach ihr benannt.
Aquarell: Alfred Edward Chalon, um 1840, gemeinfrei, zugeschnitten (Wikimedia Commons)
Schreib eine Funktion sum_to(n), die alle Zahlen von 1 bis n zusammenzählt: sum_to(4) ergibt 10, denn 1 + 2 + 3 + 4 = 10. Mit einer Schleife.
(1..n).each do |i| … end läuft mit i von 1 bis n. In der Schleife addierst du i zu total.
Schreib eine Funktion sum_to(n), die alle Zahlen von 1 bis n zusammenzählt: sum_to(4) ergibt 10, denn 1 + 2 + 3 + 4 = 10. Mit einer Schleife.
for i in range(1, n + 1): läuft mit i von 1 bis n. In der Schleife addierst du i zu total.
Schreib eine Funktion sumTo(n), die alle Zahlen von 1 bis n zusammenzählt: sumTo(4) ergibt 10, denn 1 + 2 + 3 + 4 = 10. Mit einer Schleife.
for (let i = 1; i <= n; i++) { … } läuft mit i von 1 bis n. In der Schleife addierst du i zu total.
Schreib eine Funktion numbers(n), die eine Liste der Zahlen von 1 bis n zurückgibt: numbers(4) ergibt [1, 2, 3, 4]. Mit einer Schleife, die die Liste Zahl für Zahl füllt.
result << i hängt i hinten an die Liste an.
Schreib eine Funktion numbers(n), die eine Liste der Zahlen von 1 bis n zurückgibt: numbers(4) ergibt [1, 2, 3, 4]. Mit einer Schleife, die die Liste Zahl für Zahl füllt.
result.append(i) hängt i hinten an die Liste an.
Schreib eine Funktion numbers(n), die eine Liste der Zahlen von 1 bis n zurückgibt: numbers(4) ergibt [1, 2, 3, 4]. Mit einer Schleife, die die Liste Zahl für Zahl füllt.
result.push(i) hängt i hinten an die Liste an.
Schreib eine Funktion squares(n), die die Quadratzahlen von 1² bis n² als Liste zurückgibt: squares(4) ergibt [1, 4, 9, 16].
Schreib eine Funktion squares(n), die die Quadratzahlen von 1² bis n² als Liste zurückgibt: squares(4) ergibt [1, 4, 9, 16].
Schreib eine Funktion squares(n), die die Quadratzahlen von 1² bis n² als Liste zurückgibt: squares(4) ergibt [1, 4, 9, 16].
Schreib eine Funktion countdown(n), die von n bis 0 herunterzählt und die Zahlen als Liste zurückgibt: countdown(3) ergibt [3, 2, 1, 0].
n.downto(0) do |i| … end zählt herunter. Oder eine while-Schleife, die n jedes Mal um 1 kleiner macht.
Schreib eine Funktion countdown(n), die von n bis 0 herunterzählt und die Zahlen als Liste zurückgibt: countdown(3) ergibt [3, 2, 1, 0].
range(n, -1, -1) zählt von n herunter bis 0: Die zweite Zahl ist die erste, die nicht mehr dabei ist. Oder eine while-Schleife, die n jedes Mal um 1 kleiner macht.
Schreib eine Funktion countdown(n), die von n bis 0 herunterzählt und die Zahlen als Liste zurückgibt: countdown(3) ergibt [3, 2, 1, 0].
for (let i = n; i >= 0; i--) zählt herunter bis 0.
Die Fakultät n! ist das Produkt aller Zahlen von 1 bis n: 5! = 1 · 2 · 3 · 4 · 5 = 120. Und 0! ist 1. Schreib eine Funktion factorial(n): factorial(5) ergibt 120.
Rechne 4! von Hand und schreib jeden Zwischenwert auf: 1, 2, 6, 24.
Wie bei der Summe, nur mit * statt +. Womit muss das Produkt anfangen?
Die Fakultät n! ist das Produkt aller Zahlen von 1 bis n: 5! = 1 · 2 · 3 · 4 · 5 = 120. Und 0! ist 1. Schreib eine Funktion factorial(n): factorial(5) ergibt 120.
Rechne 4! von Hand und schreib jeden Zwischenwert auf: 1, 2, 6, 24.
Wie bei der Summe, nur mit * statt +. Womit muss das Produkt anfangen?
Die Fakultät n! ist das Produkt aller Zahlen von 1 bis n: 5! = 1 · 2 · 3 · 4 · 5 = 120. Und 0! ist 1. Schreib eine Funktion factorial(n): factorial(5) ergibt 120.
Rechne 4! von Hand und schreib jeden Zwischenwert auf: 1, 2, 6, 24.
Wie bei der Summe, nur mit * statt +. Womit muss das Produkt anfangen?
Die Quersumme einer Zahl ist die Summe ihrer Ziffern: Die Quersumme von 1234 ist 1 + 2 + 3 + 4 = 10. Schreib eine Funktion digit_sum(n), nur mit Rechnen, ohne die Zahl in einen Text zu verwandeln.
1234 % 10 ist 4, die letzte Ziffer. Und 1234 / 10?
Wiederhole: letzte Ziffer zur Summe, dann die Zahl durch 10 teilen. Bis wann?
Ein Gerüst:
def digit_sum(n) total = 0 while n > 0 # hier: letzte Ziffer dazu, dann n kleiner machen end total end
Die Quersumme einer Zahl ist die Summe ihrer Ziffern: Die Quersumme von 1234 ist 1 + 2 + 3 + 4 = 10. Schreib eine Funktion digit_sum(n), nur mit Rechnen, ohne die Zahl in einen Text zu verwandeln.
1234 % 10 ist 4, die letzte Ziffer. Und 1234 // 10?
Wiederhole: letzte Ziffer zur Summe, dann die Zahl durch 10 teilen. Bis wann?
Ein Gerüst:
def digit_sum(n): total = 0 while n > 0: ... # letzte Ziffer dazu, dann n kleiner machen return total
Die Quersumme einer Zahl ist die Summe ihrer Ziffern: Die Quersumme von 1234 ist 1 + 2 + 3 + 4 = 10. Schreib eine Funktion digitSum(n), nur mit Rechnen, ohne die Zahl in einen Text zu verwandeln.
1234 % 10 ist 4, die letzte Ziffer. Und Math.floor(1234 / 10)?
Wiederhole: letzte Ziffer zur Summe, dann die Zahl durch 10 teilen. Bis wann?
Ein Gerüst:
function digitSum(n) { let total = 0; while (n > 0) { // hier: letzte Ziffer dazu, dann n kleiner machen } return total; }
Die Fibonacci-Zahlen beginnen mit 0 und 1, und jede weitere ist die Summe der beiden davor: 0, 1, 1, 2, 3, 5, 8, 13 … Schreib eine Funktion fibonacci(n), die die n-te zurückgibt, gezählt ab 0: fibonacci(0) ergibt 0, fibonacci(7) ergibt 13.
Schreib die Folge bis fibonacci(7) auf und zeig mit dem Finger auf die beiden Zahlen, die du gerade addierst.
Zwei Variablen merken sich die letzten beiden Zahlen, a und b. Wie sehen sie nach einem Schritt aus?
Die Fibonacci-Zahlen beginnen mit 0 und 1, und jede weitere ist die Summe der beiden davor: 0, 1, 1, 2, 3, 5, 8, 13 … Schreib eine Funktion fibonacci(n), die die n-te zurückgibt, gezählt ab 0: fibonacci(0) ergibt 0, fibonacci(7) ergibt 13.
Schreib die Folge bis fibonacci(7) auf und zeig mit dem Finger auf die beiden Zahlen, die du gerade addierst.
Zwei Variablen merken sich die letzten beiden Zahlen, a und b. Wie sehen sie nach einem Schritt aus?
Die Fibonacci-Zahlen beginnen mit 0 und 1, und jede weitere ist die Summe der beiden davor: 0, 1, 1, 2, 3, 5, 8, 13 … Schreib eine Funktion fibonacci(n), die die n-te zurückgibt, gezählt ab 0: fibonacci(0) ergibt 0, fibonacci(7) ergibt 13.
Schreib die Folge bis fibonacci(7) auf und zeig mit dem Finger auf die beiden Zahlen, die du gerade addierst.
Zwei Variablen merken sich die letzten beiden Zahlen, a und b. Wie sehen sie nach einem Schritt aus?
Schreib eine Funktion count_divisors(n), die zählt, durch wie viele Zahlen n ohne Rest teilbar ist: 12 hat die Teiler 1, 2, 3, 4, 6 und 12, count_divisors(12) ergibt also 6.
Probier jede Zahl von 1 bis n aus: Lässt sie einen Rest?
Ein Zähler fängt bei 0 an und wird bei jedem Teiler um 1 größer.
Schreib eine Funktion count_divisors(n), die zählt, durch wie viele Zahlen n ohne Rest teilbar ist: 12 hat die Teiler 1, 2, 3, 4, 6 und 12, count_divisors(12) ergibt also 6.
Probier jede Zahl von 1 bis n aus: Lässt sie einen Rest?
Ein Zähler fängt bei 0 an und wird bei jedem Teiler um 1 größer.
Schreib eine Funktion countDivisors(n), die zählt, durch wie viele Zahlen n ohne Rest teilbar ist: 12 hat die Teiler 1, 2, 3, 4, 6 und 12, countDivisors(12) ergibt also 6.
Probier jede Zahl von 1 bis n aus: Lässt sie einen Rest?
Ein Zähler fängt bei 0 an und wird bei jedem Teiler um 1 größer.
Jetzt hört eine Schleife nicht nach einer festen Zahl von Durchläufen auf, sondern wenn etwas gefunden ist.
Eine Primzahl hat genau zwei Teiler, 1 und sich selbst: 2, 3, 5, 7, 11 … Schreib eine Funktion prime(n), die sagt, ob n eine Primzahl ist.
Teilt irgendeine Zahl zwischen 2 und n - 1 die Zahl n ohne Rest? Dann ist n keine Primzahl.
Sobald du einen Teiler gefunden hast, steht die Antwort fest: return false. Und was gilt für 0 und 1?
Es reicht, bis zur Wurzel von n zu suchen: Hat n einen Teiler, der größer ist, hat es auch einen kleineren.
Eine Primzahl hat genau zwei Teiler, 1 und sich selbst: 2, 3, 5, 7, 11 … Schreib eine Funktion prime(n), die sagt, ob n eine Primzahl ist.
Teilt irgendeine Zahl zwischen 2 und n - 1 die Zahl n ohne Rest? Dann ist n keine Primzahl.
Sobald du einen Teiler gefunden hast, steht die Antwort fest: return False. Und was gilt für 0 und 1?
Es reicht, bis zur Wurzel von n zu suchen: Hat n einen Teiler, der größer ist, hat es auch einen kleineren.
Eine Primzahl hat genau zwei Teiler, 1 und sich selbst: 2, 3, 5, 7, 11 … Schreib eine Funktion prime(n), die sagt, ob n eine Primzahl ist.
Teilt irgendeine Zahl zwischen 2 und n - 1 die Zahl n ohne Rest? Dann ist n keine Primzahl.
Sobald du einen Teiler gefunden hast, steht die Antwort fest: return false. Und was gilt für 0 und 1?
Es reicht, bis zur Wurzel von n zu suchen: Hat n einen Teiler, der größer ist, hat es auch einen kleineren.
Schreib eine Funktion gcd(a, b), die den größten gemeinsamen Teiler zweier Zahlen zurückgibt: die größte Zahl, die beide ohne Rest teilt. gcd(60, 48) ergibt 12.
Rechne gcd(60, 48) von Hand. Welche Zahlen teilen beide?
Euklid: Was a und b teilt, teilt auch den Rest a % b. Was passiert, wenn du a, b durch b, a % b ersetzt, bis b 0 ist?
Ein Gerüst:
def gcd(a, b) while b != 0 # hier: a und b neu belegen end a end
Schreib eine Funktion gcd(a, b), die den größten gemeinsamen Teiler zweier Zahlen zurückgibt: die größte Zahl, die beide ohne Rest teilt. gcd(60, 48) ergibt 12.
Rechne gcd(60, 48) von Hand. Welche Zahlen teilen beide?
Euklid: Was a und b teilt, teilt auch den Rest a % b. Was passiert, wenn du a, b durch b, a % b ersetzt, bis b 0 ist?
Ein Gerüst:
def gcd(a, b): while b != 0: ... # a und b neu belegen return a
Schreib eine Funktion gcd(a, b), die den größten gemeinsamen Teiler zweier Zahlen zurückgibt: die größte Zahl, die beide ohne Rest teilt. gcd(60, 48) ergibt 12.
Rechne gcd(60, 48) von Hand. Welche Zahlen teilen beide?
Euklid: Was a und b teilt, teilt auch den Rest a % b. Was passiert, wenn du a, b durch b, a % b ersetzt, bis b 0 ist?
Ein Gerüst:
function gcd(a, b) { while (b !== 0) { // hier: a und b neu belegen } return a; }
Nimm eine Zahl. Ist sie gerade, halbiere sie, sonst nimm sie mal 3 und addiere 1. Wiederhole das. Aus 6 wird 3, 10, 5, 16, 8, 4, 2, 1: acht Schritte bis zur 1. Bisher kam jede Zahl, die man probiert hat, irgendwann bei 1 an; ob das für alle gilt, weiß niemand. Schreib eine Funktion collatz_steps(n), die die Schritte bis zur 1 zählt.
Geh die Folge von 6 mit dem Finger durch und zähl mit: Wann hörst du auf zu zählen?
Eine while-Schleife läuft, solange n nicht 1 ist; jeder Durchlauf ist ein Schritt.
Nimm eine Zahl. Ist sie gerade, halbiere sie, sonst nimm sie mal 3 und addiere 1. Wiederhole das. Aus 6 wird 3, 10, 5, 16, 8, 4, 2, 1: acht Schritte bis zur 1. Bisher kam jede Zahl, die man probiert hat, irgendwann bei 1 an; ob das für alle gilt, weiß niemand. Schreib eine Funktion collatz_steps(n), die die Schritte bis zur 1 zählt.
Geh die Folge von 6 mit dem Finger durch und zähl mit: Wann hörst du auf zu zählen?
Eine while-Schleife läuft, solange n nicht 1 ist; jeder Durchlauf ist ein Schritt.
Nimm eine Zahl. Ist sie gerade, halbiere sie, sonst nimm sie mal 3 und addiere 1. Wiederhole das. Aus 6 wird 3, 10, 5, 16, 8, 4, 2, 1: acht Schritte bis zur 1. Bisher kam jede Zahl, die man probiert hat, irgendwann bei 1 an; ob das für alle gilt, weiß niemand. Schreib eine Funktion collatzSteps(n), die die Schritte bis zur 1 zählt.
Geh die Folge von 6 mit dem Finger durch und zähl mit: Wann hörst du auf zu zählen?
Eine while-Schleife läuft, solange n nicht 1 ist; jeder Durchlauf ist ein Schritt.
Ein Extra für Schnelle: Die Seite ist ohne dieses Kapitel vollständig.
Zwei Katas, die nicht mitzählen. Bei der zweiten zählt auch, wie schnell dein Code ist.
Eine Zahl ist vollkommen, wenn sie die Summe ihrer Teiler ist, ohne sich selbst: 6 = 1 + 2 + 3. Schreib eine Funktion perfect_numbers(limit), die alle vollkommenen Zahlen bis limit als Liste zurückgibt. Bis 10000 sind es vier.
Eine Funktion, die die Teiler einer Zahl zusammenzählt, und eine Schleife über alle Zahlen bis limit. Teiler gibt es höchstens bis zur Hälfte der Zahl.
Eine Zahl ist vollkommen, wenn sie die Summe ihrer Teiler ist, ohne sich selbst: 6 = 1 + 2 + 3. Schreib eine Funktion perfect_numbers(limit), die alle vollkommenen Zahlen bis limit als Liste zurückgibt. Bis 10000 sind es vier.
Eine Funktion, die die Teiler einer Zahl zusammenzählt, und eine Schleife über alle Zahlen bis limit. Teiler gibt es höchstens bis zur Hälfte der Zahl.
Eine Zahl ist vollkommen, wenn sie die Summe ihrer Teiler ist, ohne sich selbst: 6 = 1 + 2 + 3. Schreib eine Funktion perfectNumbers(limit), die alle vollkommenen Zahlen bis limit als Liste zurückgibt. Bis 10000 sind es vier.
Eine Funktion, die die Teiler einer Zahl zusammenzählt, und eine Schleife über alle Zahlen bis limit. Teiler gibt es höchstens bis zur Hälfte der Zahl.
Schreib eine Funktion primes_up_to(n), die alle Primzahlen bis n als Liste zurückgibt: primes_up_to(20) ergibt [2, 3, 5, 7, 11, 13, 17, 19]. Die Prüfung fragt auch nach allen bis eine Million, und dafür hat dein Code sechs Sekunden. Prüft er jede Zahl einzeln, reicht das nicht. Eratosthenes hat sich vor über 2000 Jahren etwas Schnelleres ausgedacht: Streich aus einer Liste aller Zahlen die Vielfachen jeder Primzahl.
Ein Array prime = Array.new(n + 1, true) sagt für jede Zahl, ob sie noch im Rennen ist. Für jede Zahl p, die noch drin ist, streichst du p * p, p * p + p, … bis n.
Schreib eine Funktion primes_up_to(n), die alle Primzahlen bis n als Liste zurückgibt: primes_up_to(20) ergibt [2, 3, 5, 7, 11, 13, 17, 19]. Die Prüfung fragt auch nach allen bis eine Million, und dafür hat dein Code sechs Sekunden. Prüft er jede Zahl einzeln, reicht das nicht. Eratosthenes hat sich vor über 2000 Jahren etwas Schnelleres ausgedacht: Streich aus einer Liste aller Zahlen die Vielfachen jeder Primzahl.
Eine Liste prime = [True] * (n + 1) sagt für jede Zahl, ob sie noch im Rennen ist. Für jede Zahl p, die noch drin ist, streichst du p * p, p * p + p, … bis n.
Schreib eine Funktion primesUpTo(n), die alle Primzahlen bis n als Liste zurückgibt: primesUpTo(20) ergibt [2, 3, 5, 7, 11, 13, 17, 19]. Die Prüfung fragt auch nach allen bis zehn Millionen, und dafür hat dein Code sechs Sekunden. Prüft er jede Zahl einzeln, reicht das nicht. Eratosthenes hat sich vor über 2000 Jahren etwas Schnelleres ausgedacht: Streich aus einer Liste aller Zahlen die Vielfachen jeder Primzahl.
Eine Liste const prime = new Array(n + 1).fill(true) sagt für jede Zahl, ob sie noch im Rennen ist. Für jede Zahl p, die noch drin ist, streichst du p * p, p * p + p, … bis n.