From a647a0293fab1177955e78b436e1c0fb902d41f3 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 17 Dec 2022 20:19:42 +0100 Subject: [PATCH] finish eight --- app/eight.hs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 app/eight.hs diff --git a/app/eight.hs b/app/eight.hs new file mode 100644 index 0000000..f5c75a6 --- /dev/null +++ b/app/eight.hs @@ -0,0 +1,61 @@ +import Data.Char + +type TreeHeight=Int +data Tree = Tree TreeHeight [TreeHeight] [TreeHeight] [TreeHeight] [TreeHeight] deriving(Show) + +parseTrees :: [[TreeHeight]] -> [TreeHeight] -> [[TreeHeight]] -> [Tree] +parseTrees linesAbove heights linesBelow = do + let heightsWithIndex = zipWith (,) heights [0..] + let trees=map (\heightWithIndex -> do + let (_,columnAbove) = getAlingedHeightsInColumn (linesAbove) heightWithIndex + let (_,columnBelow) = getAlingedHeightsInColumn linesBelow heightWithIndex + let (rowBefore,self:rowAfter) = splitAt (snd heightWithIndex) heights + Tree (fst heightWithIndex) columnAbove columnBelow (reverse rowBefore) rowAfter ) heightsWithIndex + let recrusiveResult = if (0 == length linesBelow) then [] else + (parseTrees (heights:linesAbove) (head linesBelow ) $ tail linesBelow) + trees <> recrusiveResult + +isVisible :: Tree -> Bool +isVisible (Tree height columnAbove columnBelow rowBefore rowAfter) = + canBeSeen columnAbove || + canBeSeen columnBelow || + canBeSeen rowBefore || + canBeSeen rowAfter + where canBeSeen = all (< height) + + +getTreeViewingScore :: Tree -> Int +getTreeViewingScore (Tree height columnAbove columnBelow rowBefore rowAfter) = + foldl (*) 1 $ map (scoreInOneDirection height) [columnBelow,columnAbove,rowAfter,rowBefore] + +scoreInOneDirection :: TreeHeight -> [TreeHeight] -> Int +scoreInOneDirection height heights =let (a,b,c) = (foldl foldFunc (-1,0,True) heights) in b + where foldFunc :: (TreeHeight,Int,Bool) -> TreeHeight -> (TreeHeight,Int,Bool) + foldFunc (currentHeight,count,canSee) nextHeight + | not canSee = (currentHeight,count,canSee) + | nextHeight >= height = (currentHeight,count+1,False) + | nextHeight >= currentHeight = (max nextHeight currentHeight,count+1,True) + | nextHeight < currentHeight = (currentHeight,count+1,True) + + + +getAlingedHeightsInColumn :: [[TreeHeight]] -> (TreeHeight,Int) -> (TreeHeight,[TreeHeight]) +getAlingedHeightsInColumn rows ((ownHeight,index)) = (ownHeight, map (!! index) rows) + +mainP1:: IO () +mainP1 = do + content <- readFile "eight-input.txt" + let (firstRow:rest) = (map digitToInt) <$> lines content + let trees = parseTrees [] firstRow rest + print $ length $ filter isVisible trees + +mainP2:: IO () +mainP2 = do + content <- readFile "eight-input.txt" + let (firstRow:rest) = (map digitToInt) <$> lines content + let trees = parseTrees [] firstRow rest + mapM (print) trees + print $ maximum $ map getTreeViewingScore trees + + +main=mainP2