You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
5.5 KiB
Go

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 >= 0 {
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 >= 0 {
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 >= 0 {
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
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
}