this repo has no description
1module Lib
2 ( parseComponents
3 , validBridges
4 , strongestBridge
5 , bridgeStrength
6 , longestBridges
7 ) where
8
9import Data.List.Split (splitOn)
10import Data.List
11
12parseComponents :: [String] -> [(Int, Int)]
13parseComponents = map (\s -> let p1 = read (head $ splitOn "/" s) :: Int
14 p2 = read (head . tail $ splitOn "/" s) :: Int
15 in (p1, p2))
16
17strongestBridge :: [[(Int, Int)]] -> Int
18strongestBridge = maximum . map bridgeStrength
19
20longestBridges :: [[(Int, Int)]] -> [[(Int, Int)]]
21longestBridges bs = let maxLength = maximum . map (length) $ bs
22 in filter (\b -> length b == maxLength) bs
23
24bridgeStrength :: [(Int, Int)] -> Int
25bridgeStrength [] = 0
26bridgeStrength ((x,y):xs) = x + y + bridgeStrength xs
27
28validBridges :: [(Int, Int)] -> [[(Int, Int)]]
29validBridges components = go zeroPorts
30 where zeroPorts = map (\c -> [c]) $ findZeroPorts components
31
32 go :: [[(Int, Int)]] -> [[(Int, Int)]]
33 go bridges = let newBridges = (concatMap nextSteps bridges) \\ bridges
34 in if length newBridges > 0 then go (bridges ++ newBridges)
35 else bridges
36
37 nextSteps :: [(Int, Int)] -> [[(Int, Int)]]
38 nextSteps [] = []
39 nextSteps bridge
40 | length bridge == 1 = let portToMatch = bridgeStrength bridge
41 in map (\c -> c:bridge) $ componentsForPort portToMatch (components \\ bridge)
42 | otherwise = let (p1, p2) = head bridge
43 (p1', p2') = head . tail $ bridge
44 portToMatch = if p1 == p1' || p1 == p2' then p2 else p1
45 in map (\c -> c:bridge) $ componentsForPort portToMatch (components \\ bridge)
46
47componentsForPort :: Int -> [(Int, Int)] -> [(Int, Int)]
48componentsForPort 0 _ = []
49componentsForPort p components = filter (\c -> fst c == p || snd c == p) components
50
51findZeroPorts :: [(Int, Int)] -> [(Int, Int)]
52findZeroPorts = filter (\c -> fst c == 0 || snd c == 0)