Skip to content

Instantly share code, notes, and snippets.

@nestordemeure
Last active April 28, 2017 08:51
Show Gist options
  • Save nestordemeure/6d5cac3ce00a2a61456c456aa9853776 to your computer and use it in GitHub Desktop.
Save nestordemeure/6d5cac3ce00a2a61456c456aa9853776 to your computer and use it in GitHub Desktop.
merge some trees
open System.Collections.Generic
type Tree = { Value : int; Children : Tree Set }
//-------------------------------------------------------------------------------------------------
/// get the primary key from a node
/// placeholder : if the value cannot be used as a primary key, this bit should be changed
let getKey tree =
tree.Value
/// gets the value given a primary key
let getValue key =
key
//-----
/// adds the nodes from a tree to a dictionnary
let addNodes (childrens:Dictionary<_,_>) tree =
let rec extract tree =
let newChildrens =
match childrens.ContainsKey (getKey tree) with
| false ->
Set.map getKey tree.Children
| true ->
tree.Children
|> Set.map getKey
|> Set.union childrens.[getKey tree]
childrens.[getKey tree] <- newChildrens
Set.iter extract tree.Children
childrens
/// rebuild a tree from a root and a dictionnary of nodes
/// stores the rebuilded nodes to avoid doing the same task twice
let rec rebuild (rebuildedTrees:Dictionary<_,_>) (childrens:Dictionary<_,_>) rootKey =
match rebuildedTrees.ContainsKey rootKey with
| true -> // this tree has already been build, no need to work twice
rebuildedTrees.[rootKey]
| false -> // unknown root : building and saving it for later retrieval
let tree = { Value = getValue rootKey; Children = Set.map (rebuild rebuildedTrees childrens) childrens.[rootKey] }
rebuildedTrees.[rootKey] <- tree
tree
//-------------------------------------------------------------------------------------------------
/// merge a list of trees and returns a list (of equal length) of merged trees
let merge treeList =
let roots = List.map getKey treeList
let childrens = List.fold addNodes (Dictionary()) treeList
let rebuildedTrees = Dictionary()
List.map (rebuild rebuildedTrees childrens) roots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment