Euler项目8-Haskell

Euler项目8-Haskell,haskell,Haskell,通过Euler项目,我将我的解决方案与其他解决方案进行比较 对于问题8,我的代码生成正确答案(通过网站上的校验和确认)23514624000 module Main where import Data.List main = do print $ last (sort eulerEight) eulerEight = doCalc [ x | x <- toDigits 7316717653133062491922511967442657474235534919493496

通过Euler项目,我将我的解决方案与其他解决方案进行比较

对于问题8,我的代码生成正确答案(通过网站上的校验和确认)23514624000

module Main where

import Data.List

main = do
    print $ last (sort eulerEight)


eulerEight = doCalc [ x | x <- toDigits 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450]
    where
        doCalc (_:[]) = []
        doCalc (x:xs) = if 0 `notElem` take 13 (x:xs) && length (x:xs) > 12
                then product (take 13 (x:xs)) : doCalc xs
                else doCalc xs

toDigits n 
 | n < 1 = []
 | otherwise = toDigits (n `div` 10) ++ [n `mod` 10]
modulemain其中
导入数据。列表
main=do
打印$last(排序eulerEight)
eulerEight=doCalc[x | x 12
然后产品(取13(x:xs)):doCalc-xs
else doCalc xs
托迪金
|n<1=[]
|否则=toDigits(n`div`10)+[n`mod`10]
我意识到这可能会好得多,所以检查了解决方案,它似乎不正确

import Data.Char (digitToInt)
import Data.List

problem_8 = do
        str <- readFile "number.txt"
        -- This line just converts our str(ing) to a list of 1000 Ints
        let number = map digitToInt (concat $ lines str)
        print $ maximum $ map (product . take 13) (tails number)
导入数据.Char(DigitPoint) 导入数据。列表 问题8=do
str发生的情况是,
digitToInt
返回一个
Int
,在32位系统上,当5增加到13时,该值太短,无法保存测试数字。将其更改为
(从integral.digitToInt)
,它工作正常。

问题已被确定为Int溢出,但wiki代码本身不正确。它没有正确截断列表,可能会产生不正确的结果,具体取决于输入数据(即,它很幸运地在此处产生了正确的结果)

想象一个以
0
结尾的数字串,后跟12
9
s。在计算最大值时,该代码将错误地考虑
9^12
。更简单的是,对于1000个零,它将产生1作为答案

由于压缩的特性,我们可以实现自动截断:


顺便说一句,如果有人感到困惑,我还擅自修改了维基上的代码:)我注意到有一些解决方案与原来的问题不太匹配。不过让你保持警惕!我假设他们正在更新Project Euler网站上的问题,以补偿摩尔定律或其他东西。你能解释一下吗你用拉链做了什么?无点符号让我很难理解。@matthias无点实际上对我来说更容易理解。:)只要把
读成“of”:“打印
地图产品的
最大值的结果,以及折叠
zipWith(:)
在列表中,最右边的元素是
重复[]=[[]、[]、[]、[]、[]、[]、[]、[]、…]、[/code>”。关键是标识
foldr f z[a、b、…,n]==f a(f b(f…(f n z)…)
。因此,使用
取3
,我们将得到
带(:)的zipWith(:)xs(带(:)(带)的zipWith(:)(带(:)(带)的尾xs)(带)(带)的zipWith(:)(带)(带)的zipWith(:)(带)(带)(带)
。例如,对于
xs=[a,b,c,d]
这将产生
[a:b:c:[],b:c:d:[]
。压缩在最短的列表上停止,因此没有
c:d:[]
……因为没有
e
!--我们所得到的是
zipWith(:)[a,b,c,d](zipWith(:)[b,c,d](zipWith(:)[c,d])(重复[)
。结果是,额外的尾部被自动忽略,而我们没有额外的努力。:)并且我们生成的所有子列表的长度都相同——3.谢谢。我写了
最大$map product$foldr(zipWith(:)(重复[])$take 13$iterate tail x
我对空列表的内容有问题,你的帖子也有帮助。这确实让我读起来更容易,但我还是觉得有点难:)我指的是数字
n xs。你用xs作为累加器吗?
import Data.Char
import Data.List

euler_8 = do
   str <- readFile "numbers.txt"
   print . maximum . map product
         . foldr (zipWith (:)) (repeat [])   -- here
         . take 13 . tails . map (fromIntegral . digitToInt)
         . concat . lines $ str
toDigits n xs  -- to be called as `toDigits n []`
 | n < 1 = xs
 | otherwise = toDigits (n `div` 10) ((n `mod` 10) : xs)