package tools

import (
	"math/big"
)

var (
	valMin = big.NewInt(1187)
	//valMin  = big.NewInt(1)
	maxTest = big.NewInt(111187000)
	//maxTest = big.NewInt(87)
	max = Exp64(big.NewInt(2), 63)
)

func And(a, b *big.Int) *big.Int {
	return new(big.Int).And(a, b)
}

func Exp(a, b, mod *big.Int) *big.Int {
	return new(big.Int).Exp(a, b, mod)
}

func Exp64(a *big.Int, b int64) *big.Int {
	return new(big.Int).Exp(a, big.NewInt(b), nil)
}

func Mul(a, b *big.Int) *big.Int {
	return new(big.Int).Mul(a, b)
}

func Add(a, b *big.Int) *big.Int {
	return new(big.Int).Add(a, b)
}

func Add64(a *big.Int, b int64) *big.Int {
	return Add(a, big.NewInt(b))
}

func Mod(a, b *big.Int) *big.Int {
	return new(big.Int).Mod(a, b)
}

func Mod64(a *big.Int, b int64) *big.Int {
	return Mod(a, big.NewInt(b))
}

func Neg(a *big.Int) *big.Int {
	return new(big.Int).Neg(a)
}

func Sub(a, b *big.Int) *big.Int {
	return new(big.Int).Sub(a, b)
}

func Sub64(a *big.Int, b int64) *big.Int {
	return Sub(a, big.NewInt(b))
}

func Cmp(a, b *big.Int) bool {
	return a.Cmp(b) == 0
}

func Div(a, b *big.Int) *big.Int {
	return new(big.Int).Div(a, b)
}

func Div64(a *big.Int, b int64) *big.Int {
	return Div(a, big.NewInt(b))
}

func Rem(a, b *big.Int) *big.Int {
	return new(big.Int).Rem(a, b)
}

func Split(x *big.Int, parts int, firstOffset, lastOffset *big.Int) [][]*big.Int {
	res := make([][]*big.Int, parts)
	div := Div64(x, int64(parts))
	var last []*big.Int
	for i := 0; i < parts; i++ {
		res[i] = []*big.Int{
			Mul(big.NewInt(int64(i)), div),
			Sub64(Add(Mul(big.NewInt(int64(i)), div), div), 1),
		}
		last = res[i]
	}
	last[1] = Add(last[1], Add64(Mod64(x, int64(parts)), 1))
	res[0][0] = Add(res[0][0], firstOffset)
	last[1] = Sub(last[1], lastOffset)
	return res
}