package main import ( "bufio" "fmt" "log" "os" "strconv" "strings" ) var comps []Component // Greater than 907 func main() { inp := StdinToStrings() for i := range inp { comps = append(comps, NewComponent(inp[i])) } // Need to build chains of all permutations var perms []Bridge for i := range comps { if comps[i].Has(0) { perms = append(perms, Bridge([]Component{comps[i]})) } } changed := true for changed { perms, changed = GetNextPerms(perms) } var highB Bridge highest := 0 for _, b := range perms { if b.Value() > highest { highB = b highest = b.Value() } } fmt.Println(highB) /* for _, b := range perms { tst := GetAllThatFit(b) for i := range tst { } for tst != nil { b = b.Add(*tst) tst = GetNextBest(b) } fmt.Println(b) } */ } func GetNextPerms(perms []Bridge) ([]Bridge, bool) { var ret []Bridge var changed bool for i := range perms { if !perms[i].IsDone() { allComps := GetAllThatFit(perms[i]) if len(allComps) == 0 { ret = append(ret, perms[i].Add(NewComponent("0/0"))) } for j := range allComps { ret = append(ret, perms[i].Add(allComps[j])) changed = true } } } return ret, changed } func GetAllThatFit(b Bridge) []Component { var ret []Component port := b.Needs() for i := range comps { if comps[i].Has(port) && !b.Has(comps[i]) { ret = append(ret, comps[i]) } } return ret } func GetNextBest(b Bridge) *Component { var best *Component port := b.Needs() for i := range comps { if comps[i].Has(port) && !b.Has(comps[i]) { if best == nil || comps[i].Value() > best.Value() { best = &comps[i] } } } return best } type Bridge []Component func (b Bridge) IsDone() bool { t := []Component(b) c := t[len(t)-1] return c.Value() == 0 } func (b Bridge) Value() int { var ret int for _, v := range []Component(b) { ret += v.Value() } return ret } func (b Bridge) Has(c Component) bool { for _, v := range []Component(b) { if v.Name == c.Name { return true } } return false } func (b Bridge) Add(c Component) Bridge { b = Bridge(append([]Component(b), c)) return b } func (b Bridge) Needs() int { t := []Component(b) c := t[len(t)-1] if len(t) == 1 { return c.Other(0) } c1 := t[len(t)-2] // Find the side of c that doesn't connect with c1 if c.Has(c1.Side1) { return c.Other(c1.Side1) } return c.Other(c1.Side2) } func (b Bridge) String() string { ret := "[ " for _, v := range []Component(b) { ret += v.Name + " " } return fmt.Sprint(ret+"] ", b.Value()) } type Component struct { Name string Side1, Side2 int } func NewComponent(in string) Component { c := Component{} c.Name = in pts := strings.Split(in, "/") c.Side1 = Atoi(pts[0]) c.Side2 = Atoi(pts[1]) return c } func (c *Component) Equals(t Component) bool { return c.Side1 == t.Side1 && c.Side2 == t.Side2 } func (c *Component) Value() int { return c.Side1 + c.Side2 } func (c *Component) Has(v int) bool { return c.Side1 == v || c.Side2 == v } func (c *Component) Other(v int) int { if c.Side1 == v { return c.Side2 } return c.Side1 } func Atoi(i string) int { var ret int var err error if ret, err = strconv.Atoi(i); err != nil { log.Fatal("Invalid Atoi") } return ret } func StdinToStrings() []string { var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } return input }