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 }