Cycle detection

func brent (f, x0) {
    var power = 1
    var λ = 1
    var tortoise = x0
    var hare = f(x0)
 
    while (tortoise != hare) {
        if (power == λ) {
            tortoise = hare
            power *= 2
            λ = 0
        }
        hare = f(hare)
        λ += 1
    }
 
    var μ = 0
    tortoise = x0
    hare = x0
    { hare = f(hare) } * λ
 
    while (tortoise != hare) {
        tortoise = f(tortoise)
        hare = f(hare)
        μ += 1
    }
 
    return, μ)
}
 
func cyclical_function(x) { (x*x + 1) % 255 }
 
var (l, s) = brent(cyclical_function, 3)
 
var seq = gather {
    var x = 3
    { take(x); x = cyclical_function(x) } * 20
}
 
say seq.join(', ')+', ...'
 
say "Cycle length #{l}.";
say "Cycle start index #{s}."
say [seq[s .. (s + l - 1)]]

Output:

3, 10, 101, 2, 5, 26, 167, 95, 101, 2, 5, 26, 167, 95, 101, 2, 5, 26, 167, 95, ...
Cycle length 6.
Cycle start index 2.
[101, 2, 5, 26, 167, 95]

Last updated