func (s *State) Encode() []byte { enc := arith.NewEncoder() historic := s.Historic().Cubes baseline := s.Baseline().Cubes current := s.Current().Cubes mzeros := mZeros() items := []int{} for i := range current { cube, base := ¤t[i], &baseline[i] if *cube == *base { mzeros.Encode(enc, 0) } else { mzeros.Encode(enc, 1) items = append(items, i) } } for _, i := range items { cube := ¤t[i] mzeros.Encode(enc, uint(cube.Interacting^1)) } for _, i := range items { cube, base := ¤t[i], &baseline[i] v := uint(cube.Largest ^ base.Largest) mzeros.Encode(enc, v&1) mzeros.Encode(enc, v>>1) } items6 := Index6(items, len(baseline)) SortByZ(items6, Delta6(historic, baseline)) get6 := Extra6(historic, baseline, current) max := uint64(0) for _, i := range items6 { ext := uint64(bit.ZEncode(int64(get6(i)))) if max < ext { max = ext } } if max == 0 { mzeros.Encode(enc, 1) enc.Close() return enc.Bytes() } nbits := bit.ScanRight(max) + 1 for i := 0; i < int(nbits); i += 1 { mzeros.Encode(enc, 0) } mzeros.Encode(enc, 1) mvalues := mValues(nbits) for _, i := range items6 { val := uint(bit.ZEncode(int64(get6(i)))) mvalues.Encode(enc, val) } enc.Close() return enc.Bytes() }
func main() { flag.Parse() rand.Seed(time.Now().UnixNano()) var baseline []physics.Cube var current []physics.Cube file, err := os.Open(flag.Arg(0)) check(err) dec := gob.NewDecoder(file) dec.Decode(¤t) dec.Decode(&baseline) minimal := 1 << 10 items := []int{} for i := range current { cube, base := ¤t[i], &baseline[i] if *cube != *base { items = append(items, i) } } items6 := physics.Index6(items, len(current)) cur6 := physics.Delta6(baseline, current) max := uint64(0) for _, i := range items6 { ext := uint64(bit.ZEncode(int64(cur6(i)))) if max < ext { max = ext } } nbits := bit.ScanRight(max) + 1 for i := 0; i < *tries; i += 1 { menc, desc := RandomTree(nbits) enc := arith.NewEncoder() for _, i := range items { cube := ¤t[i] menc.Encode(enc, uint(cube.Interacting^1)) } for _, i := range items { cube, base := ¤t[i], &baseline[i] v := uint(cube.Largest ^ base.Largest) menc.Encode(enc, v&1) menc.Encode(enc, v>>1) } enc.Close() if len(enc.Bytes()) < minimal { fmt.Printf("%6d %5d - %s\n", i, len(enc.Bytes()), desc) minimal = len(enc.Bytes()) } } }