package serializer import ( "fonchain-artshow/cmd/model" "math" "sort" ) func CalcPrice(total_price int64, total_ruler int32, artworksPrices []*model.ArtworkPrice) []*model.ArtworkPrice { price := math.Floor(float64(total_price) / float64(total_ruler)) _, f := math.Modf(float64(total_price) / float64(total_ruler)) if f >= 0.5 { price += 1 } var ( current_total_price int64 current_artwork_price int64 current_copyright_price int64 add_total_balance int64 add_artwork_balance int64 add_copyright_balance int64 loss_total_price int64 loss_artwork_price int64 loss_copyright_price int64 ) for total_price-current_total_price != 0 { current_total_price = calcTotalPrice(artworksPrices, add_total_balance, int64(price)) if current_total_price != 0 { add_total_balance = total_price - current_total_price } if int(math.Abs(float64(add_total_balance))) < len(artworksPrices) { loss_total_price = add_total_balance break } } maxId, dirId := findArtworkToAdd(artworksPrices, int64(price)) if dirId > -1 { artworksPrices[dirId].Price = artworksPrices[dirId].Price + loss_total_price } else { artworksPrices[maxId].Price = artworksPrices[maxId].Price + loss_total_price } for int64(float64(total_price)*0.95)-current_artwork_price != 0 { current_artwork_price = calcArtworkPrice(artworksPrices, add_artwork_balance) if current_artwork_price != 0 { add_artwork_balance = int64(float64(total_price)*0.95) - current_artwork_price } if int(math.Abs(float64(add_artwork_balance))) < len(artworksPrices) { _, f := math.Modf(float64(total_price) * 0.95) if f >= 0.5 { add_artwork_balance += 1 } loss_artwork_price = add_artwork_balance break } } if dirId > -1 { artworksPrices[dirId].ArtworkPrice = artworksPrices[dirId].ArtworkPrice + loss_artwork_price } else { artworksPrices[maxId].ArtworkPrice = artworksPrices[maxId].ArtworkPrice + loss_artwork_price } for int64(float64(total_price)*0.05)-current_copyright_price != 0 { current_copyright_price = calcCopyrightPrice(artworksPrices, add_copyright_balance) if current_copyright_price != 0 { add_copyright_balance = int64(float64(total_price)*0.05) - current_copyright_price } if int(math.Abs(float64(add_copyright_balance))) < len(artworksPrices) { loss_copyright_price = add_copyright_balance break } } if dirId > -1 { artworksPrices[dirId].CopyrightPrice = artworksPrices[dirId].CopyrightPrice + loss_copyright_price } else { artworksPrices[maxId].CopyrightPrice = artworksPrices[maxId].CopyrightPrice + loss_copyright_price } return artworksPrices } func calcArtworkPrice(artworks []*model.ArtworkPrice, add_balance int64) int64 { var ( current_artwork_price int64 add_balance_single float64 ) if math.Abs(float64(add_balance)) > 0 { add_balance_single = math.Floor(math.Abs(float64(add_balance)) / float64(len(artworks))) if add_balance < 0 { add_balance_single = 0 - add_balance_single } } for i := 0; i < len(artworks); i++ { artworks[i].ArtworkPrice = int64(math.Floor(float64(artworks[i].Price) * 0.95)) artworks[i].ArtworkPrice += int64(add_balance_single) current_artwork_price += artworks[i].ArtworkPrice } return current_artwork_price } func calcCopyrightPrice(artworks []*model.ArtworkPrice, add_balance int64) int64 { var ( current_copyright_price int64 add_balance_single float64 ) if math.Abs(float64(add_balance)) > 0 { add_balance_single = math.Floor(math.Abs(float64(add_balance)) / float64(len(artworks))) if add_balance < 0 { add_balance_single = 0 - add_balance_single } } for i := 0; i < len(artworks); i++ { artworks[i].CopyrightPrice = int64(math.Floor(float64(artworks[i].Price) * 0.05)) artworks[i].CopyrightPrice += int64(add_balance_single) current_copyright_price += artworks[i].CopyrightPrice } return current_copyright_price } func calcTotalPrice(artworks []*model.ArtworkPrice, add_balance, price int64) int64 { var ( current_total_price int64 add_balance_single float64 ) if math.Abs(float64(add_balance)) > 0 { add_balance_single = math.Floor(math.Abs(float64(add_balance)) / float64(len(artworks))) if add_balance < 0 { add_balance_single = 0 - add_balance_single } } for i := 0; i < len(artworks); i++ { artworks[i].Price = int64(add_balance_single) artworks[i].Price += int64(artworks[i].Ruler) * price artworks[i].RulerPrice = price current_total_price += artworks[i].Price } return current_total_price } func findArtworkToAdd(artworks []*model.ArtworkPrice, ruler_price int64) (int, int) { var ( max_ruler = -1 maxIndex = -1 difIndex = -1 ) bucket := make(map[int][]int, 0) sortFir := make(map[int]int, 0) sortSec := make([]int, 0) for i := 0; i < len(artworks); i++ { if len(bucket[int(artworks[i].Ruler)]) > 0 { bucket[int(artworks[i].Ruler)] = append(bucket[int(artworks[i].Ruler)], i) } else { bucket[int(artworks[i].Ruler)] = make([]int, 0) bucket[int(artworks[i].Ruler)] = append(bucket[int(artworks[i].Ruler)], i) } sortFir[int(artworks[i].Ruler)] = i //fmt.Println(bucket[artworks[i].Ruler]) } for ruler, _ := range sortFir { sortSec = append(sortSec, int(ruler)) } sort.Ints(sortSec) if len(sortSec) == 1 { maxIndex = bucket[sortSec[0]][0] //return maxIndex ,0 } else { for i := len(sortSec); i > 0; i-- { if max_ruler < sortSec[i-1] { max_ruler = sortSec[i-1] } if len(bucket[sortSec[i-1]]) > 1 { continue } if len(bucket[sortSec[i-1]]) == 1 { difIndex = bucket[sortSec[i-1]][0] break } } if difIndex == -1 { maxIndex = bucket[max_ruler][0] } } return maxIndex, difIndex }