4

Ich lerne Grundlagen von Haskell und versuche, Projekt Eulers einfache Aufgaben zu lösen: finde das größte Palindrom der dreistelligen Zahlen (100.999). Ich schrieb diesen Code:Merkwürdiges Verhalten der Listenkomprehensionen

palindrome = maximum $ filter (\a -> reverse a == a) $ 
            map show [ x*y :: Int | x <- [100 .. 999], 
                  y <- [x, x+1 .. 999]] 

Es gibt eine falsche Antwort = 99999, wenn ich es noch zu x <- [307 .. 999] Antwort ändern, ist falsch: 94249 (alle Palindrome, aber nicht die größte) und schließlich, wenn ich es zu x <- [308 .. 999], ändern sie gibt mir richtige Antwort: 906609.

Ich verstehe dieses Verhalten wirklich nicht: es scheint, dass es eine Art von Überlauf und Trunkierung innerhalb der generierten Liste passiert. Kann mir jemand dieses falsche Verhalten erklären? Ich will nicht Sie die Aufgabe zu beantworten: Ich weiß, meine Lösung ist nicht sehr effizient. Ich möchte nur, dass Sie dieses Codeverhalten erklären (Abschneiden der Liste oder Speicherprobleme). Vielen Dank.

Antwort

9

Das Ergebnis von filter ist eine Liste von String Werte, so maximum vergleicht sie lexikographisch. Sie müssen zuerst die Werte zurück in Int s konvertieren. Die Typ-Signatur stellt sicher, dass read Werte des richtigen Typs zurückgibt.

palindrome :: Int 
palindrome = maximum . map read . filter ... 

Ein weiterer Ansatz ist es, nur einen Wert zu einem String im selbst Filter zu konvertieren:

palindrome :: Int 
palindrome = maximum $ filter (\a -> let sa = show a in reverse sa == sa) [ x*y | x <- [100..999], y <- [x..999]] 
+0

Danke für die schnelle Antwort, aber lexikographische Reihenfolge ist alphabetisch sortiert nach Länge Vergleich voraus, so 906.609 ist immer noch größer als 99999. Warum ändert sich das Vergleichsergebnis nur, wenn ich die Grenze ändere? – MainstreamDeveloper00

+5

Länge wird überprüft * nach * alphabetischer Reihenfolge. '" aaaaaaaaaa "<" b "'. – chepner

+0

Indem Sie die untere Grenze für "x" ändern, eliminieren Sie die Zahlen, die aus allen 9 bestehen. – chepner