func TestDedup(t *testing.T) { a := []int{} n := Dedupe(sort.IntSlice(a)) if g, e := n, 0; g != e { t.Fatal(g, e) } if g, e := len(a), 0; g != e { t.Fatal(g, e) } for c := 1; c <= 7; c++ { in := make([]int, c) lim := int(mathutil.ModPowUint32(uint32(c), uint32(c), math.MaxUint32)) for n := 0; n < lim; n++ { m := n for i := range in { in[i] = m % c m /= c } in0 := append([]int(nil), in...) out0 := dedupe(in) n := Dedupe(sort.IntSlice(in)) if g, e := n, len(out0); g != e { t.Fatalf("n %d, exp %d, in0 %v, in %v, out0 %v", g, e, in0, in, out0) } for i, v := range out0 { if g, e := in[i], v; g != e { t.Fatalf("n %d, in0 %v, in %v, out0 %v", n, in0, in, out0) } } } } }
// ModPow2 returns x such that 2^Me % Mm == 2^x. It panics for m < 2. Typical // run time is < 1 µs. Use instead of ModPow(2, e, m) wherever possible. func ModPow2(e, m uint32) (x uint32) { /* m < 2 -> panic e == 0 -> x == 0 e == 1 -> x == 1 2^M1 % M2 == 2^1 % 3 == 2^1 10 // 2^1, 3, 5, 7 ... +2k 2^M1 % M3 == 2^1 % 7 == 2^1 010 // 2^1, 4, 7, ... +3k 2^M1 % M4 == 2^1 % 15 == 2^1 0010 // 2^1, 5, 9, 13... +4k 2^M1 % M5 == 2^1 % 31 == 2^1 00010 // 2^1, 6, 11, 16... +5k 2^M2 % M2 == 2^3 % 3 == 2^1 10.. // 2^3, 5, 7, 9, 11, ... +2k 2^M2 % M3 == 2^3 % 7 == 2^0 001... // 2^3, 6, 9, 12, 15, ... +3k 2^M2 % M4 == 2^3 % 15 == 2^3 1000 // 2^3, 7, 11, 15, 19, ... +4k 2^M2 % M5 == 2^3 % 31 == 2^3 01000 // 2^3, 8, 13, 18, 23, ... +5k 2^M3 % M2 == 2^7 % 3 == 2^1 10..--.. // 2^3, 5, 7... +2k 2^M3 % M3 == 2^7 % 7 == 2^1 010...--- // 2^1, 4, 7... +3k 2^M3 % M4 == 2^7 % 15 == 2^3 1000.... // +4k 2^M3 % M5 == 2^7 % 31 == 2^2 00100..... // +5k 2^M3 % M6 == 2^7 % 63 == 2^1 000010...... // +6k 2^M3 % M7 == 2^7 % 127 == 2^0 0000001....... 2^M3 % M8 == 2^7 % 255 == 2^7 10000000 2^M3 % M9 == 2^7 % 511 == 2^7 010000000 2^M4 % M2 == 2^15 % 3 == 2^1 10..--..--..--.. 2^M4 % M3 == 2^15 % 7 == 2^0 1...---...---... 2^M4 % M4 == 2^15 % 15 == 2^3 1000....----.... 2^M4 % M5 == 2^15 % 31 == 2^0 1.....-----..... 2^M4 % M6 == 2^15 % 63 == 2^3 1000......------ 2^M4 % M7 == 2^15 % 127 == 2^1 10.......------- 2^M4 % M8 == 2^15 % 255 == 2^7 10000000........ 2^M4 % M9 == 2^15 % 511 == 2^6 1000000......... */ switch { case m < 2: panic(0) case e < 2: return e } if x = mathutil.ModPowUint32(2, e, m); x == 0 { return m - 1 } return x - 1 }
// HasFactorUint32 returns true if d | Mn. Typical run time for a 32 bit factor // and a 32 bit exponent is < 1 µs. func HasFactorUint32(d, n uint32) bool { return d == 1 || d&1 != 0 && mathutil.ModPowUint32(2, n, d) == 1 }