adventofcode/2015/day24/main.go
2016-12-16 16:21:15 -06:00

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
}