Knuth's power tree: Difference between revisions

Content added Content deleted
Line 1,100: Line 1,100:
3 ^ 191 = 13494588674281093803728157396523884917402502294030101914066705367021922008906273586058258347
3 ^ 191 = 13494588674281093803728157396523884917402502294030101914066705367021922008906273586058258347
</pre>
</pre>

=={{header|Nim}}==
{{trans|Kotlin}}
{{libheader|bignum}}
This is a translation of the Kotlin/Python program. The algorithm is the same but there are some changes: replacement of global variables by a tree object, use of longer names, replacement of the "lvl" list of lists by a simple list, use of generics to handle the case of big integers...

<lang Nim>import tables
import bignum

type

Id = Natural # Node identifier (= exponent value).

Tree = object
parents: Table[Id, Id] # Mapping node id -> parent node id.
lastLevel: seq[Id] # List of node ids in current last level.


func initTree(): Tree =
## Return an initialized tree.
const Root = Id(1)
Tree(parents: {Root: Id(0)}.toTable, lastLevel: @[Root])


func path(tree: var Tree; id: Id): seq[Id] =
## Return the path to node with given id.

if id == 0: return

while id notin tree.parents:
# Node "id" not yet present in the tree: build a new level.
var newLevel: seq[Id]
for x in tree.lastLevel:
for y in tree.path(x):
let newId = x + y
if newId in tree.parents: break # Node already created.
# Create a new node.
tree.parents[newId] = x
newLevel.add newId
tree.lastLevel = move(newLevel)

# Node path is the concatenation of parent node path and node id.
result = tree.path(tree.parents[id]) & id


func treePow[T: SomeNumber | Int](tree: var Tree; x: T; n: Natural): T =
## Compute x^n using the power tree.
let one = when T is Int: newInt(1) else: T(1)
var results = {0: one, 1: x}.toTable # Intermediate and last results.
var k = 0
for i in tree.path(n):
results[i] = results[i - k] * results[k]
k = i
return results[n]


proc showPow[T: SomeNumber | Int](tree: var Tree; x: T; n: Natural) =
echo n, " → ", ($tree.path(n))[1..^1]
let result = tree.treePow(x, n)
echo x, "^", n, " = ", result


when isMainModule:

var tree = initTree()
for n in 0..17: tree.showPow(2, n)
echo ""
tree.showPow(1.1, 81)
echo ""
tree.showPow(newInt(3), 191)</lang>

{{out}}
<pre>0 → []
2^0 = 1
1 → [1]
2^1 = 2
2 → [1, 2]
2^2 = 4
3 → [1, 2, 3]
2^3 = 8
4 → [1, 2, 4]
2^4 = 16
5 → [1, 2, 4, 5]
2^5 = 32
6 → [1, 2, 4, 6]
2^6 = 64
7 → [1, 2, 4, 6, 7]
2^7 = 128
8 → [1, 2, 4, 8]
2^8 = 256
9 → [1, 2, 4, 8, 9]
2^9 = 512
10 → [1, 2, 4, 8, 10]
2^10 = 1024
11 → [1, 2, 4, 8, 10, 11]
2^11 = 2048
12 → [1, 2, 4, 8, 12]
2^12 = 4096
13 → [1, 2, 4, 8, 12, 13]
2^13 = 8192
14 → [1, 2, 4, 8, 12, 14]
2^14 = 16384
15 → [1, 2, 4, 8, 12, 14, 15]
2^15 = 32768
16 → [1, 2, 4, 8, 16]
2^16 = 65536
17 → [1, 2, 4, 8, 16, 17]
2^17 = 131072

81 → [1, 2, 4, 8, 16, 32, 64, 80, 81]
1.1^81 = 2253.240236044025

191 → [1, 2, 4, 8, 16, 32, 64, 128, 160, 176, 184, 188, 190, 191]
3^191 = 13494588674281093803728157396523884917402502294030101914066705367021922008906273586058258347</pre>


=={{header|Perl}}==
=={{header|Perl}}==