ruxo
1/19/2016 - 5:51 PM

Tree Travels

type TreeNode<'a> = 'a * 'a seq

let rec traverse (prefix: 'a list) (lookup: 'a -> TreeNode option) (x:'a, subnodes: 'a seq) :'a list seq =
  seq {
    let routes = x::prefix
    yield routes

    let nextScan = subnodes |> Seq.filter (fun x' -> not (routes |> List.contains x'))
    for n in nextScan do
      match lookup n with
      | None -> ()
      | Some node -> yield! traverse routes lookup node
  }
  
let map = [ 0; [1; 2; 3]
            1; [0]
            2; [1; 3]
            3; [1] ]
let arrayToSeq(a, b: 'a list) = a, b :> 'a seq 
let mapLookup n = map |> Seq.tryFind (fst >> (=)n) |> Option.map arrayToSeq

let possibleWays = map |> Seq.collect (arrayToSeq >> (traverse [] mapLookup)) |> Seq.toList

printfn "Possible: %A" possibleWays