package compress

import 

// Estimate returns a normalized compressibility estimate of block b.
// Values close to zero are likely uncompressible.
// Values above 0.1 are likely to be compressible.
// Values above 0.5 are very compressible.
// Very small lengths will return 0.
func ( []byte) float64 {
	if len() < 16 {
		return 0
	}

	// Correctly predicted order 1
	 := 0
	 := false
	var  [256]byte
	var  [256]int
	 := byte(0)
	for ,  := range  {
		if  == [] {
			// We only count a hit if there was two correct predictions in a row.
			if  {
				++
			}
			 = true
		} else {
			 = false
		}
		[] = 
		 = 
		[]++
	}

	// Use x^0.6 to give better spread
	 := math.Pow(float64()/float64(len()), 0.6)

	// Calculate histogram distribution
	 := float64(0)
	 := float64(len()) / 256

	for ,  := range  {
		 := float64() - 
		 +=  * 
	}

	 := math.Sqrt(float64()) / float64(len())
	 := math.Sqrt(1 / float64(len()))

	// Subtract expected stddev
	 -= 
	if  < 0 {
		 = 0
	}
	 *= 1 + 

	// Use x^0.4 to give better spread
	 := math.Pow(, 0.4)

	// 50/50 weight between prediction and histogram distribution
	return math.Pow((+)/2, 0.9)
}

// ShannonEntropyBits returns the number of bits minimum required to represent
// an entropy encoding of the input bytes.
// https://en.wiktionary.org/wiki/Shannon_entropy
func ( []byte) int {
	if len() == 0 {
		return 0
	}
	var  [256]int
	for ,  := range  {
		[]++
	}
	 := float64(0)
	 := 1.0 / float64(len())
	for ,  := range [:] {
		if  > 0 {
			 := float64()
			 += math.Ceil(-math.Log2(*) * )
		}
	}
	return int(math.Ceil())
}