package main import ( "bufio" "fmt" "os" "strconv" "strings" ) var ings []ingredient func main() { var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } var stringIngs []string total := 100 for i := range input { bldI := *createIngredient(input[i]) ings = append(ings, bldI) stringIngs = append(stringIngs, bldI.name) } combis := getIntCombis(total, len(stringIngs)) ingPerms := getStringPermus(stringIngs) var highVal int var highMap map[string]int for h := range combis { for i := range ingPerms { tstMap := make(map[string]int) for j := range ingPerms[i] { tstMap[ingPerms[i][j]] = combis[h][j] } tmp, cals := calcValue(tstMap) if cals == 500 && tmp > highVal { highVal = tmp highMap = tstMap fmt.Print(strconv.Itoa(tmp)) fmt.Print(" :: ") fmt.Println(tstMap) } } } fmt.Println() fmt.Println(highMap) fmt.Println("Highest Value: " + strconv.Itoa(highVal)) } func getStringPermus(vals []string) [][]string { var ret [][]string if len(vals) == 1 { return append(ret, vals) } for j := range vals { var bld []string for i := range vals { if i != j { bld = append(bld, vals[i]) } } tmp := getStringPermus(bld) for i := range tmp { tmp[i] = append([]string{vals[j]}, tmp[i]...) ret = append(ret, tmp[i]) } } return ret } func getIntCombis(total, containers int) [][]int { var ret [][]int if containers == 2 { for i := total; i >= 0; i-- { //(total / 2); i-- { ret = append(ret, []int{i, (total - i)}) } return ret } for i := total; i >= 0; i-- { //(total / 2); i-- { tmp := getIntCombis((total - i), (containers - 1)) for j := 0; j < len(tmp); j++ { tmp[j] = append([]int{i}, tmp[j]...) ret = append(ret, tmp[j]) } } return ret } func getIngredient(name string) *ingredient { for i := range ings { if ings[i].name == name { return &ings[i] } } return nil } func calcValue(list map[string]int) (int, int) { tmp := new(ingredient) for kname, v := range list { k := getIngredient(kname) tmp.capacity += k.capacity * v tmp.durability += k.durability * v tmp.flavor += k.flavor * v tmp.texture += k.texture * v tmp.calories += k.calories * v } if tmp.texture < 0 || tmp.durability < 0 || tmp.flavor < 0 || tmp.texture < 0 { return 0, 0 } return (tmp.capacity * tmp.durability * tmp.flavor * tmp.texture), tmp.calories } type ingredient struct { name string capacity int durability int flavor int texture int calories int } func createIngredient(s string) *ingredient { parts := strings.Split(s, " ") name := parts[0] name = name[:len(name)-1] c := parts[2] d := parts[4] f := parts[6] t := parts[8] cal := parts[10] i := ingredient{ name: name, capacity: mustAtoi(c[:len(c)-1]), durability: mustAtoi(d[:len(d)-1]), flavor: mustAtoi(f[:len(f)-1]), texture: mustAtoi(t[:len(t)-1]), calories: mustAtoi(cal), } return &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) } return i }