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

Published on 12 May 2024 09:40 PM
#Go

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:

  1. 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.
  2. path Function:

    • This function takes an integer n as input and returns the path from the root node to n 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 slice lvl) and continues the search for n until it finds it.
    • Finally, it returns the path to n in the tree.
  3. treePow Function:

    • This function takes a float64 x and an integer n as input and returns the result of x raised to the power of n 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 compute x raised to the power of n.
    • Finally, it returns the result as a big.Float object.
  4. showPow Function:

    • This function takes a float64 x, an integer n, and a boolean isIntegral as input and prints the result of x raised to the power of n.
    • It prints the path from the root node to n in the tree.
    • It prints x and n in a formatted string and then prints the result returned by the treePow function.
  5. main Function:

    • This is the entry point of the program.
    • It iterates through n values from 0 to 17 and calls the showPow function to print the powers of 2 raised to n 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