package main import ( "encoding/json" "math" "net/http" ) type Container struct { Length float64 `json:"length"` Width float64 `json:"width"` Height float64 `json:"height"` } type Box struct { Length float64 `json:"length"` Width float64 `json:"width"` Height float64 `json:"height"` } type Placement struct { X, Y, Z float64 `json:"x"` } type Response struct { Count int `json:"count"` Layout []Placement `json:"layout"` BoxLength float64 `json:"boxLength"` BoxWidth float64 `json:"boxWidth"` BoxHeight float64 `json:"boxHeight"` Strategy string `json:"strategy"` Density float64 `json:"density"` SpaceUtilization float64 `json:"spaceUtilization"` UsedVolume float64 `json:"usedVolume"` } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) http.HandleFunc("/calculate", func(w http.ResponseWriter, r *http.Request) { var data struct { Container Container `json:"container"` Box Box `json:"box"` } json.NewDecoder(r.Body).Decode(&data) layout, bestRotation, strategy, density, spaceUtilization, usedVolume := optimizePacking(data.Container, data.Box) count := len(layout) response := Response{ Count: count, Layout: layout, BoxLength: bestRotation.Length, BoxWidth: bestRotation.Width, BoxHeight: bestRotation.Height, Strategy: strategy, Density: density, SpaceUtilization: spaceUtilization, UsedVolume: usedVolume, } json.NewEncoder(w).Encode(response) }) http.ListenAndServe(":8080", nil) } func optimizePacking(con Container, box Box) ([]Placement, Box, string, float64, float64, float64) { var bestLayout []Placement var bestRotation Box var bestStrategy string maxCount := 0 var bestDensity float64 var bestSpaceUtilization float64 var bestUsedVolume float64 rotations := generateRotations(box) conVolume := con.Length * con.Width * con.Height for _, r := range rotations { for _, strategy := range []string{"XY", "XZ", "YX", "YZ", "ZX", "ZY"} { var xCount, yCount, zCount float64 switch strategy { case "XY": xCount = math.Floor(con.Length / r.Length) yCount = math.Floor(con.Width / r.Width) zCount = math.Floor(con.Height / r.Height) case "XZ": xCount = math.Floor(con.Length / r.Length) zCount = math.Floor(con.Height / r.Height) yCount = math.Floor(con.Width / r.Width) case "YX": yCount = math.Floor(con.Width / r.Length) xCount = math.Floor(con.Length / r.Width) zCount = math.Floor(con.Height / r.Height) case "YZ": yCount = math.Floor(con.Width / r.Length) zCount = math.Floor(con.Height / r.Height) xCount = math.Floor(con.Length / r.Width) case "ZX": zCount = math.Floor(con.Height / r.Length) xCount = math.Floor(con.Length / r.Width) yCount = math.Floor(con.Width / r.Height) case "ZY": zCount = math.Floor(con.Height / r.Length) yCount = math.Floor(con.Width / r.Height) xCount = math.Floor(con.Length / r.Width) } total := int(xCount * yCount * zCount) if total > maxCount && total > 0 { maxCount = total bestRotation = r bestStrategy = strategy bestLayout = generateLayout(r, xCount, yCount, zCount, strategy) boxVolume := r.Length * r.Width * r.Height bestUsedVolume = float64(total) * boxVolume bestDensity = (bestUsedVolume / conVolume) * 100 bestSpaceUtilization = bestDensity } } } return bestLayout, bestRotation, bestStrategy, bestDensity, bestSpaceUtilization, bestUsedVolume } func generateRotations(box Box) []Box { return []Box{ {box.Length, box.Width, box.Height}, {box.Length, box.Height, box.Width}, {box.Width, box.Length, box.Height}, {box.Width, box.Height, box.Length}, {box.Height, box.Length, box.Width}, {box.Height, box.Width, box.Length}, } } func generateLayout(r Box, xCount, yCount, zCount float64, strategy string) []Placement { var layout []Placement switch strategy { case "XY": for x := 0.0; x < xCount; x++ { for y := 0.0; y < yCount; y++ { for z := 0.0; z < zCount; z++ { layout = append(layout, Placement{ X: x * r.Length, Y: z * r.Height, Z: y * r.Width, }) } } } case "XZ": for x := 0.0; x < xCount; x++ { for z := 0.0; z < zCount; z++ { for y := 0.0; y < yCount; y++ { layout = append(layout, Placement{ X: x * r.Length, Y: z * r.Height, Z: y * r.Width, }) } } } case "YX": for y := 0.0; y < yCount; y++ { for x := 0.0; x < xCount; x++ { for z := 0.0; z < zCount; z++ { layout = append(layout, Placement{ X: x * r.Width, Y: z * r.Height, Z: y * r.Length, }) } } } case "YZ": for y := 0.0; y < yCount; y++ { for z := 0.0; z < zCount; z++ { for x := 0.0; x < xCount; x++ { layout = append(layout, Placement{ X: x * r.Width, Y: z * r.Height, Z: y * r.Length, }) } } } case "ZX": for z := 0.0; z < zCount; z++ { for x := 0.0; x < xCount; x++ { for y := 0.0; y < yCount; y++ { layout = append(layout, Placement{ X: x * r.Width, Y: z * r.Length, Z: y * r.Height, }) } } } case "ZY": for z := 0.0; z < zCount; z++ { for y := 0.0; y < yCount; y++ { for x := 0.0; x < xCount; x++ { layout = append(layout, Placement{ X: x * r.Width, Y: z * r.Length, Z: y * r.Height, }) } } } } return layout }