Still thinking a bit about how to churn out those palindromes in order, or at least take advantage of what order there is. If you take a look at justOnes, it may be that each of the k values gives a hunk in ascending order, so you may be able to foldl' merge [] them and get them in order for cheaper... (UPDATE: no such luck) though that may not actually be cheaper than a single O(n log n) sort.
But now we take another peek at the output. The slowness of piecing together Strings to generate output has been noticed... oh, yes, it has been noticed... and people have come up with a way to cut down on it: using shows or something like it.
shows returns a function that takes a String as parameter and returns a String--the returned String is a printable representation of the thing (which must be in the ShowS type class) with the String parameter appended at the end. Instead of generating the String, you create a function that will generate it when called.
So.. remember
format :: (Int, Int) -> String
format (lineNum, result) = "Case #" ++ show lineNum ++ ": " ++ show result
? Well, now we have
showsResult :: (Int, Int) -> String -> String
showsResult (c, n) = ("Case #" ++) . shows c . (": " ++) . shows n
The use of "sections" makes the correspondence clear. Since we're now passing along functions instead of strings, they're used a little differently:
main = do
s <- B.getContents
let r = map format $ zip [1..] (map process (tail $ B.lines s))
putStr (unlines r)
becomes
main = do
s <- B.getContents
let r = map showsResult $ zip [1..] (map process (tail $ B.lines s))
mapM putStr $ map ($ "\n") r
Now, putStr, if you look it up, has the type String -> IO (), but it has a reassuring name. mapM, though, hints at the dreaded "M" word... monad. [insert dramatic chipmunk sound clip here]. All it is, though, is a monad-flavored map. Before, r was a [String]; now it's a [String -> String]. To get the [String], we use map with a section. (In Haskell, $ is the function application operator. We've used it before; its low priority makes it attractive as a way to avoid parentheses, but here, it's more than a syntactic convenience.) The "\n" means we don't have to use unlines, mapM putStr just runs putStr on each of the Strings on the list.
Does it help? Well... where time output is concerned, it's a wash. The profiler output shows it taking .01 second longer. Ah, but the memory graph! The -hc graph shows the format version somewhere around 7 MB, but the showsResult version at maybe 6.25 MB. That's got to count for something.
random notes and thoughts, mostly about Haskell these days, of a rather past middle-aged programmer
Subscribe to:
Post Comments (Atom)
Riddler Classic, May 23, 2020—Holy Mackerel!
Another one using Peter Norvig's word list . It turns out that the word "mackerel" has a curious property: there is exactly ...
-
Back in the Cretaceous era I worked at the University of Oklahoma as a student assistant at Remote 1. OU was a [shudder] IBM big iron shop a...
-
You've probably heard about how the notion of sum types (e.g. Algol 68 union s, Rust enum s, Haskell type s) and product types (e.g. tup...
-
Verbal Abuse as Entertainment When I grew up, my parents always told me that there was a sort of person who needed to tear down others t...
No comments:
Post a Comment