module Tins::Attempt
def compute_duration_base(sleep, attempts)
def compute_duration_base(sleep, attempts) x1, x2 = 1, sleep attempts <= sleep or raise ArgumentError, "need less or equal number of attempts than sleep duration #{sleep}" x1 >= x2 and raise ArgumentError, "invalid sleep argument: #{sleep.inspect}" function = -> x { (0...attempts).inject { |s, i| s + x ** i } - sleep } f, fmid = function[x1], function[x2] f * fmid >= 0 and raise ArgumentError, "invalid sleep argument: #{sleep.inspect}" n = 1 << 16 epsilon = 1E-16 root = if f < 0 dx = x2 - x1 x1 else dx = x1 - x2 x2 end n.times do fmid = function[xmid = root + (dx *= 0.5)] fmid < 0 and root = xmid dx.abs < epsilon or fmid == 0 and return root end raise ArgumentError, "too many iterations (#{n})" result end