158 lines
2.9 KiB
Go
158 lines
2.9 KiB
Go
|
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
|
||
|
}
|