package main import ( "bufio" "fmt" "os" "strconv" "strings" ) type container struct { value int name string } func main() { if len(os.Args) < 2 { fmt.Println("Usage: day17 ") os.Exit(1) } total := mustAtoi(os.Args[1]) var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } var containers []container for i := range input { val := mustAtoi(input[i]) // Generate a name for this container var u int for j := range containers { if containers[j].value == val { u++ } } n := strconv.Itoa(val) + "-" + strconv.Itoa(u) containers = append(containers, container{value: val, name: n}) } fmt.Println("All Containers: ") fmt.Println(containers) fmt.Println() fmt.Println("Finding Combinations...") res := findCombis(total, containers) var final [][]container fmt.Println() fmt.Println("Sorting Results...") for i := 0; i < len(res); i++ { tst := sortContainers(res[i]) var dup bool for j := 0; j < len(final); j++ { if isEqual(tst, final[j]) { dup = true } } if !dup { final = append(final, tst) } } minNum := len(final[0]) var minConfig [][]container for i := 0; i < len(final); i++ { if len(final[i]) < minNum { minNum = len(final[i]) } } for i := 0; i < len(final); i++ { if len(final[i]) == minNum { minConfig = append(minConfig, final[i]) } } fmt.Print("Total Combinations: ") fmt.Println(strconv.Itoa(len(final))) fmt.Println("Minimum Containers: " + strconv.Itoa(minNum)) fmt.Println("Num Configurations: " + strconv.Itoa(len(minConfig))) } func findCombis(total int, containers []container) [][]container { var ret [][]container for i := range containers { if total == containers[i].value { fmt.Print("O") ret = append(ret, []container{containers[i]}) } if containers[i].value < total { fmt.Print(".") bld := []container{containers[i]} var pass []container for j := range containers { if i != j { pass = append(pass, containers[j]) } } tmp := findCombis((total - containers[i].value), pass) for idx := 0; idx < len(tmp); idx++ { tmp[idx] = append(bld, tmp[idx]...) } ret = append(ret, tmp...) } } return ret } func sortContainers(c []container) []container { n := len(c) swapped := true for swapped { swapped = false for i := 1; i <= n-1; i++ { if strings.Compare(c[i-1].name, c[i].name) > 0 { tmp := c[i-1] c[i-1] = c[i] c[i] = tmp swapped = true } } n = n - 1 } return c } func isEqual(a, b []container) bool { if len(a) != len(b) { return false } for i := 0; i < len(a); i++ { if a[i].name != b[i].name { return false } } return true } 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 }