Created
October 3, 2013 22:19
-
-
Save nfunato/6818019 to your computer and use it in GitHub Desktop.
project euler problem 17
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
p17 = p17' [1..1000] | |
p17' = sum . map (length . filter(`notElem` " -") . itoa) | |
itoa i | |
| i < 0 = "minus " ++ itoa (-i) | |
| i < 20 = smalls i | |
| i < 100 = f (quotRem i 10) tens "-" smalls | |
| i < 1000 = f (quotRem i 100) ((++" hundred").smalls) " and " itoa | |
| i ==1000 = "one thousand" | |
| otherwise = error "unsupported range" | |
where f (q,0) a _ _ = a q | |
f (q,r) a b c = a q ++ b ++ c r | |
smalls = (["zero", "one", "two", "three", "four", "five", "six", "seven", | |
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", | |
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"] !!) | |
tens = ([undefined, undefined, "twenty", "thirty", "forty", "fifty", | |
"sixty", "seventy", "eighty", "ninety"] !!) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- try ghc -O4 -fno-cse --make p17b.hs | |
import Data.List (intercalate, unfoldr) | |
main = print $ p17' [1..123456789012345678901234567890123456] | |
p17 = p17' [1..1000] | |
p17' = sum . map (length . filter(`notElem` ", -") . itoa) | |
itoa i | |
| i < 0 = "minus " ++ itoa (-i) | |
| i < 20 = smalls i | |
| i < 100 = f (quotRem i 10) tens "-" smalls | |
| i < 1000 = f (quotRem i 100) ((++" hundred").smalls) " and " itoa | |
-- | otherwise = error "unsupported range" | |
| otherwise = intercalate ", " $ itoa' i | |
where f (q,0) a _ _ = a q | |
f (q,r) a b c = a q ++ b ++ c r | |
smalls = ((["zero", "one", "two", "three", "four", "five", "six", "seven", | |
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", | |
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"] | |
!!).fromInteger) | |
tens = (([undefined, undefined, "twenty", "thirty", "forty", "fifty", | |
"sixty", "seventy", "eighty", "ninety"] | |
!!).fromInteger) | |
pref_b = ["m", "b", "tr", "quadr", "quint", "sext", "sept", "oct", "non", "dec"] | |
bigs = ((("" : " thousand" : map f pref_b) !!).fromInteger) | |
where f s = " "++s++"illion" | |
itoa' = map f . reverse . filter ((0/=).snd) . zip [0..] . triplize | |
where f (n,i) = itoa i ++ bigs n | |
triplize = unfoldr (\i -> if i==0 then Nothing else Just $ f i) | |
where f = uncurry (flip (,)) . flip quotRem 1000 | |
{- | |
*Main> itoa 123456789012345678901234567890123456 | |
"one hundred and twenty-three decillion, four hundred and fifty-six nonillion, seven hundred and eighty-nine octillion, twelve septillion, three hundred and forty-five sextillion, six hundred and seventy-eight quintillion, nine hundred and one quadrillion, two hundred and thirty-four trillion, five hundred and sixty-seven billion, eight hundred and ninety million, one hundred and twenty-three thousand, four hundred and fifty-six" | |
(0.01 secs, 1613288 bytes) | |
-} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.List (intercalate, unfoldr) | |
main = print $ p17' [1..123456789012345678901234567890123456] | |
p17 = p17' [1..1000] | |
p17' = sum . map itoa2 | |
_and_ = 3 | |
_minus_ = 5 | |
_hundred_ = 7 | |
itoa2 i | |
| i < 0 = _minus_ + itoa2 (-i) | |
| i < 20 = smalls' i | |
| i < 100 = f (quotRem i 10) tens' 0 smalls' | |
| i < 1000 = f (quotRem i 100) ((_hundred_+).smalls') _and_ itoa2 | |
-- | otherwise = error "unsupported range" | |
| otherwise = sum $ itoa2' i | |
where f (q,0) a _ _ = a q | |
f (q,r) a b c = a q + b + c r | |
smalls = ["zero", "one", "two", "three", "four", "five", "six", "seven", | |
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", | |
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"] | |
smalls'= (xs!!) . fromInteger where xs = map length smalls | |
tens = ["", "", "twenty", "thirty", "forty", "fifty", | |
"sixty", "seventy", "eighty", "ninety"] | |
tens' = (xs!!) . fromInteger where xs = map length tens | |
bigs = ["", "thousand", "million", "billion", "trillion", "quadrillion", | |
"quintillion", "sextillion", "septillion", "octillion", "nonillion", | |
"decillion"] | |
bigs' = (xs!!) . fromInteger where xs = map length bigs | |
itoa2' = map f . filter ((0/=).snd) . zip [0..] . triplize | |
where f (n,i) = itoa2 i + bigs' n | |
triplize = unfoldr (\i -> if i==0 then Nothing else Just $ f i) | |
where f = uncurry (flip (,)) . flip quotRem 1000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment