How to resolve the algorithm Knuth's power tree step by step in the Go programming language
How to resolve the algorithm Knuth's power tree step by step in the Go 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 Go programming language
This Go code implements an algorithm that computes the powers of a number using a divide-and-conquer approach and a binary tree data structure. Let's break down the code step by step:
-
Global Variables:
p
is a map that tracks the parent of each node in the binary tree, where the key is the node and the value is its parent.lvl
is a slice of slices that represents the levels of the binary tree, with each inner slice representing the nodes at a particular level. Initially, it contains only the root node 1 in the first level.
-
path
Function:- This function takes an integer
n
as input and returns the path from the root node ton
in the tree. - It starts by checking if
n
is 0, in which case it returns an empty slice. - It then iterates until it finds the path to
n
. If the path is not yet known (i.e.,n
does not exist in the tree), it calculates the next level of the tree by adding all possible combinations of sums of nodes in the current level. - The function adds these new nodes to the tree (map
p
and slicelvl
) and continues the search forn
until it finds it. - Finally, it returns the path to
n
in the tree.
- This function takes an integer
-
treePow
Function:- This function takes a float64
x
and an integern
as input and returns the result ofx
raised to the power ofn
using the divide-and-conquer approach and the binary tree. - It initializes a map
r
that stores the powers for each node in the tree. - It calculates the path from the root node to
n
in the tree and iteratively multiplies the powers of the nodes along the path to computex
raised to the power ofn
. - Finally, it returns the result as a
big.Float
object.
- This function takes a float64
-
showPow
Function:- This function takes a float64
x
, an integern
, and a booleanisIntegral
as input and prints the result ofx
raised to the power ofn
. - It prints the path from the root node to
n
in the tree. - It prints
x
andn
in a formatted string and then prints the result returned by thetreePow
function.
- This function takes a float64
-
main
Function:- This is the entry point of the program.
- It iterates through
n
values from 0 to 17 and calls theshowPow
function to print the powers of 2 raised ton
as integers. - It then calls
showPow
for 1.1 raised to the power of 81 and 3 raised to the power of 191, printing the results as floating-point numbers.
Source code in the go programming language
package main
import (
"fmt"
"math/big"
)
var (
p = map[int]int{1: 0}
lvl = [][]int{[]int{1}}
)
func path(n int) []int {
if n == 0 {
return []int{}
}
for {
if _, ok := p[n]; ok {
break
}
var q []int
for _, x := range lvl[0] {
for _, y := range path(x) {
z := x + y
if _, ok := p[z]; ok {
break
}
p[z] = x
q = append(q, z)
}
}
lvl[0] = q
}
r := path(p[n])
r = append(r, n)
return r
}
func treePow(x float64, n int) *big.Float {
r := map[int]*big.Float{0: big.NewFloat(1), 1: big.NewFloat(x)}
p := 0
for _, i := range path(n) {
temp := new(big.Float).SetPrec(320)
temp.Mul(r[i-p], r[p])
r[i] = temp
p = i
}
return r[n]
}
func showPow(x float64, n int, isIntegral bool) {
fmt.Printf("%d: %v\n", n, path(n))
f := "%f"
if isIntegral {
f = "%.0f"
}
fmt.Printf(f, x)
fmt.Printf(" ^ %d = ", n)
fmt.Printf(f+"\n\n", treePow(x, n))
}
func main() {
for n := 0; n <= 17; n++ {
showPow(2, n, true)
}
showPow(1.1, 81, false)
showPow(3, 191, true)
}
You may also check:How to resolve the algorithm Sort a list of object identifiers step by step in the AWK programming language
You may also check:How to resolve the algorithm I before E except after C step by step in the D programming language
You may also check:How to resolve the algorithm Loops/Infinite step by step in the Run BASIC programming language
You may also check:How to resolve the algorithm Knight's tour step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Sorting algorithms/Cocktail sort step by step in the IS-BASIC programming language