I have the following code in Ruby which takes a list of 'melds' and creates a Tree Structure in order to find the best combination of melds and returns that. I am wanting to convert this code into a F# equivalent but I am having a hard time thinking of a way to do it seeing as F# doesn't have a simple way to create a Tree of nodes(at least that I know of).
I have not been working with F# for very long so I don't have a great understanding of it or a lot of knowledge in using Higher Order Functions, so if anyone would know how to convert this code it would be greatly appreciated! Thanks.
class MeldNode
attr_accessor :cards, :deadwood, :parent
def initialize(cards, parent)
@parent = parent
@cards = cards
@deadwood = count_deadwood(cards)
if (parent != nil)
@deadwood = @parent.deadwood + @deadwood
end
end
end
def build_meld_tree(melds, root_meld)
best = root_meld
melds.each do |m|
n = MeldNode.new(m, root_meld)
new_tree = build_meld_tree(clean_meld_group(melds, m), n)
best = new_tree if (best == nil) || (new_tree.deadwood > best.deadwood)
end
best
end
So taking exactly your code and porting it to F#:
type MeldNode<'a> =
{ cards : 'a; deadwood : int; parent : MeldNode<'a> option }
static member New cards (parent:MeldNode<'a> option) =
{
cards = cards;
deadwood = (Array.length cards) + (if parent.IsSome then parent.Value.deadwood else 0);
parent = parent
}
let rec buildMeldsTree rootMeld (melds:'a[] list) =
if List.isEmpty melds then None // ensure terminating case
else
melds
|> List.map (fun m ->
let n = MeldNode<'a>.New m rootMeld
buildMeldsTree (Some n) (cleanMeldGroup melds m)
)
|> List.append (if rootMeld.IsNone then [] else [ rootMeld.Value ])
|> List.maxBy (fun (n:MeldNode<'a>) -> n.deadwood)
|> Some
I saw that you updated a var called best
. F# prefers immutable vars, so using this way of getting the "best" combination meets that preference. Hope this helps!