How to resolve the algorithm Knuth's power tree step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Knuth's power tree step by step in the Haskell programming language

Table of Contents

Problem Statement

(Knuth's power tree is used for computing   xn   efficiently.)

Compute and show the list of Knuth's power tree integers necessary for the computation of:

Then, using those integers, calculate and show the exact values of (at least) the integer powers below:

A  zero  power is often handled separately as a special case. Optionally, support negative integer powers.

An example of a small power tree for some low integers: Where, for the power   43,   following the tree "downwards" from   1: Note that for every even integer (in the power tree),   one just squares the previous value. For an odd integer, multiply the previous value with an appropriate odd power of   X   (which was previously calculated).   For the last multiplication in the above example, it would be   (43-40),   or   3. According to Dr. Knuth (see below),   computer tests have shown that this power tree gives optimum results for all of the   n   listed above in the graph. For   n   ≤ 100,000,   the power tree method:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Knuth's power tree step by step in the Haskell programming language

The code you provided implements two functions: powerTree and power in Haskell.

The powerTree function generates a list of all the powers of 2 up to a given number. The function takes a single argument, n, and returns a list of all the powers of 2 up to n.

The power function computes the power of a given number. The function takes three arguments: a, n, and m. a is the base of the power, n is the exponent, and m is a map of powers to their values. The function returns the value of a raised to the power of n.

The powerTree function is implemented using the levels function, which generates a list of maps of powers to their values. The levels function takes no arguments and returns a list of maps. Each map in the list represents a level of the power tree, with the keys of the map representing the powers of 2 and the values of the map representing the values of the powers.

The powerTree function then iterates over the list of maps, looking up the value of n in each map. If the value of n is found in the map, the function returns a list of all the powers of 2 up to n. Otherwise, the function continues iterating over the list of maps until it reaches the end of the list. If the end of the list is reached, the function returns an empty list.

The power function is implemented using the go function, which recursively computes the power of a given number. The go function takes four arguments: a, k, m, and ls. a is the base of the power, k is the exponent, m is a map of powers to their values, and ls is a list of powers of 2. The function returns the value of a raised to the power of n.

The go function first checks if the list of powers of 2 is empty. If the list is empty, the function returns a. Otherwise, the function looks up the value of the first power of 2 in ls in the map m. If the value is found in the map, the function multiplies a by the value and updates the map m to include the new value. The function then calls itself recursively with the updated a, k, m, and ls.

The power function calls the go function with a, n, m, and the tail of the list of powers of 2 returned by the powerTree function. The go function then computes the value of a raised to the power of n and returns the result.

Source code in the haskell programming language

{-# LANGUAGE ScopedTypeVariables #-}

module Rosetta.PowerTree
    ( Natural
    , powerTree
    , power
    )  where

import           Data.Foldable (toList)
import           Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import           Data.Maybe (fromMaybe)
import           Data.List (foldl')
import           Data.Sequence (Seq (..), (|>))
import qualified Data.Sequence as Seq
import           Numeric.Natural (Natural)

type M = Map Natural S
type S = Seq Natural

levels :: [M]
levels = let s = Seq.singleton 1 in fst <$> iterate step (Map.singleton 1 s, s)

step :: (M, S) -> (M, S)
step (m, xs) = foldl' f (m, Empty) xs
  where
    f :: (M, S) -> Natural -> (M, S)
    f (m', ys) n = foldl' g (m', ys) ns
      where
        ns :: S
        ns = m' Map.! n

        g :: (M, S) -> Natural -> (M, S)
        g (m'', zs) k =
            let l = n + k
            in  case Map.lookup l m'' of
                    Nothing -> (Map.insert l (ns |>  l) m'', zs |> l)
                    Just _  -> (m'', zs)

powerTree :: Natural -> [Natural]
powerTree n
    | n <= 0    = []
    | otherwise = go levels
  where
    go :: [M] -> [Natural]
    go []       = error "impossible branch"
    go (m : ms) = fromMaybe (go ms) $ toList <$> Map.lookup n m

power :: forall a. Num a => a -> Natural -> a
power _ 0 = 1
power a n = go a 1 (Map.singleton 1 a) $ tail $ powerTree n
  where
    go :: a -> Natural -> Map Natural a -> [Natural] -> a
    go b _ _ []       = b
    go b k m (l : ls) =
        let b' = b * m Map.! (l - k)
            m' = Map.insert l b' m
        in  go b' l m' ls


  

You may also check:How to resolve the algorithm S-expressions step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Arrays step by step in the Quackery programming language
You may also check:How to resolve the algorithm Loops/Increment loop index within loop body step by step in the EasyLang programming language
You may also check:How to resolve the algorithm Number reversal game step by step in the M2000 Interpreter programming language
You may also check:How to resolve the algorithm Formatted numeric output step by step in the Standard ML programming language