# Pastebin 9bL24qdo follow :: Dir -> [Knot] -> [Knot] follow dir = para (\case Nil -> [] Cons (Knot hp hs) ([], _) -> let np = fwd dir hp in [Knot np (Set.insert np hs)] Cons ex@(Knot hp _) (rest@(Knot p s:_), remaining) | touching hp p -> ex:remaining | otherwise -> let np = towardsHead p hp in Knot np (Set.insert np s) : rest) where towardsHead tp@(tx,ty) hp@(hx,hy) | tx == hx || ty == hy = head [p | p <- around tp, touching hp p] | otherwise = head [p | p <- diags tp, touching hp p] diags (x,y) = [(x-1,y-1), (x-1,y+1), (x+1,y+1), (x+1,y-1)] touching p1 p2 = p1 == p2 || p1 `elem` aroundD p2