Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Knuths-power-tree/00-META.yaml
Normal file
3
Task/Knuths-power-tree/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Knuth's_power_tree
|
||||
note: Knuth's power tree
|
||||
78
Task/Knuths-power-tree/00-TASK.txt
Normal file
78
Task/Knuths-power-tree/00-TASK.txt
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
(Knuth's power tree is used for computing <big><big>x<sup>n</sup></big></big> efficiently.)<br>
|
||||
|
||||
|
||||
;Task:
|
||||
Compute and show the list of Knuth's power tree integers necessary for the computation of:
|
||||
|
||||
::* <big><big>x<sup>n</sup></big></big> for any real <big><big>x</big></big> and any non-negative integer <big>n</big>.
|
||||
|
||||
|
||||
|
||||
Then, using those integers, calculate and show the exact values of (at least) the integer powers below:
|
||||
|
||||
::* <big>2<sup>n</sup></big> where n ranges from 0 ──► 17 (inclusive) <br>
|
||||
::* <big>3<sup>191</sup></big>
|
||||
::* <big>1.1<sup>81</sup></big>
|
||||
|
||||
|
||||
A ''zero'' power is often handled separately as a special case.
|
||||
|
||||
Optionally, support negative integer powers.
|
||||
|
||||
|
||||
;Example:
|
||||
An example of a small power tree for some low integers:
|
||||
<pre>
|
||||
1
|
||||
\
|
||||
2
|
||||
___________________________________________/ \
|
||||
/ \
|
||||
3 4
|
||||
/ \____________________________________ \
|
||||
/ \ \
|
||||
5 6 8
|
||||
/ \____________ / \ \
|
||||
/ \ / \ \
|
||||
7 10 9 12 16
|
||||
/ //\\ │ │ /\
|
||||
/ _____// \\________ │ │ / \
|
||||
14 / / \ \ │ │ / \
|
||||
/│ \ 11 13 15 20 18 24 17 32
|
||||
/ │ \ │ /\ /\ │ /\ │ /\ │
|
||||
/ │ \ │ / \ / \ │ / \ │ / \ │
|
||||
19 21 28 22 23 26 25 30 40 27 36 48 33 34 64
|
||||
│ /\ /│\ │ │ /\ │ /\ /│\ │ /\ /│\ │ │ /\
|
||||
│ / \ / │ \ │ │ / \ │ / \ / │ \ │ / \ / │ \ │ │ / \
|
||||
38 35 42 29 31 56 44 46 39 52 50 45 60 41 43 80 54 37 72 49 51 96 66 68 65 128
|
||||
</pre>
|
||||
Where, for the power <big>43</big>, following the tree "downwards" from <big>1</big>:
|
||||
::* (for 2) compute square of <big>X</big>, store <big>X<sup>2</sup></big>
|
||||
::* (for 3) compute <big>X</big> * <big>X<sup>2</sup></big>, store <big>X<sup>3</sup></big>
|
||||
::* (for 5) compute <big>X<sup>3</sup></big> * <big>X<sup>2</sup></big>, store <big>X<sup>5</sup></big>
|
||||
::* (for 10) compute square of <big>X<sup>5</sup></big>, store <big>X<sup>10</sup></big>
|
||||
::* (for 20) compute square of <big>X<sup>10</sup></big>, store <big>X<sup>20</sup></big>
|
||||
::* (for 40) compute square of <big>X<sup>20</sup></big>, store <big>X<sup>40</sup></big>
|
||||
::* (for 43) compute <big>X<sup>40</sup></big> * <big>X<sup>3</sup></big> (result).
|
||||
|
||||
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 <big>X</big> (which was previously calculated).
|
||||
For the last multiplication in the above example, it would be <big>(43-40)</big>, or <big>3</big>. <br>
|
||||
|
||||
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:
|
||||
::* bests the factor method 88,803 times,
|
||||
::* ties 11,191 times,
|
||||
::* loses 6 times.
|
||||
|
||||
<br>
|
||||
;References:
|
||||
::* Donald E. Knuth's book: ''The Art of Computer Programming, Vol. 2'', Second Edition, Seminumerical Algorithms, section 4.6.3: Evaluation of Powers.
|
||||
::* link [http://codegolf.stackexchange.com/questions/3177/knuths-power-tree codegolf.stackexchange.com/questions/3177/knuths-power-tree] It shows a '''Haskell''', '''Python''', and a '''Ruby''' computer program example (but they are mostly ''code golf'').
|
||||
::* link [https://comeoncodeon.wordpress.com/tag/knuth/ comeoncodeon.wordpress.com/tag/knuth/] (See the section on Knuth's Power Tree.) It shows a '''C++''' computer program example.
|
||||
::* link to Rosetta Code [http://rosettacode.org/wiki/Addition-chain_exponentiation addition-chain exponentiation].
|
||||
<br><br>
|
||||
|
||||
35
Task/Knuths-power-tree/11l/knuths-power-tree.11l
Normal file
35
Task/Knuths-power-tree/11l/knuths-power-tree.11l
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
V p = [1 = 0]
|
||||
V lvl = [[1]]
|
||||
|
||||
F path(n)
|
||||
I !n
|
||||
R [Int]()
|
||||
L n !C :p
|
||||
[Int] q
|
||||
L(x) :lvl[0]
|
||||
L(y) path(x)
|
||||
I !(x + y C :p)
|
||||
:p[x + y] = x
|
||||
q.append(x + y)
|
||||
:lvl[0] = q
|
||||
|
||||
R path(:p[n]) [+] [n]
|
||||
|
||||
F tree_pow(x, n)
|
||||
T Ty = T(x)
|
||||
V (r, p) = ([0 = Ty(1), 1 = x], 0)
|
||||
L(i) path(n)
|
||||
r[i] = r[i - p] * r[p]
|
||||
p = i
|
||||
R r[n]
|
||||
|
||||
F show_pow_i(x, n)
|
||||
print("#.: #.\n#.^#. = #.\n".format(n, path(n), x, n, tree_pow(BigInt(x), n)))
|
||||
|
||||
F show_pow_f(x, n)
|
||||
print("#.: #.\n#.^#. = #.6\n".format(n, path(n), x, n, tree_pow(x, n)))
|
||||
|
||||
L(x) 18
|
||||
show_pow_i(2, x)
|
||||
show_pow_i(3, 191)
|
||||
show_pow_f(1.1, 81)
|
||||
116
Task/Knuths-power-tree/Ada/knuths-power-tree.ada
Normal file
116
Task/Knuths-power-tree/Ada/knuths-power-tree.ada
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
with Ada.Containers.Ordered_Maps;
|
||||
with Ada.Numerics.Big_Numbers.Big_Integers;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Power_Tree is
|
||||
|
||||
Debug_On : constant Boolean := False;
|
||||
|
||||
generic
|
||||
type Result_Type is private;
|
||||
Base : Result_Type;
|
||||
Identity : Result_Type;
|
||||
with function "*" (Left, Right : Result_Type) return Result_Type is <>;
|
||||
package Knuth_Power_Tree is
|
||||
subtype Exponent is Natural;
|
||||
|
||||
function Power (Exp : Exponent) return Result_Type;
|
||||
end Knuth_Power_Tree;
|
||||
|
||||
package body Knuth_Power_Tree is
|
||||
|
||||
package Power_Trees is
|
||||
new Ada.Containers.Ordered_Maps (Key_Type => Exponent,
|
||||
Element_Type => Result_Type);
|
||||
Tree : Power_Trees.Map;
|
||||
|
||||
procedure Debug (Item : String) is
|
||||
begin
|
||||
if Debug_On then
|
||||
Put_Line (Standard_Error, Item);
|
||||
end if;
|
||||
end Debug;
|
||||
|
||||
function Power (Exp : Exponent) return Result_Type is
|
||||
Pow : Result_Type;
|
||||
begin
|
||||
if Tree.Contains (Exp) then
|
||||
return Tree.Element (Exp);
|
||||
else
|
||||
Debug ("lookup failed of " & Exp'Image);
|
||||
end if;
|
||||
|
||||
if Exp mod 2 = 0 then
|
||||
Debug ("lookup half " & Exponent'(Exp / 2)'Image);
|
||||
Pow := Power (Exp / 2);
|
||||
Pow := Pow * Pow;
|
||||
else
|
||||
Debug ("lookup one less " & Exponent'(Exp - 1)'Image);
|
||||
Pow := Power (Exp - 1);
|
||||
Pow := Result_Type (Base) * Pow;
|
||||
end if;
|
||||
Debug ("insert " & Exp'Image);
|
||||
Tree.Insert (Key => Exp, New_Item => Pow);
|
||||
return Pow;
|
||||
end Power;
|
||||
|
||||
begin
|
||||
Tree.Insert (Key => 0, New_Item => Identity);
|
||||
end Knuth_Power_Tree;
|
||||
|
||||
|
||||
procedure Part_1
|
||||
is
|
||||
package Power_2 is new Knuth_Power_Tree (Result_Type => Long_Integer,
|
||||
Base => 2,
|
||||
Identity => 1);
|
||||
R : Long_Integer;
|
||||
begin
|
||||
Put_Line ("=== Part 1 ===");
|
||||
for N in 0 .. 25 loop
|
||||
R := Power_2.Power (N);
|
||||
Put ("2 **"); Put (N'Image);
|
||||
Put (" ="); Put (R'Image);
|
||||
New_Line;
|
||||
end loop;
|
||||
end Part_1;
|
||||
|
||||
procedure Part_2
|
||||
is
|
||||
use Ada.Numerics.Big_Numbers.Big_Integers;
|
||||
|
||||
package Power_3 is new Knuth_Power_Tree (Result_Type => Big_Integer,
|
||||
Base => 3,
|
||||
Identity => 1);
|
||||
R : Big_Integer;
|
||||
begin
|
||||
Put_Line ("=== Part 2 ===");
|
||||
for E in 190 .. 192 loop
|
||||
R := Power_3.Power (E);
|
||||
Put ("3 **" & E'Image & " ="); Put (R'Image); New_Line;
|
||||
end loop;
|
||||
end Part_2;
|
||||
|
||||
procedure Part_3
|
||||
is
|
||||
subtype Real is Long_Long_Float;
|
||||
package Real_IO is new Ada.Text_IO.Float_IO (Real);
|
||||
package Power_1_1 is new Knuth_Power_Tree (Result_Type => Real,
|
||||
Base => 1.1,
|
||||
Identity => 1.0);
|
||||
R : Real;
|
||||
begin
|
||||
Put_Line ("=== Part 3 ===");
|
||||
for E in 81 .. 84 loop
|
||||
R := Power_1_1.Power (E);
|
||||
Put ("1.1 **" & E'Image & " = ");
|
||||
Real_IO.Put (R, Exp => 0, Aft => 6);
|
||||
New_Line;
|
||||
end loop;
|
||||
end Part_3;
|
||||
|
||||
begin
|
||||
Part_1;
|
||||
Part_2;
|
||||
Part_3;
|
||||
end Power_Tree;
|
||||
40
Task/Knuths-power-tree/EchoLisp/knuths-power-tree-1.l
Normal file
40
Task/Knuths-power-tree/EchoLisp/knuths-power-tree-1.l
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
(lib 'tree)
|
||||
|
||||
;; displays a chain hit
|
||||
(define (power-hit target chain)
|
||||
(vector-push chain target)
|
||||
(printf "L(%d) = %d - chain:%a "
|
||||
target (1- (vector-length chain)) chain)
|
||||
(vector-pop chain))
|
||||
|
||||
;; build the power-tree : add 1 level of leaf nodes
|
||||
;; display all chains which lead to target
|
||||
|
||||
(define (add-level node chain target nums (new))
|
||||
(vector-push chain (node-datum node))
|
||||
(cond
|
||||
[(node-leaf? node)
|
||||
;; add leaves by summing this node to all nodes in chain
|
||||
;; do not add leaf if number already known
|
||||
(for [(prev chain)]
|
||||
(set! new (+ prev (node-datum node)))
|
||||
(when (= new target) (power-hit target chain ))
|
||||
#:continue (vector-search* new nums)
|
||||
(node-add-leaf node new)
|
||||
(vector-insert* nums new)
|
||||
)]
|
||||
[else ;; not leaf node -> recurse
|
||||
(for [(son (node-sons node))]
|
||||
(add-level son chain target nums )) ])
|
||||
(vector-pop chain))
|
||||
|
||||
;; add levels in tree until target found
|
||||
;; return (number of nodes . upper-bound for L(target))
|
||||
(define (power-tree target)
|
||||
(define nums (make-vector 1 1)) ;; known nums = 1
|
||||
(define T (make-tree 1)) ;; root node has value 1
|
||||
(printf "Looking for %d in %a." target T)
|
||||
(while #t
|
||||
#:break (vector-search* target nums) => (tree-count T)
|
||||
(add-level T init-chain: (make-vector 0) target nums)
|
||||
))
|
||||
11
Task/Knuths-power-tree/EchoLisp/knuths-power-tree-2.l
Normal file
11
Task/Knuths-power-tree/EchoLisp/knuths-power-tree-2.l
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
;; j such as chain[i] = chain[i-1] + chain[j]
|
||||
(define (adder chain i)
|
||||
(for ((j i)) #:break (= [chain i] (+ [chain(1- i)] [chain j])) => j ))
|
||||
|
||||
|
||||
(define (power-exp x chain)
|
||||
(define lg (vector-length chain))
|
||||
(define pow (make-vector lg x))
|
||||
(for ((i (in-range 1 lg)))
|
||||
(vector-set! pow i ( * [pow [1- i]] [pow (adder chain i)])))
|
||||
[pow (1- lg)])
|
||||
15
Task/Knuths-power-tree/F-Sharp/knuths-power-tree-1.fs
Normal file
15
Task/Knuths-power-tree/F-Sharp/knuths-power-tree-1.fs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Integer exponentiation using Knuth power tree. Nigel Galloway: October 29th., 2020
|
||||
let kT α=let n=Array.zeroCreate<int*int list>((pown 2 (α+1))+1)
|
||||
let fN g=let rec fN p=[yield g+p; if p>0 then let g,_=n.[p] in yield! fN g] in (g+g)::(fN (fst n.[g]))|>List.rev
|
||||
let fG g=[for α,β in g do for g in β do let p,_=n.[g] in n.[g]<-(p,fN g|>List.filter(fun β->if box n.[β]=null then n.[β]<-(g,[]); true else false)); yield n.[g]]
|
||||
let rec kT n g=match g with 0->() |_->let n=fG n in kT n (g-1)
|
||||
let fE X g=let α=let rec fE g=[|yield g; if g>1 then yield! fE (fst n.[g])|] in fE g
|
||||
let β=Array.zeroCreate<bigint>α.Length
|
||||
let l=β.Length-1
|
||||
β.[l]<-bigint (X+0)
|
||||
for e in l-1.. -1..0 do β.[e]<-match α.[e]%2 with 0->β.[e+1]*β.[e+1] |_->let l=α.[e+1] in β.[e+1]*β.[α|>Array.findIndex(fun n->l+n=α.[e])]
|
||||
β.[0]
|
||||
n.[1]<-(0,[2]); n.[2]<-(1,[]); kT [n.[1]] α; (fun n g->if g=0 then 1I else fE n g)
|
||||
let xp=kT 11
|
||||
[0..17]|>List.iter(fun n->printfn "2**%d=%A\n" n (xp 2 n))
|
||||
printfn "3**191=%A" (xp 3 191)
|
||||
15
Task/Knuths-power-tree/F-Sharp/knuths-power-tree-2.fs
Normal file
15
Task/Knuths-power-tree/F-Sharp/knuths-power-tree-2.fs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Float exponentiation using Knuth power tree. Nigel Galloway: October 29th., 2020
|
||||
let kTf α=let n=Array.zeroCreate<int*int list>((pown 2 (α+1))+1)
|
||||
let fN g=let rec fN p=[yield g+p; if p>0 then let g,_=n.[p] in yield! fN g] in (g+g)::(fN (fst n.[g]))|>List.rev
|
||||
let fG g=[for α,β in g do for g in β do let p,_=n.[g] in n.[g]<-(p,fN g|>List.filter(fun β->if box n.[β]=null then n.[β]<-(g,[]); true else false)); yield n.[g]]
|
||||
let rec kT n g=match g with 0->() |_->let n=fG n in kT n (g-1)
|
||||
let fE X g=let α=let rec fE g=[|yield g; if g>1 then yield! fE (fst n.[g])|] in fE g
|
||||
let β=Array.zeroCreate<float>α.Length
|
||||
let l=β.Length-1
|
||||
β.[l]<-X
|
||||
for e in l-1.. -1..0 do β.[e]<-match α.[e]%2 with 0->β.[e+1]*β.[e+1] |_->let l=α.[e+1] in β.[e+1]*β.[α|>Array.findIndex(fun n->l+n=α.[e])]
|
||||
β.[0]
|
||||
n.[1]<-(0,[2]); n.[2]<-(1,[]); kT [n.[1]] α; (fun n g->if g=0 then 1.0 else fE n g)
|
||||
|
||||
let xpf=kTf 11
|
||||
printfn "1.1**81=%f" (xpf 1.1 81)
|
||||
68
Task/Knuths-power-tree/Go/knuths-power-tree.go
Normal file
68
Task/Knuths-power-tree/Go/knuths-power-tree.go
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
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)
|
||||
}
|
||||
62
Task/Knuths-power-tree/Groovy/knuths-power-tree.groovy
Normal file
62
Task/Knuths-power-tree/Groovy/knuths-power-tree.groovy
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
class PowerTree {
|
||||
private static Map<Integer, Integer> p = new HashMap<>()
|
||||
private static List<List<Integer>> lvl = new ArrayList<>()
|
||||
|
||||
static {
|
||||
p[1] = 0
|
||||
|
||||
List<Integer> temp = new ArrayList<Integer>()
|
||||
temp.add 1
|
||||
lvl.add temp
|
||||
}
|
||||
|
||||
private static List<Integer> path(int n) {
|
||||
if (n == 0) return new ArrayList<Integer>()
|
||||
while (!p.containsKey(n)) {
|
||||
List<Integer> q = new ArrayList<>()
|
||||
for (Integer x in lvl.get(0)) {
|
||||
for (Integer y in path(x)) {
|
||||
if (p.containsKey(x + y)) break
|
||||
p[x + y] = x
|
||||
q.add x + y
|
||||
}
|
||||
}
|
||||
lvl[0].clear()
|
||||
lvl[0].addAll q
|
||||
}
|
||||
List<Integer> temp = path p[n]
|
||||
temp.add n
|
||||
temp
|
||||
}
|
||||
|
||||
private static BigDecimal treePow(double x, int n) {
|
||||
Map<Integer, BigDecimal> r = new HashMap<>()
|
||||
r[0] = BigDecimal.ONE
|
||||
r[1] = BigDecimal.valueOf(x)
|
||||
|
||||
int p = 0
|
||||
for (Integer i in path(n)) {
|
||||
r[i] = r[i - p] * r[p]
|
||||
p = i
|
||||
}
|
||||
r[n]
|
||||
}
|
||||
|
||||
private static void showPos(double x, int n, boolean isIntegral) {
|
||||
printf("%d: %s\n", n, path(n))
|
||||
String f = isIntegral ? "%.0f" : "%f"
|
||||
printf(f, x)
|
||||
printf(" ^ %d = ", n)
|
||||
printf(f, treePow(x, n))
|
||||
println()
|
||||
println()
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
for (int n = 0; n <= 17; ++n) {
|
||||
showPos 2.0, n, true
|
||||
}
|
||||
showPos 1.1, 81, false
|
||||
showPos 3.0, 191, true
|
||||
}
|
||||
}
|
||||
58
Task/Knuths-power-tree/Haskell/knuths-power-tree.hs
Normal file
58
Task/Knuths-power-tree/Haskell/knuths-power-tree.hs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{-# 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
|
||||
28
Task/Knuths-power-tree/J/knuths-power-tree-1.j
Normal file
28
Task/Knuths-power-tree/J/knuths-power-tree-1.j
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
knuth_power_tree=:3 :0
|
||||
L=: P=: %(1+y){._ 1
|
||||
findpath=: ]
|
||||
while. _ e.P do.
|
||||
for_n.(/: findpath&>)I.L=>./L-._ do.
|
||||
for_a. findpath n do.
|
||||
j=. n+a
|
||||
l=. 1+n{L
|
||||
if. j>y do. break. end.
|
||||
if. l>:j{ L do. continue. end.
|
||||
L=: l j} L
|
||||
P=: n j} P
|
||||
end.
|
||||
findpath=: [: |. {&P^:a:
|
||||
end.
|
||||
end.
|
||||
P
|
||||
)
|
||||
|
||||
usepath=:4 :0
|
||||
path=. findpath y
|
||||
exp=. 1,({:path)#x
|
||||
for_ex.(,.~2 -~/\"1])2 ,\path do.
|
||||
'ea eb ec'=. ex
|
||||
exp=.((ea{exp)*eb{exp) ec} exp
|
||||
end.
|
||||
{:exp
|
||||
)
|
||||
102
Task/Knuths-power-tree/J/knuths-power-tree-2.j
Normal file
102
Task/Knuths-power-tree/J/knuths-power-tree-2.j
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
knuth_power_tree 191 NB. generate sufficiently large tree
|
||||
0 1 1 2 2 3 3 5 4 6 5 10 6 10 7 10 8 16 9 14 10 14 11 13 12 15 13 18 14 28 15 28 16 17 17 21 18 36 19 26 20 40 21 40 22 30 23 42 24 48 25 48 26 52 27 44 28 38 29 31 30 56 31 42 32 64 33 66 34 46 35 57 36 37 37 50 38 76 39 76 40 41 41 43 42 80 43 84 44 47 45 70 46 62 47 57 48 49 49 51 50 100 51 100 52 70 53 104 54 104 55 108 56 112 57 112 58 61 59 112 60 120 61 120 62 75 63 126 64 65 65 129 66 67 67 90 68 136 69 138 70 140 71 140 72 144 73 144 74 132 75 138 76 144 77 79 78 152 79 152 80 160 81 160 82 85 83 162 84 168 85 114 86 168 87 105 88 118 89 176 90 176 91 122 92 184 93 176 94 126 95 190
|
||||
|
||||
findpath 0
|
||||
0
|
||||
2 usepath 0
|
||||
1
|
||||
|
||||
findpath 1
|
||||
1
|
||||
2 usepath 1
|
||||
2
|
||||
|
||||
findpath 2
|
||||
1 2
|
||||
2 usepath 2
|
||||
4
|
||||
|
||||
findpath 3
|
||||
1 2 3
|
||||
2 usepath 3
|
||||
8
|
||||
|
||||
findpath 4
|
||||
1 2 4
|
||||
2 usepath 4
|
||||
16
|
||||
|
||||
findpath 5
|
||||
1 2 3 5
|
||||
2 usepath 5
|
||||
32
|
||||
|
||||
findpath 6
|
||||
1 2 3 6
|
||||
2 usepath 6
|
||||
64
|
||||
|
||||
findpath 7
|
||||
1 2 3 5 7
|
||||
2 usepath 7
|
||||
128
|
||||
|
||||
findpath 8
|
||||
1 2 4 8
|
||||
2 usepath 8
|
||||
256
|
||||
|
||||
findpath 9
|
||||
1 2 3 6 9
|
||||
2 usepath 9
|
||||
512
|
||||
|
||||
findpath 10
|
||||
1 2 3 5 10
|
||||
2 usepath 10
|
||||
1024
|
||||
|
||||
findpath 11
|
||||
1 2 3 5 10 11
|
||||
2 usepath 11
|
||||
2048
|
||||
|
||||
findpath 12
|
||||
1 2 3 6 12
|
||||
2 usepath 12
|
||||
4096
|
||||
|
||||
findpath 13
|
||||
1 2 3 5 10 13
|
||||
2 usepath 13
|
||||
8192
|
||||
|
||||
findpath 14
|
||||
1 2 3 5 7 14
|
||||
2 usepath 14
|
||||
16384
|
||||
|
||||
findpath 15
|
||||
1 2 3 5 10 15
|
||||
2 usepath 15
|
||||
32768
|
||||
|
||||
findpath 16
|
||||
1 2 4 8 16
|
||||
2 usepath 16
|
||||
65536
|
||||
|
||||
findpath 17
|
||||
1 2 4 8 16 17
|
||||
2 usepath 17
|
||||
131072
|
||||
|
||||
findpath 191
|
||||
1 2 3 5 7 14 19 38 57 95 190 191
|
||||
3x usepath 191
|
||||
13494588674281093803728157396523884917402502294030101914066705367021922008906273586058258347
|
||||
|
||||
findpath 81
|
||||
1 2 3 5 10 20 40 41 81
|
||||
(x:1.1) usepath 81
|
||||
2253240236044012487937308538033349567966729852481170503814810577345406584190098644811r1000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
2
Task/Knuths-power-tree/J/knuths-power-tree-3.j
Normal file
2
Task/Knuths-power-tree/J/knuths-power-tree-3.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
90j83 ": (x:1.1) usepath 81
|
||||
2253.24023604401248793730853803334956796672985248117050381481057734540658419009864481100
|
||||
67
Task/Knuths-power-tree/Java/knuths-power-tree.java
Normal file
67
Task/Knuths-power-tree/Java/knuths-power-tree.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PowerTree {
|
||||
private static Map<Integer, Integer> p = new HashMap<>();
|
||||
private static List<List<Integer>> lvl = new ArrayList<>();
|
||||
|
||||
static {
|
||||
p.put(1, 0);
|
||||
|
||||
ArrayList<Integer> temp = new ArrayList<>();
|
||||
temp.add(1);
|
||||
lvl.add(temp);
|
||||
}
|
||||
|
||||
private static List<Integer> path(int n) {
|
||||
if (n == 0) return new ArrayList<>();
|
||||
while (!p.containsKey(n)) {
|
||||
List<Integer> q = new ArrayList<>();
|
||||
for (Integer x : lvl.get(0)) {
|
||||
for (Integer y : path(x)) {
|
||||
if (p.containsKey(x + y)) break;
|
||||
p.put(x + y, x);
|
||||
q.add(x + y);
|
||||
}
|
||||
}
|
||||
lvl.get(0).clear();
|
||||
lvl.get(0).addAll(q);
|
||||
}
|
||||
List<Integer> temp = path(p.get(n));
|
||||
temp.add(n);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private static BigDecimal treePow(double x, int n) {
|
||||
Map<Integer, BigDecimal> r = new HashMap<>();
|
||||
r.put(0, BigDecimal.ONE);
|
||||
r.put(1, BigDecimal.valueOf(x));
|
||||
|
||||
int p = 0;
|
||||
for (Integer i : path(n)) {
|
||||
r.put(i, r.get(i - p).multiply(r.get(p)));
|
||||
p = i;
|
||||
}
|
||||
return r.get(n);
|
||||
}
|
||||
|
||||
private static void showPow(double x, int n, boolean isIntegral) {
|
||||
System.out.printf("%d: %s\n", n, path(n));
|
||||
String f = isIntegral ? "%.0f" : "%f";
|
||||
System.out.printf(f, x);
|
||||
System.out.printf(" ^ %d = ", n);
|
||||
System.out.printf(f, treePow(x, n));
|
||||
System.out.println("\n");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int n = 0; n <= 17; ++n) {
|
||||
showPow(2.0, n, true);
|
||||
}
|
||||
showPow(1.1, 81, false);
|
||||
showPow(3.0, 191, true);
|
||||
}
|
||||
}
|
||||
41
Task/Knuths-power-tree/Jq/knuths-power-tree.jq
Normal file
41
Task/Knuths-power-tree/Jq/knuths-power-tree.jq
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Input: {p, lvl, path}
|
||||
def kpath($n):
|
||||
if $n == 0 then .path=[]
|
||||
else until( .p[$n|tostring];
|
||||
.q = []
|
||||
| reduce .lvl[0][] as $x (.;
|
||||
kpath($x)
|
||||
| label $out
|
||||
| foreach (.path[], null) as $y (.;
|
||||
if $y == null then .
|
||||
else (($x + $y)|tostring) as $xy
|
||||
| if .p[$xy] then .
|
||||
else .p[$xy] = $x
|
||||
| .q += [$x + $y]
|
||||
end
|
||||
end;
|
||||
select($y == null) ) )
|
||||
| .lvl[0] = .q )
|
||||
| kpath(.p[$n|tostring])
|
||||
| .path += [$n]
|
||||
end ;
|
||||
|
||||
# Input: as for kpath
|
||||
def treePow($x; $n):
|
||||
reduce kpath($n).path[] as $i (
|
||||
{r: { "0": 1, "1": $x }, pp: 0 };
|
||||
.r[$i|tostring] = .r[($i - .pp)|tostring] * .r[.pp|tostring]
|
||||
| .pp = $i )
|
||||
| .r[$n|tostring] ;
|
||||
|
||||
def showPow($x; $n):
|
||||
{ p: {"1": 0},
|
||||
lvl: [[1]],
|
||||
path: []}
|
||||
| "\($n): \(kpath($n).path)",
|
||||
"\($x) ^ \($n) = \(treePow($x; $n))";
|
||||
|
||||
|
||||
(range(0;18) as $n | showPow(2; $n)),
|
||||
showPow(1.1; 81),
|
||||
showPow(3; 191)
|
||||
32
Task/Knuths-power-tree/Julia/knuths-power-tree-1.julia
Normal file
32
Task/Knuths-power-tree/Julia/knuths-power-tree-1.julia
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
module KnuthPowerTree
|
||||
|
||||
const p = Dict(1 => 0)
|
||||
const lvl = [[1]]
|
||||
|
||||
function path(n)
|
||||
global p, lvl
|
||||
iszero(n) && return Int[]
|
||||
while n ∉ keys(p)
|
||||
q = Int[]
|
||||
for x in lvl[1], y in path(x)
|
||||
if (x + y) ∉ keys(p)
|
||||
p[x + y] = x
|
||||
push!(q, x + y)
|
||||
end
|
||||
end
|
||||
lvl[1] = q
|
||||
end
|
||||
return push!(path(p[n]), n)
|
||||
end
|
||||
|
||||
function pow(x::Number, n::Integer)
|
||||
r = Dict{typeof(n), typeof(x)}(0 => 1, 1 => x)
|
||||
p = 0
|
||||
for i in path(n)
|
||||
r[i] = r[i - p] * r[p]
|
||||
p = i
|
||||
end
|
||||
return r[n]
|
||||
end
|
||||
|
||||
end # module KnuthPowerTree
|
||||
9
Task/Knuths-power-tree/Julia/knuths-power-tree-2.julia
Normal file
9
Task/Knuths-power-tree/Julia/knuths-power-tree-2.julia
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using .KnuthPowerTree: path, pow
|
||||
|
||||
for n in 0:17
|
||||
println("2 ^ $n:\n - path: ", join(path(n), ", "), "\n - result: ", pow(2, n))
|
||||
end
|
||||
|
||||
for (x, n) in ((big(3), 191), (1.1, 81))
|
||||
println("$x ^ $n:\n - path: ", join(path(n), ", "), "\n - result: ", pow(x, n))
|
||||
end
|
||||
44
Task/Knuths-power-tree/Kotlin/knuths-power-tree.kotlin
Normal file
44
Task/Knuths-power-tree/Kotlin/knuths-power-tree.kotlin
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// version 1.1.3
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
var p = mutableMapOf(1 to 0)
|
||||
var lvl = mutableListOf(listOf(1))
|
||||
|
||||
fun path(n: Int): List<Int> {
|
||||
if (n == 0) return emptyList<Int>()
|
||||
while (n !in p) {
|
||||
val q = mutableListOf<Int>()
|
||||
for (x in lvl[0]) {
|
||||
for (y in path(x)) {
|
||||
if ((x + y) in p) break
|
||||
p[x + y] = x
|
||||
q.add(x + y)
|
||||
}
|
||||
}
|
||||
lvl[0] = q
|
||||
}
|
||||
return path(p[n]!!) + n
|
||||
}
|
||||
|
||||
fun treePow(x: Double, n: Int): BigDecimal {
|
||||
val r = mutableMapOf(0 to BigDecimal.ONE, 1 to BigDecimal(x.toString()))
|
||||
var p = 0
|
||||
for (i in path(n)) {
|
||||
r[i] = r[i - p]!! * r[p]!!
|
||||
p = i
|
||||
}
|
||||
return r[n]!!
|
||||
}
|
||||
|
||||
fun showPow(x: Double, n: Int, isIntegral: Boolean = true) {
|
||||
println("$n: ${path(n)}")
|
||||
val f = if (isIntegral) "%.0f" else "%f"
|
||||
println("${f.format(x)} ^ $n = ${f.format(treePow(x, n))}\n")
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
for (n in 0..17) showPow(2.0, n)
|
||||
showPow(1.1, 81, false)
|
||||
showPow(3.0, 191)
|
||||
}
|
||||
52
Task/Knuths-power-tree/Mathematica/knuths-power-tree.math
Normal file
52
Task/Knuths-power-tree/Mathematica/knuths-power-tree.math
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
ClearAll[NextStep, TreePow]
|
||||
NextStep[pows_List] := Module[{maxlen, sel, new, vals, knows},
|
||||
maxlen = Max[Length /@ pows[[All, "Path"]]];
|
||||
sel = Select[pows, Length[#["Path"]] == maxlen &];
|
||||
knows = pows[[All, "P"]];
|
||||
new = {};
|
||||
Do[
|
||||
vals = s["P"] + s["Path"];
|
||||
vals = DeleteCases[vals, Alternatives @@ Join[s["Path"], knows]];
|
||||
new =
|
||||
Join[
|
||||
new, <|"Path" -> Append[s["Path"], #], "P" -> #|> & /@ vals];
|
||||
,
|
||||
{s, sel}
|
||||
];
|
||||
new //= DeleteDuplicatesBy[#["P"] &];
|
||||
SortBy[Join[pows, new], #["P"] &]
|
||||
]
|
||||
TreePow[path_List, base_] := Module[{db, tups},
|
||||
db = <|1 -> base|>;
|
||||
Do[
|
||||
tups = Tuples[Keys[db], 2];
|
||||
tups = Select[tups, #[[2]] >= #[[1]] &];
|
||||
tups = Select[tups, Total[#] == next &];
|
||||
If[Length[tups] < 1, Abort[]];
|
||||
tups //= First;
|
||||
AssociateTo[db, Total[tups] -> (Times @@ (db /@ tups))]
|
||||
,
|
||||
{next, Rest[path]}
|
||||
];
|
||||
db[Last[path]]
|
||||
]
|
||||
|
||||
pows = {<|"Path" -> {1}, "P" -> 1|>};
|
||||
steps = Nest[NextStep, pows, 7];
|
||||
LayeredGraphPlot[DirectedEdge @@@ steps[[2 ;;, "Path", -2 ;;]], VertexLabels -> Automatic]
|
||||
|
||||
pows = {<|"Path" -> {1}, "P" -> 1|>};
|
||||
steps = Nest[NextStep, pows, 5];
|
||||
assoc = Association[#["P"] -> #["Path"] & /@ steps];
|
||||
Dataset[assoc]
|
||||
TreePow[assoc[#], 2] & /@ Range[1, 17]
|
||||
|
||||
pows = {<|"Path" -> {1}, "P" -> 1|>};
|
||||
steps = NestWhile[NextStep, pows, Not[MemberQ[#[[All, "P"]], 191]] &];
|
||||
SelectFirst[steps, #["P"] == 191 &]["Path"];
|
||||
TreePow[%, 3]
|
||||
|
||||
pows = {<|"Path" -> {1}, "P" -> 1|>};
|
||||
steps = NestWhile[NextStep, pows, Not[MemberQ[#[[All, "P"]], 81]] &];
|
||||
SelectFirst[steps, #["P"] == 81 &]["Path"];
|
||||
TreePow[%, 1.1]
|
||||
64
Task/Knuths-power-tree/Nim/knuths-power-tree.nim
Normal file
64
Task/Knuths-power-tree/Nim/knuths-power-tree.nim
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
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)
|
||||
44
Task/Knuths-power-tree/Perl/knuths-power-tree.pl
Normal file
44
Task/Knuths-power-tree/Perl/knuths-power-tree.pl
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
my @lvl = [1];
|
||||
my %p = (1 => 0);
|
||||
|
||||
sub path {
|
||||
my ($n) = @_;
|
||||
return () if ($n == 0);
|
||||
until (exists $p{$n}) {
|
||||
my @q;
|
||||
foreach my $x (@{$lvl[0]}) {
|
||||
foreach my $y (path($x)) {
|
||||
my $z = $x + $y;
|
||||
last if exists($p{$z});
|
||||
$p{$z} = $x;
|
||||
push @q, $z;
|
||||
}
|
||||
}
|
||||
$lvl[0] = \@q;
|
||||
}
|
||||
(path($p{$n}), $n);
|
||||
}
|
||||
|
||||
sub tree_pow {
|
||||
my ($x, $n) = @_;
|
||||
my %r = (0 => 1, 1 => $x);
|
||||
my $p = 0;
|
||||
foreach my $i (path($n)) {
|
||||
$r{$i} = $r{$i - $p} * $r{$p};
|
||||
$p = $i;
|
||||
}
|
||||
$r{$n};
|
||||
}
|
||||
|
||||
sub show_pow {
|
||||
my ($x, $n) = @_;
|
||||
my $fmt = "%d: %s\n" . ("%g^%s = %f", "%s^%s = %s")[$x == int($x)] . "\n";
|
||||
printf($fmt, $n, "(" . join(" ", path($n)) . ")", $x, $n, tree_pow($x, $n));
|
||||
}
|
||||
|
||||
show_pow(2, $_) for 0 .. 17;
|
||||
show_pow(1.1, 81);
|
||||
{
|
||||
use bigint (try => 'GMP');
|
||||
show_pow(3, 191);
|
||||
}
|
||||
63
Task/Knuths-power-tree/Phix/knuths-power-tree.phix
Normal file
63
Task/Knuths-power-tree/Phix/knuths-power-tree.phix
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}})</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lvl</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">path</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lvl</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lvl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">px</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">path</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">px</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">px</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)!=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">q</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">y</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">lvl</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">path</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">n</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
<span style="color: #7060A8;">mpfr_set_default_precision</span><span style="color: #0000FF;">(</span><span style="color: #000000;">500</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">treepow</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">pn</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{})</span>
|
||||
<span style="color: #000080;font-style:italic;">-- x can be atom or string (but not mpfr)
|
||||
-- (asides: sequence r uses out-by-1 indexing, ie r[1] is for 0.
|
||||
-- sequence c is used to double-check we are not trying
|
||||
-- to use something which has not yet been calculated.)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">pn</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pn</span><span style="color: #0000FF;">=</span><span style="color: #000000;">path</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)},</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pi</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pi</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000080;font-style:italic;">-- string res = shorten(trim_tail(mpfr_sprintf("%.83Rf",r[n+1]),".0"))</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">83</span><span style="color: #0000FF;">),</span><span style="color: #008000;">".0"</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">showpow</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">path</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">xs</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">x</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%3g"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%48v : %3s ^ %d = %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">treepow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pn</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">17</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">showpow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">showpow</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.1"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">81</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">showpow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">191</span><span style="color: #0000FF;">)</span>
|
||||
<!--
|
||||
28
Task/Knuths-power-tree/Python/knuths-power-tree.py
Normal file
28
Task/Knuths-power-tree/Python/knuths-power-tree.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from __future__ import print_function
|
||||
|
||||
# remember the tree generation state and expand on demand
|
||||
def path(n, p = {1:0}, lvl=[[1]]):
|
||||
if not n: return []
|
||||
while n not in p:
|
||||
q = []
|
||||
for x,y in ((x, x+y) for x in lvl[0] for y in path(x) if not x+y in p):
|
||||
p[y] = x
|
||||
q.append(y)
|
||||
lvl[0] = q
|
||||
|
||||
return path(p[n]) + [n]
|
||||
|
||||
def tree_pow(x, n):
|
||||
r, p = {0:1, 1:x}, 0
|
||||
for i in path(n):
|
||||
r[i] = r[i-p] * r[p]
|
||||
p = i
|
||||
return r[n]
|
||||
|
||||
def show_pow(x, n):
|
||||
fmt = "%d: %s\n" + ["%g^%d = %f", "%d^%d = %d"][x==int(x)] + "\n"
|
||||
print(fmt % (n, repr(path(n)), x, n, tree_pow(x, n)))
|
||||
|
||||
for x in range(18): show_pow(2, x)
|
||||
show_pow(3, 191)
|
||||
show_pow(1.1, 81)
|
||||
60
Task/Knuths-power-tree/REXX/knuths-power-tree.rexx
Normal file
60
Task/Knuths-power-tree/REXX/knuths-power-tree.rexx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*REXX program produces & displays a power tree for P, and calculates & displays X^P.*/
|
||||
numeric digits 1000 /*be able to handle some large numbers.*/
|
||||
parse arg XP /*get sets: X, low power, high power.*/
|
||||
if XP='' then XP='2 -4 17 3 191 191 1.1 81' /*Not specified? Then use the default.*/
|
||||
/*────── X LP HP X LP HP X LP ◄── X, low power, high power ··· repeat*/
|
||||
do until XP=''
|
||||
parse var XP x pL pH XP; x= x / 1 /*get X, lowP, highP; and normalize X. */
|
||||
if pH='' then pH= pL /*No highPower? Then assume lowPower. */
|
||||
|
||||
do e=pL to pH; p= abs(e) / 1 /*use a range of powers; use │E│ */
|
||||
$= powerTree(p); w= length(pH) /*construct the power tree, (pow list).*/
|
||||
/* [↑] W≡length for an aligned display*/
|
||||
do i=1 for words($); @.i= word($, i) /*build a fast Knuth's power tree array*/
|
||||
end /*i*/
|
||||
|
||||
if p==0 then do; z= 1; call show; iterate; end /*handle case of zero power.*/
|
||||
!.= .; z= x; !.1= z; prv= z /*define/construct the first power of X*/
|
||||
|
||||
do k=2 to words($); n= @.k /*obtain the power (number) to be used.*/
|
||||
prev= k - 1; diff= n - @.prev /*these are used for the odd powers. */
|
||||
if n//2==0 then z= prv ** 2 /*Even power? Then square the number.*/
|
||||
else z= z * !.diff /* Odd " " mult. by pow diff.*/
|
||||
!.n= z /*remember for other multiplications. */
|
||||
prv= z /*remember for squaring the numbers. */
|
||||
end /*k*/
|
||||
call show /*display the expression and its value.*/
|
||||
end /*e*/
|
||||
end /*until XP ···*/
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
powerTree: arg y 1 oy; $= /*Z is the result; $ is the power tree.*/
|
||||
if y=0 | y=1 then return y /*handle special cases for zero & unity*/
|
||||
#.= 0; @.= 0; #.0= 1 /*define default & initial array values*/
|
||||
/* [↓] add blank "flag" thingy──►list.*/
|
||||
do while \(y//2); $= $ ' ' /*reduce "front" even power #s to odd #*/
|
||||
if y\==oy then $= y $ /*(only) ignore the first power number*/
|
||||
y= y % 2 /*integer divide the power (it's even).*/
|
||||
end /*while*/
|
||||
|
||||
if $\=='' then $= y $ /*re─introduce the last power number. */
|
||||
$= $ oy /*insert last power number 1st in list.*/
|
||||
if y>1 then do while @.y==0; n= #.0; m= 0
|
||||
do while n\==0; q= 0; s= n
|
||||
do while s\==0; _= n + s
|
||||
if @._==0 then do; if q==0 then m_= _;
|
||||
#._= q; @._= n; q= _
|
||||
end
|
||||
s= @.s
|
||||
end /*while s¬==0*/
|
||||
if q\==0 then do; #.m= q; m= m_; end
|
||||
n= #.n
|
||||
end /*while n¬==0*/
|
||||
#.m= 0
|
||||
end /*while @.y==0*/
|
||||
z= @.y
|
||||
do while z\==0; $= z $; z= @.z; end /*build power list*/
|
||||
return space($) /*del extra blanks*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
show: if e<0 then z=format(1/z, , 40)/1; _=right(e, w) /*use reciprocal? */
|
||||
say left('power tree for ' _ " is: " $,60) '═══' x"^"_ ' is: ' z; return
|
||||
40
Task/Knuths-power-tree/Racket/knuths-power-tree.rkt
Normal file
40
Task/Knuths-power-tree/Racket/knuths-power-tree.rkt
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#lang racket
|
||||
|
||||
(define pow-path-cache (make-hash '((0 . (0)) (1 . (0 1)))))
|
||||
|
||||
(define pow-path-level '(1))
|
||||
|
||||
(define (pow-path-extend!)
|
||||
(define next-level
|
||||
(for*/fold ([next-level '()])
|
||||
([x (in-list pow-path-level)]
|
||||
[y (in-list (pow-path x))]
|
||||
[s (in-value (+ x y))]
|
||||
#:when (not (hash-has-key? pow-path-cache s)))
|
||||
(hash-set! pow-path-cache s (append (hash-ref pow-path-cache x) (list s)))
|
||||
(cons s next-level)))
|
||||
(set! pow-path-level (reverse next-level)))
|
||||
|
||||
(define (pow-path n)
|
||||
(let loop ()
|
||||
(unless (hash-has-key? pow-path-cache n)
|
||||
(pow-path-extend!)
|
||||
(loop)))
|
||||
(hash-ref pow-path-cache n))
|
||||
|
||||
(define (pow-tree x n)
|
||||
(define pows (make-hash `((0 . 1) (1 . ,x))))
|
||||
(for/fold ([prev 0])
|
||||
([i (in-list (pow-path n))])
|
||||
(hash-set! pows i (* (hash-ref pows (- i prev)) (hash-ref pows prev)))
|
||||
i)
|
||||
(hash-ref pows n))
|
||||
|
||||
(define (show-pow x n)
|
||||
(printf "~a: ~a\n" n (cdr (pow-path n)))
|
||||
(printf "~a^~a = ~a\n" x n (pow-tree x n)))
|
||||
|
||||
(for ([x (in-range 18)])
|
||||
(show-pow 2 x))
|
||||
(show-pow 3 191)
|
||||
(show-pow 1.1 81)
|
||||
39
Task/Knuths-power-tree/Raku/knuths-power-tree.raku
Normal file
39
Task/Knuths-power-tree/Raku/knuths-power-tree.raku
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
use v6;
|
||||
|
||||
sub power-path ($n ) {
|
||||
state @unused_nodes = (2,);
|
||||
state @power-tree = (False,0,1);
|
||||
|
||||
until @power-tree[$n].defined {
|
||||
my $node = @unused_nodes.shift;
|
||||
|
||||
for $node X+ power-path($node).pick(*) {
|
||||
next if @power-tree[$_].defined;
|
||||
@unused_nodes.push($_);
|
||||
@power-tree[$_]= $node;
|
||||
}
|
||||
}
|
||||
|
||||
( $n, { @power-tree[$_] } ...^ 0 ).reverse;
|
||||
}
|
||||
|
||||
multi power ( $, 0 ) { 1 };
|
||||
multi power ( $n, $exponent ) {
|
||||
state %p;
|
||||
my %r = %p{$n} // ( 0 => 1, 1 => $n ) ;
|
||||
|
||||
for power-path( $exponent ).rotor( 2 => -1 ) -> ( $p, $c ) {
|
||||
%r{ $c } = %r{ $p } * %r{ $c - $p }
|
||||
}
|
||||
|
||||
%p{$n} := %r ;
|
||||
%r{ $exponent }
|
||||
}
|
||||
|
||||
say 'Power paths: ', pairs map *.&power-path, ^18;
|
||||
say '2 ** key = value: ', pairs map { 2.&power($_) }, ^18;
|
||||
|
||||
say 'Path for 191: ', power-path 191;
|
||||
say '3 ** 191 = ', power 3, 191;
|
||||
say 'Path for 81: ', power-path 81;
|
||||
say '1.1 ** 81 = ', power 1.1, 81;
|
||||
38
Task/Knuths-power-tree/Sidef/knuths-power-tree.sidef
Normal file
38
Task/Knuths-power-tree/Sidef/knuths-power-tree.sidef
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
var lvl = [[1]]
|
||||
var p = Hash(1 => 0)
|
||||
|
||||
func path(n) is cached {
|
||||
n || return []
|
||||
while (n !~ p) {
|
||||
var q = []
|
||||
for x in lvl[0] {
|
||||
for y in path(x) {
|
||||
break if (x+y ~~ p)
|
||||
y = x+y
|
||||
p{y} = x
|
||||
q << y
|
||||
}
|
||||
}
|
||||
lvl[0] = q
|
||||
}
|
||||
path(p{n}) + [n]
|
||||
}
|
||||
|
||||
func tree_pow(x, n) {
|
||||
var r = Hash(0 => 1, 1 => x)
|
||||
var p = 0
|
||||
for i in path(n) {
|
||||
r{i} = (r{i-p} * r{p})
|
||||
p = i
|
||||
}
|
||||
r{n}
|
||||
}
|
||||
|
||||
func show_pow(x, n) {
|
||||
var fmt = ("%d: %s\n" + ["%g^%s = %f", "%s^%s = %s"][x.is_int] + "\n")
|
||||
print(fmt % (n, path(n), x, n, tree_pow(x, n)))
|
||||
}
|
||||
|
||||
for x in ^18 { show_pow(2, x) }
|
||||
show_pow(1.1, 81)
|
||||
show_pow(3, 191)
|
||||
45
Task/Knuths-power-tree/Wren/knuths-power-tree.wren
Normal file
45
Task/Knuths-power-tree/Wren/knuths-power-tree.wren
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import "/big" for BigRat
|
||||
import "/fmt" for Fmt
|
||||
|
||||
var p = { 1: 0 }
|
||||
var lvl = [[1]]
|
||||
|
||||
var path // recursive
|
||||
path = Fn.new { |n|
|
||||
if (n == 0) return []
|
||||
while (!p.containsKey(n)) {
|
||||
var q = []
|
||||
for (x in lvl[0]) {
|
||||
System.write("") // guard against VM recursion bug
|
||||
for (y in path.call(x)) {
|
||||
if (p.containsKey(x + y)) break
|
||||
p[x + y] = x
|
||||
q.add(x + y)
|
||||
}
|
||||
}
|
||||
lvl[0] = q
|
||||
}
|
||||
System.write("") // guard against VM recursion bug
|
||||
var l = path.call(p[n])
|
||||
l.add(n)
|
||||
return l
|
||||
}
|
||||
|
||||
var treePow = Fn.new { |x, n|
|
||||
var r = { 0: BigRat.one, 1: BigRat.fromDecimal(x) }
|
||||
var p = 0
|
||||
for (i in path.call(n)) {
|
||||
r[i] = r[i-p] * r[p]
|
||||
p = i
|
||||
}
|
||||
return r[n]
|
||||
}
|
||||
|
||||
var showPow = Fn.new { |x, n|
|
||||
System.print("%(n): %(path.call(n))")
|
||||
Fmt.print("$s ^ $d = $s\n", x, n, treePow.call(x, n).toDecimal(6))
|
||||
}
|
||||
|
||||
for (n in 0..17) showPow.call(2, n)
|
||||
showPow.call(1.1, 81)
|
||||
showPow.call(3, 191)
|
||||
25
Task/Knuths-power-tree/Zkl/knuths-power-tree-1.zkl
Normal file
25
Task/Knuths-power-tree/Zkl/knuths-power-tree-1.zkl
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# remember the tree generation state and expand on demand
|
||||
fcn path(n,p=Dictionary(1,0),lvl=List(List(1))){
|
||||
if(n==0) return(T);
|
||||
while(not p.holds(n)){
|
||||
q:=List();
|
||||
foreach x,y in (lvl[0],path(x,p,lvl)){
|
||||
if(p.holds(x+y)) break; // not this y
|
||||
y=x+y; p[y]=x;
|
||||
q.append(y);
|
||||
}
|
||||
lvl[0]=q
|
||||
}
|
||||
path(p[n],p,lvl) + n
|
||||
}
|
||||
|
||||
fcn tree_pow(x,n,path){
|
||||
r,p:=Dictionary(0,1, 1,x), 0;
|
||||
foreach i in (path){ r[i]=r[i-p]*r[p]; p=i; }
|
||||
r[n]
|
||||
}
|
||||
|
||||
fcn show_pow(x,n){
|
||||
fmt:="%d: %s\n" + T("%g^%d = %f", "%d^%d = %d")[x==Int(x)] + "\n";
|
||||
println(fmt.fmt(n,p:=path(n),x,n,tree_pow(x,n,p)))
|
||||
}
|
||||
5
Task/Knuths-power-tree/Zkl/knuths-power-tree-2.zkl
Normal file
5
Task/Knuths-power-tree/Zkl/knuths-power-tree-2.zkl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
foreach x in (18){ show_pow(2,x) }
|
||||
show_pow(1.1,81);
|
||||
|
||||
var [const] BN=Import("zklBigNum"); // GNU GMP big ints
|
||||
show_pow(BN(3),191);
|
||||
Loading…
Add table
Add a link
Reference in a new issue