मैं Project Euler Problem #145 पर एक ब्रूट-फोर्स समाधान लिखने की कोशिश कर रहा हूं, और मुझे लगभग 1 मिनट 30 सेकंड से कम समय में चलाने का मेरा समाधान नहीं मिल रहा है।मैं एक लूप को कैसे अनुकूलित कर सकता हूं जो पूरी तरह सख्त हो सकता है
(मुझे पता है कि विभिन्न शॉर्ट-कट और पेपर-एंड-पेंसिल समाधान भी हैं; इस प्रश्न के उद्देश्य के लिए मैं उन पर विचार नहीं कर रहा हूं)।
अब तक के सबसे अच्छे संस्करण में आया है, प्रोफाइलिंग से पता चलता है कि अधिकांश समय foldDigits
में बिताया जाता है। इस समारोह को आलसी नहीं होना चाहिए, और मेरे दिमाग में एक साधारण पाश को अनुकूलित किया जाना चाहिए। जैसा कि आप देख सकते हैं कि मैंने कार्यक्रम के विभिन्न बिट्स को सख्त बनाने का प्रयास किया है।
तो मेरा सवाल है: समग्र एल्गोरिदम बदलने के बिना, क्या इस प्रोग्राम के निष्पादन समय को उप-मिनट के निशान में लाने का कोई तरीका है?
(या यदि नहीं, तो वहाँ कि foldDigits
का कोड संभव के रूप में अनुकूलित है के रूप में देखने के लिए एक तरीका है?)
-- ghc -O3 -threaded Euler-145.hs && Euler-145.exe +RTS -N4
{-# LANGUAGE BangPatterns #-}
import Control.Parallel.Strategies
foldDigits :: (a -> Int -> a) -> a -> Int -> a
foldDigits f !acc !n
| n < 10 = i
| otherwise = foldDigits f i d
where (d, m) = n `quotRem` 10
!i = f acc m
reverseNumber :: Int -> Int
reverseNumber !n
= foldDigits accumulate 0 n
where accumulate !v !d = v * 10 + d
allDigitsOdd :: Int -> Bool
allDigitsOdd n
= foldDigits andOdd True n
where andOdd !a d = a && isOdd d
isOdd !x = x `rem` 2 /= 0
isReversible :: Int -> Bool
isReversible n
= notDivisibleByTen n && allDigitsOdd (n + rn)
where rn = reverseNumber n
notDivisibleByTen !x = x `rem` 10 /= 0
countRange acc start end
| start > end = acc
| otherwise = countRange (acc + v) (start + 1) end
where v = if isReversible start then 1 else 0
main
= print $ sum $ parMap rseq cr ranges
where max = 1000000000
qmax = max `div` 4
ranges = [(1, qmax), (qmax, qmax * 2), (qmax * 2, qmax * 3), (qmax * 3, max)]
cr (s, e) = countRange 0 s e
आप इसे कितने कोर पर चल रहे हैं? – ErikR
यह कोर-i5-760 है, इसलिए चार कोर। मुझे पता है कि आवेदन में श्रेणियों को कड़ी-कोडिंग करना थोड़ा मुश्किल है, लेकिन इसने समांतरता को थोड़ा स्पष्ट बना दिया। – stusmith