Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 910271
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T17:00:58+00:00 2026-05-15T17:00:58+00:00

Any pointers on how to solve efficiently the following function in Haskell, for large

  • 0

Any pointers on how to solve efficiently the following function in Haskell, for large numbers (n > 108)

f(n) = max(n, f(n/2) + f(n/3) + f(n/4))

I’ve seen examples of memoization in Haskell to solve fibonacci
numbers, which involved computing (lazily) all the fibonacci numbers
up to the required n. But in this case, for a given n, we only need to
compute very few intermediate results.

Thanks

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T17:00:59+00:00Added an answer on May 15, 2026 at 5:00 pm

    We can do this very efficiently by making a structure that we can index in sub-linear time.

    But first,

    {-# LANGUAGE BangPatterns #-}
    
    import Data.Function (fix)
    

    Let’s define f, but make it use ‘open recursion’ rather than call itself directly.

    f :: (Int -> Int) -> Int -> Int
    f mf 0 = 0
    f mf n = max n $ mf (n `div` 2) +
                     mf (n `div` 3) +
                     mf (n `div` 4)
    

    You can get an unmemoized f by using fix f

    This will let you test that f does what you mean for small values of f by calling, for example: fix f 123 = 144

    We could memoize this by defining:

    f_list :: [Int]
    f_list = map (f faster_f) [0..]
    
    faster_f :: Int -> Int
    faster_f n = f_list !! n
    

    That performs passably well, and replaces what was going to take O(n^3) time with something that memoizes the intermediate results.

    But it still takes linear time just to index to find the memoized answer for mf. This means that results like:

    *Main Data.List> faster_f 123801
    248604
    

    are tolerable, but the result doesn’t scale much better than that. We can do better!

    First, let’s define an infinite tree:

    data Tree a = Tree (Tree a) a (Tree a)
    instance Functor Tree where
        fmap f (Tree l m r) = Tree (fmap f l) (f m) (fmap f r)
    

    And then we’ll define a way to index into it, so we can find a node with index n in O(log n) time instead:

    index :: Tree a -> Int -> a
    index (Tree _ m _) 0 = m
    index (Tree l _ r) n = case (n - 1) `divMod` 2 of
        (q,0) -> index l q
        (q,1) -> index r q
    

    … and we may find a tree full of natural numbers to be convenient so we don’t have to fiddle around with those indices:

    nats :: Tree Int
    nats = go 0 1
        where
            go !n !s = Tree (go l s') n (go r s')
                where
                    l = n + s
                    r = l + s
                    s' = s * 2
    

    Since we can index, you can just convert a tree into a list:

    toList :: Tree a -> [a]
    toList as = map (index as) [0..]
    

    You can check the work so far by verifying that toList nats gives you [0..]

    Now,

    f_tree :: Tree Int
    f_tree = fmap (f fastest_f) nats
    
    fastest_f :: Int -> Int
    fastest_f = index f_tree
    

    works just like with list above, but instead of taking linear time to find each node, can chase it down in logarithmic time.

    The result is considerably faster:

    *Main> fastest_f 12380192300
    67652175206
    
    *Main> fastest_f 12793129379123
    120695231674999
    

    In fact it is so much faster that you can go through and replace Int with Integer above and get ridiculously large answers almost instantaneously

    *Main> fastest_f' 1230891823091823018203123
    93721573993600178112200489
    
    *Main> fastest_f' 12308918230918230182031231231293810923
    11097012733777002208302545289166620866358
    

    For an out-of-the-box library that implements the tree based memoization, use MemoTrie:

    $ stack repl --package MemoTrie
    
    Prelude> import Data.MemoTrie
    Prelude Data.MemoTrie> :set -XLambdaCase
    Prelude Data.MemoTrie> :{
    Prelude Data.MemoTrie| fastest_f' :: Integer -> Integer
    Prelude Data.MemoTrie| fastest_f' = memo $ \case
    Prelude Data.MemoTrie|   0 -> 0
    Prelude Data.MemoTrie|   n -> max n (fastest_f'(n `div` 2) + fastest_f'(n `div` 3) + fastest_f'(n `div` 4))
    Prelude Data.MemoTrie| :}
    Prelude Data.MemoTrie> fastest_f' 12308918230918230182031231231293810923
    11097012733777002208302545289166620866358
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Can anyone give me any pointers. I have a text file that contains dates
Does anyone have any pointers to good resources concerning mesh networks? Maybe I'm not
I'm looking for any pointers on how to write a rails web app without
Coming from a C# Background I never used any pointers. I'm creating a vector
I'm new to postgreSQL, so would really appreciate any pointers from the community. I
When should I choose one over the other? Are there any pointers that you
I'm a DB2 newbie, so I'd appreciate even any pointers on where to start
I am using boost::any to store pointers and was wondering if there was a
Any reasons why this can not be standard behavior of free() ? multiple pointers
Does anyone have any good samples, resources, pointers etc. for C# Silverlight with RIA

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.