• # Solution en Haskell

    Posté par . En réponse au message Advent of Code, jour 13. Évalué à 2.

    Voici ma solution en Haskell.
    Pas vraiment de difficulté, j'ai factorisé le code pour résoudre les deux parties de la même manière.
    Pour les connaisseurs d'Haskell, le test isSymetry est lazy et s'arrête dès qu'il a détecté au moins une différence pour la partie 1 et deux différences pour la partie 2.
    700 microsecondes pour chacune des parties.

    module AOC2023.Day13 (solve) where
    import AOC.Prelude
    import AOC (aoc)
    import qualified Data.Vector as V
    import Data.Vector ((!))
    import AOC.Parser (Parser, sepEndBy1, some, eol)
    data Tile = Ash | Rock deriving (Eq)
    type Grid = [[Tile]]
    parser :: Parser [Grid]
    parser = (some tile `sepEndBy1` eol) `sepEndBy1` eol where
     tile = Ash <$ "." <|> Rock <$ "#"
    isSymetry :: ([Bool] -> Bool) -> Vector [Tile] -> Int -> Bool
    isSymetry check v x = check difference where
     difference = filter id $ zipWith (/=) list1 list2
     list1 = concatMap (v!) range
     list2 = concatMap (\i -> v ! (2 * x - i - 1)) range
     n = V.length v
     range = if 2 * x < n then [0..x-1] else [x..n-1]
    solveFor :: ([Bool] -> Bool) -> [Grid] -> Int
    solveFor check = sum . map score where
     score grid = (100*) <$> symetry grid <|> symetry (transpose grid) ?: 0 
     symetry grid = find (isSymetry check vgrid) [1..n-1] where
     vgrid = V.fromList grid
     n = V.length vgrid
    isSingleton :: [a] -> Bool
    isSingleton [_] = True
    isSingleton _ = False
    solve :: Text -> IO ()
    solve = aoc parser (solveFor null) (solveFor isSingleton)