From ec0e5c15b8f96c51ae2fc374cdb7167bb6c07acc Mon Sep 17 00:00:00 2001 From: Ummon Date: Tue, 12 Dec 2017 13:28:45 +0100 Subject: [PATCH] A more functional way --- AdventOfCode2017/Day12.fs | 66 ++++++++++++++------------------------- 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/AdventOfCode2017/Day12.fs b/AdventOfCode2017/Day12.fs index 1f83f1d..34c0e46 100644 --- a/AdventOfCode2017/Day12.fs +++ b/AdventOfCode2017/Day12.fs @@ -1,47 +1,27 @@ module AdventOfCode2017.Day12 open System -open System.Linq -open System.Collections.Generic - -type Graph = - { - Name : string - Neighbors : List - } - -let parseInput (lines : string[]) : (Graph * string[]) list = - [ - for line in lines do - let splitLine = line.Split ([| ' '; ',' |], StringSplitOptions.RemoveEmptyEntries) - yield { Name = splitLine.[0]; Neighbors = List () }, splitLine.[2 .. splitLine.Length - 1] - ] - -let graphCount (input : (Graph * string[]) list) = - let toVisit = Dictionary () - - for g, _ in input do - toVisit.Add (g.Name, g) - - for g, neighbors in input do - for neighbor in neighbors do - let g' = toVisit.[neighbor] - g'.Neighbors.Add g - g.Neighbors.Add g' - - let visitedGroups = List> () - - let rec visit (g : Graph) (dic : Dictionary) = - if dic.ContainsKey g.Name |> not then - toVisit.Remove g.Name |> ignore - dic.Add (g.Name, g) - for n in g.Neighbors do - visit n dic - - while toVisit.Count > 0 do - let dic = Dictionary () - visitedGroups.Add dic - visit (toVisit.First().Value) dic - - visitedGroups.First().Count, visitedGroups.Count +let parseInput (lines : string[]) : Map> = + lines + |> Array.fold ( + fun dic str -> + let l = str.Split ([| ' '; ',' |], StringSplitOptions.RemoveEmptyEntries) + dic.Add (int l.[0], l.[2 .. l.Length - 1] |> Array.map int |> Set.ofArray) + ) Map.empty + +let graphCount (g : Map>) = + + let rec visit (current : int) (visited : Set) : Set = + if visited |> Set.contains current then + Set.empty + else + seq { yield g.[current]; for neighbor in g.[current] -> visit neighbor (visited |> Set.add current) } |> Set.unionMany + + let rec nbRoots (vertices : Set) = + if Set.isEmpty vertices then + 0 + else + 1 + nbRoots (vertices - (visit (vertices |> Set.minElement) Set.empty)) + + visit 0 Set.empty |> Set.count, g |> Map.toList |> List.map fst |> Set.ofList |> nbRoots \ No newline at end of file -- 2.45.2