001    package de.hska.java.aufgaben.kontrollstrukturen;
002    
003    /**
004     * Programm, welches Kandiaten für Lychrel-Zahlen findet.
005     * 
006     * <p>
007     *   <a href="http://www.home.hs-karlsruhe.de/~pach0003/informatik_1/aufgaben/kontrollanweisungen.html#lychrel_zahl">Zurück zum Aufgabentext</a>
008     * </p>
009     * 
010     * 
011     * @author Christian Pape
012     */
013    public class LychrelZahl {
014    
015            private static final int MAXIMALE_ITERATIONEN = 1000000000;
016            
017            /**
018             * Gibt potentiellen Lychrel-Zahlen von 1 bis 1000 aus.
019             */
020            public static void main(String[] args) {
021                    for (long zahl = 1; zahl <= 1000; zahl++) {
022                            if (! erzeugePalindrom(zahl) ) {
023                                    System.out.println(zahl);
024                            }
025                    }
026            }
027    
028            /**
029             * 
030             * <p>
031             * Gibt <code>true</code> zurück, wenn aus der Zahl nach dem
032             * folgenden Algorithmus ein Palindrom gebildet werden konnte.
033             * Gibt <code>false</code> zurück, falls ein Überlauf auftrat
034             * oder der Algorithmus nach <code>MAXIMALE_ITERATIONEN</code>
035             * Schritten nicht terminierte.
036             * </p>
037             * 
038             * <p>
039             * Erzeugt Palindrome aus der <code>zahl</code>, indem
040             * fortlaufend die Summe aus <code>zahl</code> und 
041             * <code>umdrehen(zahl)</code> gebildet wird, bis 
042             * ein Palindrom entsteht.
043             * </p>
044             * 
045             * @param zahl eine positive Zahl
046             */
047            public static boolean erzeugePalindrom(long zahl) {
048          long palindrom = zahl;
049          
050          for (int i = 0; i < MAXIMALE_ITERATIONEN && zahl > 0 && ! isPalindrom(palindrom); i++) {
051                palindrom = palindrom + umdrehen(palindrom);
052          }
053              
054              return palindrom > 0 && isPalindrom(palindrom);
055            }
056    
057            /**
058             * Gibt genau dann <code>true</code> zurück, wenn <code>zahl</code>
059             * ein Palindrom ist.
060             * 
061             * @param zahl eine positive Zahl
062             */
063            public static boolean isPalindrom(long zahl) {
064                    return umdrehen(zahl) == zahl;
065            }
066    
067            /**
068             * Gibt die Zahl zurück, die sich durch umkehren
069             * der Dezimalziffer von <code>zahl</code> ergibt.
070             * Zum Beispiel ergibt <code>umdrehen(132)</code> die
071             * Zahl <code>231</code>.
072             * 
073             * @param zahl eine positive Zahl
074             */
075            private static long umdrehen(long zahl) {
076                    long umkehrung = 0;
077                    
078                    while (zahl > 0) {
079                            umkehrung = umkehrung * 10 + zahl % 10;
080                            zahl /= 10;
081                    }
082                    
083                    return umkehrung;
084            }
085    }