The Chain

On one of the parkrun related facebook groups a while ago people were comparing the number of different parkruns they had done starting with each letter of the alphabet, sort of like an extended version of alphabet bingo. This was then followed by comparing the number of events they had done starting with the same two letters.

Inspired by this I proposed a game using the parkrun chain length, where a chain is made by using the last letter of one parkrun as the first letter of another. For me this was quite easy to work out mentally and my answer was 5. My score was soon surpassed and within a day the high score stood at 32.

For people with over 100 events to their name calculating their score would prove to be very complicated, wishing to avoid such issues myself I looked for some way of making my computer do the work for me.

I found some code on rosettacode that I was able to adapt, becuase parkruns and pokemons are very similar, to produce the following:

package main

import (
    "fmt"
    "strings"
)

var parkrun = `walsall-arboretum perry-hall cardiff pontypridd coventry swansea-bay lytham-hall conkers rosliston wolverhampton hazlehead cannock-chase rugby kingsbury-Water south-oxhey markeaton blackpool dudley  sandwell-Valley telford bryn-bach riverfront newport ruchill brueton highbury-Fields clifton cannon-hill  newcastle bevendean-down`

func main() {
    // split text into slice representing directed graph
    var d []string
    for _, l := range strings.Split(parkrun, "\n") {
        d = append(d, strings.Fields(l)...)
    }
    fmt.Println("searching", len(d), "names...")
    // try each name as possible start
    for i := range d {
        d[0], d[i] = d[i], d[0]
        search(d, 1, len(d[0]))
        d[0], d[i] = d[i], d[0]
    }
    fmt.Println("maximum path length:", len(ex))
    fmt.Println("paths of that length:", nMax)
    fmt.Print("example path of that length:")
    for i, n := range ex {
        if i%6 == 0 {
            fmt.Print("\n   ")
        }
        fmt.Print(n, " ")
    }
    fmt.Println()
}

var ex []string
var nMax int

func search(d []string, i, ncPath int) {
    // tally statistics
    if i == len(ex) {
        nMax++
    } else if i > len(ex) {
        nMax = 1
        ex = append(ex[:0], d[:i]...)
    }
    // recursive search
    lastName := d[i-1]
    lastChar := lastName[len(lastName)-1]
    for j := i; j < len(d); j++ {
        if d[j][0] == lastChar {
            d[i], d[j] = d[j], d[i]
            search(d, i+1, ncPath+1+len(d[i]))
            d[i], d[j] = d[j], d[i]
        }
    }
}

The first time I ran it the response was:

searching 30 names...
maximum path length: 5
paths of that length: 2
example path of that length:
walsall-arboretum markeaton newport telford dudley

which concurred with my own answer, so I assume it works correctly. Ideally I would let this website do all the work, but I’ve yet to find an easy way to do that so I must run this code myself each time I add a new event to my list.