143 lines
2.9 KiB
Go
143 lines
2.9 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var pkgWeights []int64
|
||
|
|
||
|
func main() {
|
||
|
scanner := bufio.NewScanner(os.Stdin)
|
||
|
for scanner.Scan() {
|
||
|
pkgWeights = append(pkgWeights, int64(mustAtoi(strings.ToLower(scanner.Text()))))
|
||
|
}
|
||
|
// Sort the weights, in the case of our input, no need.
|
||
|
totalWeight := weighPackages(pkgWeights)
|
||
|
// For Part 1:
|
||
|
//splitWeight := totalWeight / 3
|
||
|
// For Part 2:
|
||
|
splitWeight := totalWeight / 4
|
||
|
fmt.Printf("Balanced at %d\n", splitWeight)
|
||
|
// Now find the fewest number of packages that are that weight
|
||
|
result := tryPackages([]int64{}, pkgWeights, splitWeight)
|
||
|
fmt.Println("*** RESULT ***")
|
||
|
//result = makeUnique(result)
|
||
|
lowestQE := int64(-1)
|
||
|
shortest := -1
|
||
|
for i := range result {
|
||
|
if len(result[i]) <= shortest || shortest == -1 {
|
||
|
fmt.Print(result[i])
|
||
|
fmt.Printf(" L:%d", len(result[i]))
|
||
|
fmt.Printf(" QE:%d\n", getQE(result[i]))
|
||
|
shortest = len(result[i])
|
||
|
if getQE(result[i]) < lowestQE || lowestQE == -1 {
|
||
|
lowestQE = getQE(result[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fmt.Println()
|
||
|
fmt.Printf("%d\n", lowestQE)
|
||
|
}
|
||
|
|
||
|
func tryPackages(pkgs []int64, rem []int64, targ int64) [][]int64 {
|
||
|
// Go through all packages in 'rem' and find the combination
|
||
|
// That results in the least total number of packages
|
||
|
var findRet [][]int64
|
||
|
fewest := -1
|
||
|
if len(pkgs) > fewest && fewest != -1 {
|
||
|
return findRet
|
||
|
}
|
||
|
for i := len(rem) - 1; i >= 0; i-- {
|
||
|
t := targ - weighPackages(pkgs)
|
||
|
if rem[i] <= t {
|
||
|
tryPkgs := append(pkgs, rem[i])
|
||
|
if weighPackages(tryPkgs) == targ {
|
||
|
//if len(tryPkgs) <= fewest || fewest == -1 {
|
||
|
findRet = append(findRet, tryPkgs)
|
||
|
// fewest = len(tryPkgs)
|
||
|
//}
|
||
|
}
|
||
|
// Not there yet... Recurse
|
||
|
rem = rem[:i]
|
||
|
res := tryPackages(tryPkgs, rem, targ)
|
||
|
for i := range res {
|
||
|
if weighPackages(res[i]) == targ {
|
||
|
//if len(res[i]) <= fewest || fewest == -1 {
|
||
|
findRet = append(findRet, res[i])
|
||
|
// fewest = len(res[i])
|
||
|
//}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return findRet
|
||
|
}
|
||
|
|
||
|
func getQE(pkgs []int64) int64 {
|
||
|
var totalQE int64
|
||
|
for i := range pkgs {
|
||
|
if totalQE == 0 {
|
||
|
totalQE = int64(pkgs[i])
|
||
|
} else {
|
||
|
totalQE = totalQE * int64(pkgs[i])
|
||
|
}
|
||
|
}
|
||
|
return totalQE
|
||
|
}
|
||
|
|
||
|
func weighPackages(pkgs []int64) int64 {
|
||
|
var totalWeight int64
|
||
|
for i := range pkgs {
|
||
|
totalWeight += pkgs[i]
|
||
|
}
|
||
|
return totalWeight
|
||
|
}
|
||
|
|
||
|
func makeUnique(s [][]int64) [][]int64 {
|
||
|
var ret [][]int64
|
||
|
for i := range s {
|
||
|
var found bool
|
||
|
// Check if s[i] is already in ret
|
||
|
for j := range ret {
|
||
|
if isSame(ret[j], s[i]) {
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
ret = append(ret, s[i])
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func isSame(s1 []int64, s2 []int64) bool {
|
||
|
if len(s1) != len(s2) {
|
||
|
return false
|
||
|
}
|
||
|
for i := range s1 {
|
||
|
if s1[i] != s2[i] {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func itoa(i int) string {
|
||
|
return strconv.Itoa(i)
|
||
|
}
|
||
|
|
||
|
func mustAtoi(s string) int {
|
||
|
var i int
|
||
|
var err error
|
||
|
if i, err = strconv.Atoi(s); err != nil {
|
||
|
fmt.Println("Tried to atoi " + s)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
return i
|
||
|
}
|