Quest 9: Encoded in the Scales

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

Link to participate: https://everybody.codes/

  • Amy@piefed.blahaj.zone
    link
    fedilink
    English
    arrow-up
    3
    ·
    4 days ago

    Haskell

    Not particularly optimized but good enough.

    import Control.Arrow ((***))  
    import Data.Array (assocs)  
    import Data.Function (on)  
    import Data.Graph  
    import Data.List  
    import Data.Map (Map)  
    import Data.Map qualified as Map  
    import Data.Maybe  
    
    readInput :: String -> Map Int [Char]  
    readInput = Map.fromList . map ((read *** tail) . break (== ':')) . lines  
    
    findRelations :: Map Int [Char] -> Graph  
    findRelations dna =  
      buildG (1, Map.size dna)  
        . concatMap (\(x, (y, z)) -> [(x, y), (x, z)])  
        . mapMaybe (\x -> (x,) <$> findParents x)  
        $ Map.keys dna  
      where  
        findParents x =  
          find (isChild x) $  
            [(y, z) | (y : zs) <- tails $ delete x $ Map.keys dna, z <- zs]  
        isChild x (y, z) =  
          all (\(a, b, c) -> a == b || a == c) $  
            zip3 (dna Map.! x) (dna Map.! y) (dna Map.! z)  
    
    scores :: Map Int [Char] -> Graph -> [Int]  
    scores dna relations =  
      [similarity x y * similarity x z | (x, [y, z]) <- assocs relations]  
      where  
        similarity i j =  
          length . filter (uncurry (==)) $ zip (dna Map.! i) (dna Map.! j)  
    
    part1, part2, part3 :: Map Int [Char] -> Int  
    part1 = sum . (scores <*> findRelations)  
    part2 = part1  
    part3 = sum . maximumBy (compare `on` length) . components . findRelations  
    
    main = do  
      readFile "everybody_codes_e2025_q09_p1.txt" >>= print . part1 . readInput  
      readFile "everybody_codes_e2025_q09_p2.txt" >>= print . part2 . readInput  
      readFile "everybody_codes_e2025_q09_p3.txt" >>= print . part3 . readInput