Cycle detection: Difference between revisions
Content added Content deleted
Not a robot (talk | contribs) (Add PL/M) |
Not a robot (talk | contribs) (Add BCPL) |
||
Line 312: | Line 312: | ||
Index 2 |
Index 2 |
||
Length 6 |
Length 6 |
||
101 2 5 26 167 95</pre> |
|||
=={{header|BCPL}}== |
|||
<lang BCPL>get "libhdr" |
|||
// Brent's algorithm. 'fn' is a function pointer, |
|||
// 'lam' and 'mu' are output pointers. |
|||
let brent(fn, x0, lam, mu) be |
|||
$( let power, tort, hare = 1, x0, fn(x0) |
|||
!lam := 1 |
|||
until tort = hare do |
|||
$( if power = !lam then |
|||
$( tort := hare |
|||
power := power * 2 |
|||
!lam := 0 |
|||
$) |
|||
hare := fn(hare) |
|||
!lam := !lam + 1 |
|||
$) |
|||
tort := x0 |
|||
hare := x0 |
|||
for i = 1 to !lam do |
|||
hare := fn(hare) |
|||
!mu := 0 |
|||
until tort = hare do |
|||
$( tort := fn(tort) |
|||
hare := fn(hare) |
|||
!mu := !mu + 1 |
|||
$) |
|||
$) |
|||
// Print fn^m(x0) to fn^n(x0) |
|||
let printRange(fn, x0, m, n) be |
|||
$( for i = 0 to n-1 do |
|||
$( if m<=i then writef("%N ", x0) |
|||
x0 := fn(x0) |
|||
$) |
|||
wrch('*N') |
|||
$) |
|||
let start() be |
|||
$( let lam, mu = 0, 0 |
|||
// the function to find a cycle in |
|||
let f(x) = (x*x + 1) rem 255 |
|||
// print the first 20 values |
|||
printRange(f, 3, 0, 20) |
|||
// find the cycle |
|||
brent(f, 3, @lam, @mu) |
|||
writef("Length: %N*NIndex: %N*N", lam, mu) |
|||
// print the cycle |
|||
printRange(f, 3, mu, mu+lam) |
|||
$)</lang> |
|||
{{out}} |
|||
<pre>3 10 101 2 5 26 167 95 101 2 5 26 167 95 101 2 5 26 167 95 |
|||
Length: 6 |
|||
Index: 2 |
|||
101 2 5 26 167 95</pre> |
101 2 5 26 167 95</pre> |
||