CUBE.CODES: Beispiele aus der Zahlentheorie (Klasse 5): Unterschied zwischen den Versionen

Aus MINT.lentner.net
Zur Navigation springen Zur Suche springen
 
(94 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 3: Zeile 3:
 
[[Datei: ErsteSchritte.png |thumb|250px|CUBE.CODES - Erste Schritte]]
 
[[Datei: ErsteSchritte.png |thumb|250px|CUBE.CODES - Erste Schritte]]
  
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/bca8b605-7711-49aa-ad2a-a2af71379d20 Erste Schleife: Teilercheckliste ausgeben]<br>Ein einfaches, aber mächtiges Sprachelement jeder Programmiersprache ist die '''Wiederholungsschleife'''. Damit lassen wir die Möglichkeiten von Taschenrechner und Tabellenkalkulation weit hinter uns. Schon kleine Aufgaben aus der 5. Klasse werden schnell zu unlösbaren Problemen, wenn die Zahlen etwas größer werden. Die Berechnung der Teilermenge von 12 lässt sich zum Beispiel ganz problemlos durchführen: Wir teilen einfach die 12 durch alle möglichen Teiler (von 1 bis 12) und schauen eben, ob die Quotienten Ganzzahlen oder Kommazahlen sind. Eigentlich easy. Interessiert uns aber die Teilermenge von 5000 oder interessiert uns eine Übersicht über alle Teilermengen von 1 bis 5000, dann wird die Aufgabe auf einmal zur Wochenarbeit. In JavaScript können wir die Aufgaben einfach mit Variablen formulieren und beliebig oft wiederholen: <br>
+
Ein einfaches, aber mächtiges Sprachelement jeder Programmiersprache ist die '''Wiederholungsschleife'''. Damit lassen wir die Möglichkeiten von Taschenrechner und Tabellenkalkulation weit hinter uns. Schon kleine Aufgaben aus der 5. Klasse werden schnell zu unlösbaren Problemen, wenn die Zahlen etwas größer werden. Die Berechnung der Teilermenge von 12 lässt sich zum Beispiel per Hand noch ganz problemlos durchführen: '''Wir teilen einfach die 12 durch alle möglichen Teiler (von 1 bis 12) und schauen eben, ob die Quotienten Ganzzahlen oder Kommazahlen sind''' oder '''wir wenden 12 Teilbarkeitsregeln an'''. Eigentlich easy!
 +
 
 +
Interessiert uns aber die Teilermenge von 5.000, dann sind es schon '''5.000 Rechnungen'''. Interessiert uns eine Übersichtsliste über alle Teilermengen von 1 bis 5000, dann sind es im Schnitt schon '''2.500*5.000, also ca. 12 Mio Rechnungen''' und die Klärung der Frage wird auf einmal zur Wochenarbeit.  
 +
 
 +
In JavaScript können wir Aufgaben einfach mit Variablen formulieren und beliebig oft wiederholen lassen:
 +
 
 +
===Programm 1: Erste Schleife: Teilercheckliste ausgeben===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/bca8b605-7711-49aa-ad2a-a2af71379d20 Direkt zu CUBE.CODES]
 
  Zahl=12;
 
  Zahl=12;
 
  Teiler=1;<br>
 
  Teiler=1;<br>
Zeile 10: Zeile 17:
 
  Teiler=Teiler+1;
 
  Teiler=Teiler+1;
 
  }
 
  }
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/c51ff0e7-497a-402d-9349-c527736ded0e Verbesserung: Unwichtige Ergebnisse bei der Ausgabe unterdrücken]
+
 
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/790501be-4dbe-490e-8228-a6149c2cf956 Beobachtung: Die Quotienten sind auch Teiler (von unten nach oben gelesen)]
+
In weniger als einer Sekunde erhalten wir das Ergebnis:
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/9fb74839-3c24-4467-8aa1-57f7370f9738 Verbesserung: Doppelte Ausgabe weglassen, Quotienten als Gegenteiler bezeichnen]
+
 
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/92646f96-9155-4909-aee3-2cdbf9220e5c Verbesserung: Anzahl der Teiler ausgebeben] (Was ist mit Quadratzahlen?)
+
[23:24:04] Program starting ...
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/e9dd6cbe-30af-4762-95f9-683ca887862a Ganze Liste mit Zahlen und ihrer jeweiligen Teileranzahl]
+
[23:24:05] Program running ...
 +
