|
Meine Frage:
Hallo,
im Internet habe ich einen Code aufgeschnappt womit man Collatz reihen generieren kann. Ich interessiere mich mathematisch für das Collatz Problem und würde den Code gerne modifizieren. Leider habe ich von Informatik keine Ahnung. Brauche den Code also nur als Mittel zum Zweck... Vielleicht kann mir jemand helfen...
Der Code generiert mit VBA Excel für die Zahlen 1-100 (die in der ersten Zeile einer Excel Tabelle aufgereiht sind) die Bildungsvorschrift bei geraden Zahlen durch 2 und bei ungeraden Zahlen 3n+1 bis man bei 1 angelangt ist. Wenn ich den Code mit 5n+1 durchrechnen lasse taucht interessanterweise mehr als eine Schleife auf.
Ich brauche den Code also so dass er nicht bei 1 abbricht sondern genau dann wenn eine Zahl doppelt auftaucht. So dass man sofort sieht wenn eine Schleife auftacht. Beispiel für 5n+1
1,6,3,16,8,4,2,1
2,1,6,3,16,8,4,2,1
3,16,8,4,2,1,6,3,16,8,4,2,1
4,2,1,6,3,16,8,4,2,1
5,26,13,66,33,166,83,416,208,104,52,26
Hier gibt es also für die Zahlen 1-4 die Schleife mit der Zahl 1. Bei der 5. Zahl kommt nun eine neue Schleife mit der Zahl 26. Da mein Code ja nun immer bis 1 rechnen muss kommt es dann in diser 5. Spalte zu einer Dauerschleife... Er soll aber genau dann abbrechen wenn die Zahl in der Spalte das zweite Mal auftaucht.
Weiß jemand was ich da schreiben muss?
Meine Ideen:
Sub eintragen()
Dim maxSpalten As Integer, Zeile As Integer
Dim fertig As Boolean
maxSpalten = 100
Rows("1:65536").ClearContents
For Spalte = 1 To maxSpalten 'erste Zeile eintragen
fertig = False
Zeile = 1
Cells(1, Spalte).Value = Spalte
Do Until fertig = True
Cells(Zeile + 1, Spalte).Value = Collatz(Cells(Zeile, Spalte).Value)
If Collatz(Cells(Zeile, Spalte).Value) = 1 And Zeile >= 2 Then
fertig = True
End If
Zeile = Zeile + 1
Loop
Next
End Sub
Function Collatz(zahl As Integer) As Integer
If zahl Mod 2 = 0 Then 'zahl ist gerade
Collatz = zahl / 2
Else 'zahl ist ungerade
Collatz = 5 * zahl + 1
End If
End Function
|
|
09.04.2016 16:24 |
|
|
| |
|
|
Ja cool... Danke... Das muss ich erst mal sacken lassen... Doofe Frage... Wo kann ich mir den Code denn jetzt ausrechnen lassen? Bin leider absoluter Laie... Ich habe VS drauf aber da sind soviele Anwendungen... Muss ich ein neues Projekt öffnen oder eher nur eine Datei? Wie bekomme ich die Zahlen angezeigt?
__________________ Gruß blindmessenger
|
|
09.04.2016 17:40 |
|
|
|
Hast du eine VS Version, die C# unterstützt?
Ich habe die Abfolge nicht genau im Kopf - ich nutze MonoDevelop.
Neues Projekt -> C# Konsolenanwendung -> Speicherort wählen.
Dann kannst du meinen Code reinkopieren (den Namespace lässt du am besten so, wie er bei dir heißt).
Um BigInteger verwenden zu können, musst du dann noch einen Verweis hinzufügen.
Dazu in der Projektmappe (standardmäßig am rechten Rand) einen Rechtsklick auf Verweise und dann System.Numerics auswählen.
Wenn das erledigt ist, kannst du mit F5 ausführen.
Wenn die Ausgabebox sofort wieder verschwindet, füge am besten zwischen Zeile 33 und 34 noch ein Conosle.ReadLine() ein. Dann schließt sich das Fenster erst mit Enter.
__________________ Syntax Highlighting fürs Board (Link)
|
|
09.04.2016 17:47 |
|
|
|
Wie sieht es denn für 7n+1 aus? Oder 9n+1? Kannst DU mir die vielleicht auch noch kurz ausgeben? Bis ich den Code verwenden kann muss ich erst noch ein paar Bücher lesen... ;-)
__________________ Gruß blindmessenger
|
|
09.04.2016 17:49 |
|
|
|
Na, meinetwegen.
Hier alle Kreise, deren Maximalwert nicht über 1 Million liegt für Faktoren < 1000.
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
|
3: 1, 4, 2
5: 1, 6, 3, 16, 8, 4, 2 : 17, 86, 43, 216, 108, 54, 27, 136, 68, 34
7: 1, 8, 4, 2
15: 1, 16, 8, 4, 2
31: 1, 32, 16, 8, 4, 2
63: 1, 64, 32, 16, 8, 4, 2
127: 1, 128, 64, 32, 16, 8, 4, 2
181: 27, 4888, 2444, 1222, 611, 110592, 55296, 27648, 13824, 6912, 3456, 1728, 864, 432, 216, 108, 54 : 35, 6336, 3168, 1584, 792, 396, 198, 99, 17920, 8960, 4480, 2240, 1120, 560, 280, 140, 70
255: 1, 256, 128, 64, 32, 16, 8, 4, 2
511: 1, 512, 256, 128, 64, 32, 16, 8, 4, 2
|
|
Die Kreise zur 1 hin für 2^n-1 überaschen nicht.
Für 5 und 181 gibt es 2 Kreise.
Bei 181 habe ich keinen Kreis mit Startwert 1 gefunden. Den kann es natürlich trotzdem geben, er hat dann aber definitiv eine Länge > 100000.
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Infoboard
{
class MainClass
{
static void Main(string[] args) {
int max = (int)1e6;
int[] collatz = new int[max + 1];
for (int f = 3; f < 1000; f+=2) {
for (int i = 1; i <= max; i++) {
if (i % 2 == 0)
collatz [i] = i / 2;
else
collatz [i] = f * i + 1;
}
List<List<int>> loops = new List<List<int>> ();
for (int start = 1; start <= max; start++) {
if (collatz [start] == 0)
continue;
List<int> seq = new List<int> ();
int current = start;
while (current <= max && collatz[current] != 0) {
seq.Add (current);
int tmp = collatz [current];
collatz [current] = 0;
current = tmp;
}
if (current == start)
loops.Add (seq);
}
if (loops.Count > 0)
Console.WriteLine (f + ": " + string.Join (" : ", loops.Select (loop => string.Join (", ", loop))));
}
}
}
} |
|
__________________ Syntax Highlighting fürs Board (Link)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von eulerscheZahl: 09.04.2016 18:34.
|
|
09.04.2016 18:31 |
|
|
|
Danke für Deine Mühe... Ich hätte noch eine Frage und zwar bräuchte ich für den 3n+1 Code noch eine kleine Modifikation:
Der normale Collatz geht ja so:
1,4,2,1
2,1
3,10,5,16,8,4,2,1
4,2,1
5,16,8,4,2,1
Ich hätte gerne:
1
2,1
3,5,1
4,1
5,1
Also: Ich bräuchte die Collatz Reihe aber nur mit den ungeraden Zahlen... Hättest Du dafür auch noch einen Code. So könnte man sich eine Matrix bauen und untersuchen...
Das mit VS hat bei mir jetzt auch funktioniert...
__________________ Gruß blindmessenger
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von blindmessenger: 09.04.2016 20:19.
|
|
09.04.2016 20:19 |
|
|
|
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Infoboard
{
class MainClass
{
static List<long> Collatz(int n) {
List<long> sequence = new List<long> { n };
while (n != 1) {
if (n % 2 == 0)
n /= 2;
else
n = n * 3 + 1;
if (n % 2 == 1)
sequence.Add (n);
}
return sequence;
}
static void Main(string[] args) {
for (int i = 1; i < 50; i++) {
Console.WriteLine (string.Join (" ", Collatz (i)));
}
}
}
} |
|
Ausgabe:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
|
1
2 1
3 5 1
4 1
5 1
6 3 5 1
7 11 17 13 5 1
8 1
9 7 11 17 13 5 1
10 5 1
11 17 13 5 1
12 3 5 1
13 5 1
14 7 11 17 13 5 1
15 23 35 53 5 1
[...] |
|
__________________ Syntax Highlighting fürs Board (Link)
|
|
09.04.2016 20:34 |
|
|
|
Ich danke Dir...
__________________ Gruß blindmessenger
|
|
09.04.2016 23:35 |
|
|
|
Es sind "nur" 16096 Stellen (wie du in deinem Edit ja auch erkannt hast).
Die Zahl ist noch exakt. Das ist auch der Grund, warum ich von Excel abgeraten habe.
Aus der Hilfe:
Zitat: |
Der BigInteger-Typ ist ein unveränderlicher Typ, der eine beliebig große ganze Zahl darstellt, deren Wert theoretisch keine obere oder untere Grenze hat. |
Die Begrenzung liegt nur im vorhandenen Arbeitsspeicher. Die errechnete Zahl braucht bei guter Speicherverwaltung knapp 7kB, das ist also kein Problem.
__________________ Syntax Highlighting fürs Board (Link)
|
|
10.04.2016 20:36 |
|
|
|
|
|