return sliceCopy.Interface(), nil
}
+// Sanity check for slices created by Seq and D.
+const maxSeqSize = 1000000
+
+var errSeqSizeExceedsLimit = errors.New("size of result exceeds limit")
+
// Seq creates a sequence of integers from args. It's named and used as GNU's seq.
//
// Examples:
}
// sanity check
- if last < -100000 {
- return nil, errors.New("size of result exceeds limit")
+ if last < -maxSeqSize {
+ return nil, errSeqSizeExceedsLimit
}
size := ((last - first) / inc) + 1
// sanity check
- if size <= 0 || size > 2000 {
- return nil, errors.New("size of result exceeds limit")
+ if size <= 0 || size > maxSeqSize {
+ return nil, errSeqSizeExceedsLimit
}
seq := make([]int, size)
// See https://getkerf.wordpress.com/2016/03/30/the-best-algorithm-no-one-knows-about/
func (ns *Namespace) D(seed, n, hi any) []int {
key := dKey{seed: cast.ToUint64(seed), n: cast.ToInt(n), hi: cast.ToInt(hi)}
+ if key.n <= 0 || key.hi <= 0 || key.n > key.hi {
+ return nil
+ }
+ if key.n > maxSeqSize {
+ panic(errSeqSizeExceedsLimit)
+ }
v, _ := ns.dCache.GetOrCreate(key, func() ([]int, error) {
prng := rand.New(rand.NewPCG(key.seed, 0))
result := make([]int, 0, key.n)
{[]any{1, -1, 2}, false},
{[]any{2, 1, 1}, false},
{[]any{2, 1, 1, 1}, false},
- {[]any{2001}, false},
+ {[]any{-1000001}, false},
{[]any{}, false},
{[]any{0, -1000000}, false},
{[]any{tstNoStringer{}}, false},
c.Assert(ns.D(42, 5, 100), qt.DeepEquals, []int{24, 34, 66, 82, 96})
c.Assert(ns.D(31, 5, 100), qt.DeepEquals, []int{12, 37, 38, 69, 98})
+ c.Assert(ns.D(42, 9, 10), qt.DeepEquals, []int{0, 1, 2, 3, 4, 6, 7, 8, 9})
+ c.Assert(ns.D(42, 10, 10), qt.DeepEquals, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
+ c.Assert(ns.D(42, 11, 10), qt.IsNil) // n > hi
+ c.Assert(ns.D(42, -5, 100), qt.IsNil)
+ c.Assert(ns.D(42, 0, 100), qt.IsNil)
+ c.Assert(ns.D(42, 5, 0), qt.IsNil)
+ c.Assert(ns.D(42, 5, -10), qt.IsNil)
+ c.Assert(ns.D(42, 5, 3000000), qt.DeepEquals, []int{720363, 1041693, 2009179, 2489106, 2873969})
+ c.Assert(func() { ns.D(31, 2000000, 3000000) }, qt.PanicMatches, "size of result exceeds limit")
}
func BenchmarkD2(b *testing.B) {