Längste Collatz-Folge

sserio

Bekanntes Mitglied
Aufgabe:
Die folgende sich wiederholende Folge ist definiert für die Menge der positiven ganzen Zahlen:

n → n/2 (n ist gerade)
n → 3n + 1 (n ist ungerade)

Wenn wir die Regeln oben benutzen und mit 13 beginnen, erhalten wir die folgende Folge:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
Es ist zu sehen, dass diese Folge (beginnend bei 13 und endend bei 1) 10 Glieder enthält. Obwohl es bisher nicht bewiesen wurde (Collatz-Problem), wird vermutet, dass alle Anfangszahlen bei 1 enden.

Welche Anfangszahl unter 1 Million erzeugt die längste Folge?
Java:
package ProjectEuler14;

import java.math.BigInteger;

public class Main {
    public static void main(String... args) {
        System.out.printf("%1$d ", findTheNumberWithTheLongestCollatzFollow(1000000));
    }

    public static int findTheNumberWithTheLongestCollatzFollow(int limit) {
        var value = 0;
        var temp = 0;
        for (var number = 3; number < limit; number++) {
            if (getFactorLength(number) > temp) {
                temp = getFactorLength(number);
                value = number;
            }
        }
        return value;
    }

    public static int getFactorLength(int number) {
        var counter = 0;
        while (number > 1) {
            if (isEven(number)) {
                number = number / 2;
                counter++;
            } else {
                number = 3 * number + 1;
                counter++;
            }
        }

        return counter;
    }

    public static boolean isEven(int number) {
        if (number % 2 == 0) {
            return true;
        } else return false;
    }
}
Weshalb gibt er mir 910107 aus ? irgendwas muss falsch laufen. Das richtige ergebnis ist 837799
 
Zuletzt bearbeitet:
Das Programm funktioniert. Ich habe es getestet mit einem anderen Rechner im Internet. Jedoch wird es irgendwie nicht aktualisiert bei 837799

EDIT: ich habe mir jetzt mal ausgeben lassen was die teiler von meinem angeblichen ergebnis und dem wirklichen ergebnis ist. Wieso zur Hölle
ist bei dem einen die richtige anzahl und bei dem anderen was komplett falsches XD
Java:
837799 //richtiges ergebnis
58 // falche teiler vom richtigen
475 //richtige Teiler vom falschen
910107 //falsches ergebnis
 
Zuletzt bearbeitet:
gib dir die zwischen ergebnisse aus und rechne selber die ersten paar schritte... da wo es nicht gleich ist siehst du dann den fehler

und
Java:
    public static boolean isEven(int number) {
        return number % 2 == 0;
    }
tut doch in den augen weh 😀
 
gib dir die zwischen ergebnisse aus und rechne selber die ersten paar schritte... da wo es nicht gleich ist siehst du dann den fehler

und
Java:
    public static boolean isEven(int number) {
        return number % 2 == 0;
    }
tut doch in den augen weh 😀
ja habs geändert. Ich glaube ich weiß woran es liegt. Ich habe gerade 20min mit dem taschenrechner durchgerechnet. Die zahl wird irgendwann zu groß .... Aber wobei ... ich habe var benutzt und ein long sollte eigentlich ausreichen
 
ein var ist in dem moment genau der objekt typ der rechts steht im code bzw der während compile zeit erwartet wird der raus kommt

der verändert sich nicht nach lust und laune 🙂

wenn du sagst

dann ist und bleibt var ein integer für immer und ewig außer du castest natürlich
 
OMFG es lag einfach daran, dass ich falsch gecastet habe!!!!! Ich habe bei *3 oder +1 jetzt überall ein großes L drangehangen und auch bei den Schleifen alles mit long gemacht. Als wenn das zu einem Fehler im ganzen programm führen kann. Oh man 🙁
 
ein var ist in dem moment genau der objekt typ der rechts steht im code bzw der während compile zeit erwartet wird der raus kommt

der verändert sich nicht nach lust und laune 🙂

wenn du sagst


dann ist und bleibt var ein integer für immer und ewig außer du castest natürlich
wo du gerade casten ansprichst xD ist es mir selber auch eingefallen
 
Java:
package ProjectEuler14;

public class Main {
    public static void main(String... args) {
        System.out.printf("%1$d ", findTheNumberWithTheLongestCollatzFollow(1_000_000));
    }

    public static long findTheNumberWithTheLongestCollatzFollow(int limit) {
        long value = 0L;
        long temp = 0L;
        for (long number = limit - 1L; number > 3L; number--) {
            if (getFactorLength(number) > temp) {
                temp = getFactorLength(number);
                value = number;

            }
        }
        return value;
    }

    public static long getFactorLength(long number) {
        var counter = 0L;
        while (number > 1L) {
            if (isEven(number)) {
                number = number / 2L;
            } else {
                number = (3L * number) + 1L;
            }
            counter++;
        }
        return counter;
    }

    public static boolean isEven(long number) {
        return number % 2L == 0L;
    }
}
 
Ob das jetzt wirklich bei jedem so nötig ist ein L dranzuhängen lass ich mal so stehen. Weil ich mich noch nicht so auskenne
 
naja du musst ja unterscheiden obs ein float ein long ein double usw is

double ist wahrshcienlich besser für dein ding

obs ein unsigned double auch gibt weis ich grad nicht
 
Ob das jetzt wirklich bei jedem so nötig ist ein L dranzuhängen lass ich mal so stehen. Weil ich mich noch nicht so auskenne
Nein. Java konvertiert ggf. automatisch nach long. Wenn Du z. B. ein int mit einem long vergleichst, wird der int-Wert vor dem eigentlichen Vergleich automatisch nach long konvertiert (s. https://docs.oracle.com/javase/specs/jls/se10/html/jls-5.html#jls-5.1.2 i. V. m. https://docs.oracle.com/javase/specs/jls/se10/html/jls-4.html#jls-4.2.2)

In Deiner Methode findTheNumberWithTheLongestCollatzFollow brauchst Du gar kein long und in getFactorLength nur für die Berechnung der Zahl:
Java:
    public static int getFactorLength(int initialNumber) {
        int counter = 0;
        long number = initialNumber;
        while (number > 1L) {
            if (isEven(number)) {
                number = number / 2L;
            } else {
                number = (3L * number) + 1L;
            }
            counter++;
        }
        return counter;
    }
 

Zurück
Oben