Zahl: 12, Teiler: 1, Quotient: 12
 +
Zahl: 12, Teiler: 2, Quotient: 6
 +
Zahl: 12, Teiler: 3, Quotient: 4
 +
Zahl: 12, Teiler: 4, Quotient: 3
 +
Zahl: 12, Teiler: 5, Quotient: 2.4
 +
Zahl: 12, Teiler: 6, Quotient: 2
 +
Zahl: 12, Teiler: 7, Quotient: 1.7142857142857142
 +
Zahl: 12, Teiler: 8, Quotient: 1.5
 +
Zahl: 12, Teiler: 9, Quotient: 1.3333333333333333
 +
Zahl: 12, Teiler: 10, Quotient: 1.2
 +
Zahl: 12, Teiler: 11, Quotient: 1.0909090909090908
 +
Zahl: 12, Teiler: 12, Quotient: 1
 +
[23:24:05] Program finished successfully
 +
 
 +
Wir müssen die Teiler mit ganzzahligen Quotienten nur ablesen und haben unsere Teilermenge. Da der PC bei der sturen Wiederholung von Rechenschritten recht schmerzfrei ist, stört es kein bisschen, die Zuordnung '''Zahl=12;''' durch '''Zahl=5000;''' zu ersetzen und in weniger als einer Sekunde haben wir die Teiler von 5000 - zugegebenermaßen etwas mühsam ablesbar!
 +
 
 +
===Programm 2: Verbesserung: Unwichtige Ergebnisse bei der Ausgabe unterdrücken===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/c51ff0e7-497a-402d-9349-c527736ded0e Direkt zu CUBE.CODES]<br>
 +
 
 +
Eine klitzekleine Formulierung mit '''if''', eine sogenannte '''bedingte Anweisung''' ermöglicht es, die unwichtigen Ergebnisse (mit Kommazahlen als Quotienten) einfach wegzulassen und schon haben wir nur die Teiler auf dem Schirm.
 +
 
 +
'''Tipp:''' Versuch's mal mit 120191930!
 +
 
 +
