package main import ( "bufio" "fmt" "os" "strconv" "strings" ) var people map[string]person func main() { var pplSlice []string people = make(map[string]person) var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } for i := range input { p := parseLine(input[i]) people[p.name] = p } for i := range people { pplSlice = append(pplSlice, people[i].name) } // Output all preferences /* for k, v := range people { fmt.Println(k) fmt.Println(" High: " + v.highName + " :: " + strconv.Itoa(v.highVal)) for pk, pv := range v.prefs { fmt.Println(" " + pk + ": " + strconv.Itoa(pv)) } } */ //getPerms(pplSlice) first := pplSlice[0] res := getPerms(pplSlice[1:]) var high int var arrangement []string for i := range res { tstArr := append([]string{first}, res[i]...) tst := happinessFromStrings(tstArr) if tst > high { high = tst arrangement = tstArr } } fmt.Println("Highest: " + strconv.Itoa(high)) fmt.Println(arrangement) } func getPerms(ppl []string) [][]string { var ret [][]string if len(ppl) == 1 { return append(ret, ppl) } for j := range ppl { var bld []string for i := range ppl { if i != j { bld = append(bld, ppl[i]) } } perms := getPerms(bld) for i := range perms { perms[i] = append([]string{ppl[j]}, perms[i]...) ret = append(ret, perms[i]) } } return ret } func happinessFromStrings(pS []string) int { var ppl []person for i := range pS { ppl = append(ppl, people[pS[i]]) } return happinessValue(ppl) } func happinessValue(ppl []person) int { var ret int for i := range ppl { p1, p2 := getNeighbors(ppl[i], ppl) ret += ppl[i].prefs[p1.name] ret += ppl[i].prefs[p2.name] } return ret } func getNeighbors(p person, ppl []person) (person, person) { var p1, p2 person for idx := range ppl { if ppl[idx].name == p.name { if idx == 0 { p1 = ppl[len(ppl)-1] p2 = ppl[idx+1] } else if idx == len(ppl)-1 { p1 = ppl[idx-1] p2 = ppl[0] } else { p1 = ppl[idx-1] p2 = ppl[idx+1] } break } } return p1, p2 } type person struct { name string prefs map[string]int highName string highVal int lowName string lowVal int } func parseLine(s string) person { parts := strings.Split(s, " ") who := parts[0] direction := parts[2] amount := mustAtoi(parts[3]) nextTo := parts[10][:len(parts[10])-1] if direction == "lose" { amount = amount * -1 } var ret person var ok bool if ret, ok = people[who]; !ok { ret = person{name: who} ret.prefs = make(map[string]int) } ret.prefs[nextTo] = amount if ret.highVal < amount || ret.highName == "" { ret.highVal, ret.highName = amount, nextTo } if ret.lowVal > amount || ret.lowName == "" { ret.lowVal, ret.lowName = amount, nextTo } return ret } 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 }