'''Tipp:''' Das Prozentzeichen ist einfach der Rest bei ganzzahliger Teilung. Denkt an die Grundschule. Da hattet Ihr noch keine Kommazahlen. Auf die Frage: ''"Was ist 12 geteilt durch 5?", habt Ihr "2 Rest 2" geantwortet. Diese Antwort '''Rest = 2''' ist das Ergebnis der Rechnung '''12%5'''. Damit können wir leicht nachsehen, ob die Teilung '''12/5''' aufgeht. Nachdem das '''= Zeichen''' reserviert ist für '''Zuweisungen''' (x = 12; bedeutet ja: speichere 12 in der Speicherzelle (Variablen) x ab!), müssen wir für das '''=''' im Sinne eines Vergleichs eine andere Bezeichnung einführen, sonst gibt's Kuddelmuddel! In JavaScript ist das vergleichende '''=''' einfach das Doppelistgleich '''=='''.
 +
 
 +
Zahl=12;
 +
Teiler=1;<br>
 +
while(Teiler<=Zahl) {
 +
'''if(Zahl%Teiler==0)''' UI.log("Zahl: " + Zahl + ", Teiler: " + Teiler + ", Quotient: " + (Zahl/Teiler));
 +
Teiler=Teiler+1;
 +
}
 +
 
 +
Das Ergebnis ist jetzt deutlich schöner lesbar:
 +
 
 +
[23:24:04] Program starting ...
 +
[23:24:05] Program running ...
 +
Zahl: 12, Teiler: 1, Quotient: 12
 +
Zahl: 12, Teiler: 2, Quotient: 6
 +
Zahl: 12, Teiler: 3, Quotient: 4
 +
Zahl: 12, Teiler: 4, Quotient: 3
 +
Zahl: 12, Teiler: 6, Quotient: 2
 +
Zahl: 12, Teiler: 12, Quotient: 1
 +
[23:24:05] Program finished successfully
 +
 
 +
'''Tipp:''' Und schon macht es Spaß, mathematisch zu experimentieren und uns kreativeren Fragen zuzuwenden als ständig zu rechnen. Wir haben jetzt ja einen Rechenknecht, dier die ...arbeit für uns erledigt: '''Große Zahlen haben nicht zwangsläufig lange Teilerlisten'''. Probiert mal kleine Zahlen zu finden, die trotzdem lange Teilerlisten haben oder umgekehrt große (möglichst krumme) Zahlen, die aber kurze Teilerlisten haben! ('''12''' hat '''6 Teiler''', '''113''' aber nur zwei Teiler!) Welche Teilerlisten sind denn die kürzesten, die es gibt?
 +
 
 +
'''Ein kleiner Wettbewerb:''' Wer findet eine größere Zahl als '''113''', die trotzdem nur zwei Teiler hat?<br>
 +
Bisheriger Spitzenreiter Maria: '''2341''', Elisa: '''3001'''
 +
 
 +
===Mehr Aufgaben und Verbesserungen===
 +
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/cc278c6b-07a7-4866-ba46-67721f8a1e09 Beobachtung: ('''Doppelt gemoppelt''') Die Quotienten sind auch Teiler (von unten nach oben gelesen)] - '''Arbeiten mit flags!'''
 +
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/9fb74839-3c24-4467-8aa1-57f7370f9738 Verbesserung: Doppelte Ausgabe weglassen, Quotienten als Gegenteiler bezeichnen] - '''Ein Gedanken zur Komplexität:''' Wie stark können wir denn den Rechner entlasten durch die Beobachtung?
 +
* Versucht mal, den Rechner durch große Eingaben, an seine Grenze zu bringen. Es gibt Grenzen der Rechenzeit, aber auch Grenzen des benutzbaren Zahlenraums!
 +
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/92646f96-9155-4909-aee3-2cdbf9220e5c Verbesserung: Anzahl der Teiler ausgebeben] (Was ist mit Quadratzahlen?) - Lange Codeschnipsel, die immer wieder gebraucht werden, sollten mit eigenen Befehlen etikettiert werden, die Lösung ...
 +
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/e9dd6cbe-30af-4762-95f9-683ca887862a Ganze Liste mit Zahlen und ihrer jeweiligen Teileranzahl] - Eine eigene '''Funktion'''
 +
 
 +
===Programm 3: Die Vielfachenmenge - Die Zählschleife - Ein beliebiges Einmaleins ausgeben===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/43394728-8838-4216-9f90-0395c9f74463 Direkt zu CUBE.CODES]<br>
 +
 
 +
1 * 12 = 12
 +
2 * 12 = 24
 +
3 * 12 = 36
 +
4 * 12 = 48
 +
5 * 12 = 60
 +
6 * 12 = 72
 +
7 * 12 = 84
 +
8 * 12 = 96
 +
9 * 12 = 108
 +
10 * 12 = 120
 +
 
 +
Ein Einmalseins ist eigentlich leichter ausgegeben als eine Teilermenge, '''aber''' schon wieder müssen wir eine Wiederholung formulieren und '''mitzählen'''. Da das so oft vorkommt, gibt es eine '''Zählschleife''', die das alles in einem Schwung formuliert und schon wird die Schleife nur noch ein Einzeiler:
 +
 
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/cfe07c91-c038-41d9-a584-a6e63d1bc74e Direkt zu CUBE.CODES]<br>
 +
 
 +
Zahl=12;
 +
for(x=1; x<=10; ++x) UI.log(x + " * " + Zahl + " = " + (x*Zahl));
 +
 
 +
In dem Muster ...
 +
 
 +
for('''Anfangswert'''; '''Wiederholungsbedingung'''; '''Veränderung am Ende (Inkrement)''') '''Anweisungsblock''';
 +
 
 +
ist ...
 +
 
 +
# Der '''Anfangswert''' eine Zuweisung, die irgendeine frei wählbare Zählervariable auf einen Anfangswert setzt, ...
 +
# die '''Wiederholungsbedingung''' irgendeine Bedingung, die (falls sie wahr ist) den Anweisungsblock ausführen lässt, ...
 +
# das sog. '''Inkrement''' wird immer am Ende des Anweisungblocks ausgeführt. Die Anweisung '''x = x + 1''' kann man in JavaScript auch mir '''++x''' formulieren. Diese Abkürzung ist eine Spezialität aller '''C-Dialekte'''.
 +
# Der '''Anweisungsblock''' ist schließlich der Block, der ausgeführt wird, falls die Wiederholungsbedingung erfüllt ist.
  
 
===Die Möglichkeiten des menschlichen Rechnens kommen an ihre Grenzen: Primzahlen===
 
===Die Möglichkeiten des menschlichen Rechnens kommen an ihre Grenzen: Primzahlen===
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/7d00da2b-09de-4c47-b32e-e905343de1dd Primzahlen anhand der Anzahl der Teiler-Gegenteilerpaare erkennen]
+
'''Primzahlen sind die kleinsten Bausteine unserer Zahlen''' (zumindest, wenn wir multiplikativ denken). Jede Zahl kann man multiplikativ in immer kleinere Bausteine zerlegen (z.B. 100 = 10 * 10) bis - ja, bis es eben nimmer geht (100 = 2 * 5 * 2 * 5, feiner geht's nimmer). '''Die Bausteine, die nicht mehr weiterer zerlegbar sind, heißen Primzahlen'''. Ihr kennt sie seit der 5. Klasse. Aber auch die abgedrehtesten Forscher interessieren sich für Primzahlen, weil es so sehr seltsam undurchschaubar unregelmäßig ist, welche Zahlen zerlegbar sind und welche nicht. Oft kann man kleine Zahlen ganz oft zerlegen, obwohl sie eh schon so klein sind (48 = 2 * 2 * 2 * 2 * 3). Andere sind groß, aber nicht mehr zerlegbar (3449 = ? * ?).
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/b00b01a1-825b-46e8-ba3e-1114873e6dad Anzahl der nicht trivialen Teiler auf das Minimum reduziert]
+
 
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/f6b7f4d0-9b96-410e-8479-d7614295bd23 Primzahlliste]
+
Ist eine große Zahl zerlegbar (z.B. 5.625.319 = 7 * 233 * 3.449), dann findet man meist die Zerlegung schnell (als Mensch oder auch als Computer), denn man kann einen gefundenen Teiler (z.B. vorhin die Zahl 7) ja zum Teilen benutzen und dann beim Weitersuchen einfach mit dem viel kleineren Rest weitermachen. Findet man aber lange keinen Teiler, muss man (eventuell bis 5.625.319!) weiter '''alle Teiler durchprobieren'''. Und das kann schnell auch die Möglichkeiten eines Computers an seine Grenzen bringen. Wir in der 5. Klasse haben (je nach Ehrgeiz Eures Lehrers) bei 3-stelligen Zahlen das Handtuch geschmissen.
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/35ed97fa-d29d-4120-a06c-b8c9d91f8fdd Primfaktorzerlegung] (Zu was braucht man die function Primfaktor?)
+
 
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/801a7c35-552d-418d-a982-96e8cd9e5fd2 Die Primfaktorzerlegung als Funktion]
+
Aber jetzt haben wir ja einen Rechenknecht!
* [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/677679b0-b76b-42d1-b7f1-7ae78d3f81b0 Der Primzahltest als Funktion]
+
 
 +
===Programm 4: Wir testen zunächst nur, ob eine eingegebene Zahl eine Primzahl ist===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/ce6cdaaf-e123-4774-909c-52dd151c7d0f Direkt zu CUBE.CODES]<br>
 +
 
 +
Zahl=12197;
 +
Anzahl=0;<br>
 +
for(i=1; i<=Zahl; ++i) if(Zahl%i==0) ++Anzahl;
 +
if(Anzahl==2) UI.log("Primzahl"); else UI.log("Keine Primzahl");
 +
 
 +
Das Programm kommt schnell an seine Grenzen, aber funktioniert!
 +
 
 +
Nachdem das Erkennen einer Primzahl sicher immer wieder vorkommt, machen wir uns doch einen Befehl '''IstPrimzahl(x)''', den man immer wieder benutzen kann und wenden wir ihn gleich an, indem wir eine ganze Liste von Primzahlen ausgeben:
 +
 
 +
===Programm 5: Primzahlliste===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/680bb71f-b509-4931-9171-a32f46ec56c6 Direkt zu CUBE.CODES]<br>
 +
 
 +
function IstPrimzahl(x) {
 +
Anzahl=0;
 +
for(teiler=1; teiler<=x; ++teiler) if(x%teiler==0) ++Anzahl;
 +
if(Anzahl==2) return(1); else return(0);
 +
}<br>
 +
Zahl=100;
 +
UI.log("Die Primzahlen von 1 bis " + Zahl + ":");
 +
for(i=1; i<=Zahl; ++i) if(IstPrimzahl(i)==1) UI.log(i);
 +
 
 +
Das Ausgabedokument:
 +
 
 +
[13:22:20] Program starting ...
 +
[13:22:20] Program running ...
 +
Die Primzahlen von 1 bis 100:
 +
2
 +
3
 +
5
 +
7
 +
11
 +
13
 +
17
 +
19
 +
23
 +
29
 +
31
 +
37
 +
41
 +
43
 +
47
 +
53
 +
59
 +
61
 +
67
 +
71
 +
73
 +
79
 +
83
 +
89
 +
97
 +
[13:22:20] Program finished successfully
 +
 
 +
===Programm 6: Der nächste Streich: Die komplette Primfaktorzerlegung einer Zahl===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/8043ec6f-b64f-4b79-b8af-c082776f19f0 Direkt zu CUBE.CODES]<br>
 +
 
 +
Zahl=56253;
 +
x=Zahl;
 +
Teiler=2;
 +
Anzeige=String(Zahl)+"=";
 +
Rechenzeichen="";<br>
 +
while(x > 1 || Teiler<x) {
 +
if(x%Teiler==0) {
 +
Anzeige=Anzeige+Rechenzeichen+String(Teiler);
 +
Rechenzeichen="*";
 +
x=x/Teiler;
 +
        }
 +
else {
 +
    Teiler++;
 +
}
 +
}<br>
 +
UI.log(Anzeige);
 +
 
 +
Die unscheinbare Ausgabe lautet:
 +
 
 +
56253=3*17*1103
 +
 
 +
Welche Rechenarbeit steckt hinter diesem Ergebnis?!
 +
 
 +
Und gleich noch ein's drauf:
 +
 
 +
===Programm 7: Eine beliebig lange Liste von Primfaktorzerlegungen===
 +
>>> [https://ide.cube.codes/app/?init=loadFromUrl&url=https://share-repository.cube.codes/v1/appStates/8dce87af-72f9-4560-b83a-71f346cbb404 Direkt zu CUBE.CODES]<br>
 +
 
 +
Obergrenze=30;<br>
 +
for(Zahl=2; Zahl<=Obergrenze; ++Zahl) {
 +
x=Zahl;
 +
Teiler=2;
 +
Anzeige=String(Zahl)+"=";
 +
Rechenzeichen="";<br>
 +
while(x > 1 || Teiler<x) {
 +
if(x%Teiler==0) {
 +
Anzeige=Anzeige+Rechenzeichen+String(Teiler);
 +
Rechenzeichen="*";
 +
x=x/Teiler;
 +
}
 +
else {
 +
Teiler++;
 +
}
 +
}
 +
UI.log(Anzeige);
 +
}
 +
 
 +
Die Ausgabe:
 +
 
 +
[13:39:41] Program starting ...
 +
[13:39:42] Program running ...
 +
2=2
 +
3=3
 +
4=2*2
 +
5=5
 +
6=2*3
 +
7=7
 +
8=2*2*2
 +
9=3*3
 +
10=2*5
 +
11=11
 +
12=2*2*3
 +
13=13
 +
14=2*7
 +
15=3*5
 +
16=2*2*2*2
 +
17=17
 +
18=2*3*3
 +
19=19
 +
20=2*2*5
 +
21=3*7
 +
22=2*11
 +
23=23
 +
24=2*2*2*3
 +
25=5*5
 +
26=2*13
 +
27=3*3*3
 +
28=2*2*7
 +
29=29
 +
30=2*3*5
 +
[13:39:42] Program finished successfully
 +
 
 +
Wen das immer noch nicht beeindruckt, der gibt mal bei '''Obergrenze''' 3.000 ein!<br>
 +
(oder so, es spielt ja keine Rolle - er macht das ja für uns! ;-))

Aktuelle Version vom 23. April 2021, 08:17 Uhr

Einfache Schleifen: Vielfachenmenge und Teilermenge

CUBE.CODES - Erste Schritte

Ein einfaches, aber mächtiges Sprachelement jeder Programmiersprache ist die Wiederholungsschleife. Damit lassen wir die Möglichkeiten von Taschenrechner und Tabellenkalkulation weit hinter uns. Schon kleine Aufgaben aus der 5. Klasse werden schnell zu unlösbaren Problemen, wenn die Zahlen etwas größer werden. Die Berechnung der Teilermenge von 12 lässt sich zum Beispiel per Hand noch ganz problemlos durchführen: Wir teilen einfach die 12 durch alle möglichen Teiler (von 1 bis 12) und schauen eben, ob die Quotienten Ganzzahlen oder Kommazahlen sind oder wir wenden 12 Teilbarkeitsregeln an. Eigentlich easy!

Interessiert uns aber die Teilermenge von 5.000, dann sind es schon 5.000 Rechnungen. Interessiert uns eine Übersichtsliste über alle Teilermengen von 1 bis 5000, dann sind es im Schnitt schon 2.500*5.000, also ca. 12 Mio Rechnungen und die Klärung der Frage wird auf einmal zur Wochenarbeit.

In JavaScript können wir Aufgaben einfach mit Variablen formulieren und beliebig oft wiederholen lassen:

Programm 1: Erste Schleife: Teilercheckliste ausgeben

>>> Direkt zu CUBE.CODES

Zahl=12;
Teiler=1;
while(Teiler<=Zahl) { UI.log("Zahl: " + Zahl + ", Teiler: " + Teiler + ", Quotient: " + (Zahl/Teiler)); Teiler=Teiler+1; }

In weniger als einer Sekunde erhalten wir das Ergebnis:

[23:24:04] Program starting ...
[23:24:05] Program running ...
Zahl: 12, Teiler: 1, Quotient: 12
Zahl: 12, Teiler: 2, Quotient: 6
Zahl: 12, Teiler: 3, Quotient: 4
Zahl: 12, Teiler: 4, Quotient: 3
Zahl: 12, Teiler: 5, Quotient: 2.4
Zahl: 12, Teiler: 6, Quotient: 2
Zahl: 12, Teiler: 7, Quotient: 1.7142857142857142
Zahl: 12, Teiler: 8, Quotient: 1.5
Zahl: 12, Teiler: 9, Quotient: 1.3333333333333333
Zahl: 12, Teiler: 10, Quotient: 1.2
Zahl: 12, Teiler: 11, Quotient: 1.0909090909090908
Zahl: 12, Teiler: 12, Quotient: 1
[23:24:05] Program finished successfully

Wir müssen die Teiler mit ganzzahligen Quotienten nur ablesen und haben unsere Teilermenge. Da der PC bei der sturen Wiederholung von Rechenschritten recht schmerzfrei ist, stört es kein bisschen, die Zuordnung Zahl=12; durch Zahl=5000; zu ersetzen und in weniger als einer Sekunde haben wir die Teiler von 5000 - zugegebenermaßen etwas mühsam ablesbar!

Programm 2: Verbesserung: Unwichtige Ergebnisse bei der Ausgabe unterdrücken

>>> Direkt zu CUBE.CODES

Eine klitzekleine Formulierung mit if, eine sogenannte bedingte Anweisung ermöglicht es, die unwichtigen Ergebnisse (mit Kommazahlen als Quotienten) einfach wegzulassen und schon haben wir nur die Teiler auf dem Schirm.

Tipp: Versuch's mal mit 120191930!

Tipp: Das Prozentzeichen ist einfach der Rest bei ganzzahliger Teilung. Denkt an die Grundschule. Da hattet Ihr noch keine Kommazahlen. Auf die Frage: "Was ist 12 geteilt durch 5?", habt Ihr "2 Rest 2" geantwortet. Diese Antwort Rest = 2 ist das Ergebnis der Rechnung 12%5. Damit können wir leicht nachsehen, ob die Teilung 12/5 aufgeht. Nachdem das = Zeichen reserviert ist für Zuweisungen (x = 12; bedeutet ja: speichere 12 in der Speicherzelle (Variablen) x ab!), müssen wir für das = im Sinne eines Vergleichs eine andere Bezeichnung einführen, sonst gibt's Kuddelmuddel! In JavaScript ist das vergleichende = einfach das Doppelistgleich ==.

Zahl=12;
Teiler=1;
while(Teiler<=Zahl) { if(Zahl%Teiler==0) UI.log("Zahl: " + Zahl + ", Teiler: " + Teiler + ", Quotient: " + (Zahl/Teiler)); Teiler=Teiler+1; }

Das Ergebnis ist jetzt deutlich schöner lesbar:

[23:24:04] Program starting ...
[23:24:05] Program running ...
Zahl: 12, Teiler: 1, Quotient: 12
Zahl: 12, Teiler: 2, Quotient: 6
Zahl: 12, Teiler: 3, Quotient: 4
Zahl: 12, Teiler: 4, Quotient: 3
Zahl: 12, Teiler: 6, Quotient: 2
Zahl: 12, Teiler: 12, Quotient: 1
[23:24:05] Program finished successfully

Tipp: Und schon macht es Spaß, mathematisch zu experimentieren und uns kreativeren Fragen zuzuwenden als ständig zu rechnen. Wir haben jetzt ja einen Rechenknecht, dier die ...arbeit für uns erledigt: Große Zahlen haben nicht zwangsläufig lange Teilerlisten. Probiert mal kleine Zahlen zu finden, die trotzdem lange Teilerlisten haben oder umgekehrt große (möglichst krumme) Zahlen, die aber kurze Teilerlisten haben! (12 hat 6 Teiler, 113 aber nur zwei Teiler!) Welche Teilerlisten sind denn die kürzesten, die es gibt?

Ein kleiner Wettbewerb: Wer findet eine größere Zahl als 113, die trotzdem nur zwei Teiler hat?
Bisheriger Spitzenreiter Maria: 2341, Elisa: 3001

Mehr Aufgaben und Verbesserungen

Programm 3: Die Vielfachenmenge - Die Zählschleife - Ein beliebiges Einmaleins ausgeben

>>> Direkt zu CUBE.CODES

1 * 12 = 12
2 * 12 = 24
3 * 12 = 36
4 * 12 = 48
5 * 12 = 60
6 * 12 = 72
7 * 12 = 84
8 * 12 = 96
9 * 12 = 108
10 * 12 = 120

Ein Einmalseins ist eigentlich leichter ausgegeben als eine Teilermenge, aber schon wieder müssen wir eine Wiederholung formulieren und mitzählen. Da das so oft vorkommt, gibt es eine Zählschleife, die das alles in einem Schwung formuliert und schon wird die Schleife nur noch ein Einzeiler:

>>> Direkt zu CUBE.CODES

Zahl=12;
for(x=1; x<=10; ++x) UI.log(x + " * " + Zahl + " = " + (x*Zahl));

In dem Muster ...

for(Anfangswert; Wiederholungsbedingung; Veränderung am Ende (Inkrement)) Anweisungsblock;

ist ...

  1. Der Anfangswert eine Zuweisung, die irgendeine frei wählbare Zählervariable auf einen Anfangswert setzt, ...
  2. die Wiederholungsbedingung irgendeine Bedingung, die (falls sie wahr ist) den Anweisungsblock ausführen lässt, ...
  3. das sog. Inkrement wird immer am Ende des Anweisungblocks ausgeführt. Die Anweisung x = x + 1 kann man in JavaScript auch mir ++x formulieren. Diese Abkürzung ist eine Spezialität aller C-Dialekte.
  4. Der Anweisungsblock ist schließlich der Block, der ausgeführt wird, falls die Wiederholungsbedingung erfüllt ist.

Die Möglichkeiten des menschlichen Rechnens kommen an ihre Grenzen: Primzahlen

Primzahlen sind die kleinsten Bausteine unserer Zahlen (zumindest, wenn wir multiplikativ denken). Jede Zahl kann man multiplikativ in immer kleinere Bausteine zerlegen (z.B. 100 = 10 * 10) bis - ja, bis es eben nimmer geht (100 = 2 * 5 * 2 * 5, feiner geht's nimmer). Die Bausteine, die nicht mehr weiterer zerlegbar sind, heißen Primzahlen. Ihr kennt sie seit der 5. Klasse. Aber auch die abgedrehtesten Forscher interessieren sich für Primzahlen, weil es so sehr seltsam undurchschaubar unregelmäßig ist, welche Zahlen zerlegbar sind und welche nicht. Oft kann man kleine Zahlen ganz oft zerlegen, obwohl sie eh schon so klein sind (48 = 2 * 2 * 2 * 2 * 3). Andere sind groß, aber nicht mehr zerlegbar (3449 = ? * ?).

Ist eine große Zahl zerlegbar (z.B. 5.625.319 = 7 * 233 * 3.449), dann findet man meist die Zerlegung schnell (als Mensch oder auch als Computer), denn man kann einen gefundenen Teiler (z.B. vorhin die Zahl 7) ja zum Teilen benutzen und dann beim Weitersuchen einfach mit dem viel kleineren Rest weitermachen. Findet man aber lange keinen Teiler, muss man (eventuell bis 5.625.319!) weiter alle Teiler durchprobieren. Und das kann schnell auch die Möglichkeiten eines Computers an seine Grenzen bringen. Wir in der 5. Klasse haben (je nach Ehrgeiz Eures Lehrers) bei 3-stelligen Zahlen das Handtuch geschmissen.

Aber jetzt haben wir ja einen Rechenknecht!

Programm 4: Wir testen zunächst nur, ob eine eingegebene Zahl eine Primzahl ist

>>> Direkt zu CUBE.CODES

Zahl=12197;
Anzahl=0;
for(i=1; i<=Zahl; ++i) if(Zahl%i==0) ++Anzahl; if(Anzahl==2) UI.log("Primzahl"); else UI.log("Keine Primzahl");

Das Programm kommt schnell an seine Grenzen, aber funktioniert!

Nachdem das Erkennen einer Primzahl sicher immer wieder vorkommt, machen wir uns doch einen Befehl IstPrimzahl(x), den man immer wieder benutzen kann und wenden wir ihn gleich an, indem wir eine ganze Liste von Primzahlen ausgeben:

Programm 5: Primzahlliste

>>> Direkt zu CUBE.CODES

function IstPrimzahl(x) {
	Anzahl=0;
	for(teiler=1; teiler<=x; ++teiler) if(x%teiler==0) ++Anzahl;
	if(Anzahl==2) return(1); else return(0);
}
Zahl=100; UI.log("Die Primzahlen von 1 bis " + Zahl + ":"); for(i=1; i<=Zahl; ++i) if(IstPrimzahl(i)==1) UI.log(i);

Das Ausgabedokument:

[13:22:20] Program starting ...
[13:22:20] Program running ...
Die Primzahlen von 1 bis 100:
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
[13:22:20] Program finished successfully

Programm 6: Der nächste Streich: Die komplette Primfaktorzerlegung einer Zahl

>>> Direkt zu CUBE.CODES

Zahl=56253;
x=Zahl;
Teiler=2;
Anzeige=String(Zahl)+"=";
Rechenzeichen="";
while(x > 1 || Teiler<x) { if(x%Teiler==0) { Anzeige=Anzeige+Rechenzeichen+String(Teiler); Rechenzeichen="*"; x=x/Teiler; } else { Teiler++; } }
UI.log(Anzeige);

Die unscheinbare Ausgabe lautet:

56253=3*17*1103 

Welche Rechenarbeit steckt hinter diesem Ergebnis?!

Und gleich noch ein's drauf:

Programm 7: Eine beliebig lange Liste von Primfaktorzerlegungen

>>> Direkt zu CUBE.CODES

Obergrenze=30;
for(Zahl=2; Zahl<=Obergrenze; ++Zahl) { x=Zahl; Teiler=2; Anzeige=String(Zahl)+"="; Rechenzeichen="";
while(x > 1 || Teiler<x) { if(x%Teiler==0) { Anzeige=Anzeige+Rechenzeichen+String(Teiler); Rechenzeichen="*"; x=x/Teiler; } else { Teiler++; } } UI.log(Anzeige); }

Die Ausgabe:

[13:39:41] Program starting ...
[13:39:42] Program running ...
2=2
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5
11=11
12=2*2*3
13=13
14=2*7
15=3*5
16=2*2*2*2
17=17
18=2*3*3
19=19
20=2*2*5
21=3*7
22=2*11
23=23
24=2*2*2*3
25=5*5
26=2*13
27=3*3*3
28=2*2*7
29=29
30=2*3*5
[13:39:42] Program finished successfully

Wen das immer noch nicht beeindruckt, der gibt mal bei Obergrenze 3.000 ein!
(oder so, es spielt ja keine Rolle - er macht das ja für uns! ;-))