X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=advent10%2FMain.hs;fp=advent10%2FMain.hs;h=764638fb346f83bf35161075d58235e15378b6cc;hb=e117febdb2727b50c2eb5190ad2b0ce7bf19ddbf;hp=0000000000000000000000000000000000000000;hpb=2290e80f25ae2cc821f09d1de33345bb93b664c7;p=advent-of-code-22.git diff --git a/advent10/Main.hs b/advent10/Main.hs new file mode 100644 index 0000000..764638f --- /dev/null +++ b/advent10/Main.hs @@ -0,0 +1,79 @@ +-- Writeup at https://work.njae.me.uk/2022/12/10/advent-of-code-2022-day-9/ + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take) +import Control.Applicative +import Data.List +import Data.List.Split (chunksOf) + +data Operation = Noop | Addx Int + deriving (Show, Eq) + +type Signal = (Int, Int) -- during cycle, register + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let ops = successfulParse text + let regVals = apply ops + print $ part1 regVals + putStrLn $ part2 regVals + +part1 :: [Signal] -> Int +part1 regVals = calculateSixSignals $ extractSignals regVals + +part2 :: [Signal] -> String +part2 regVals = unlines display + where pixels = map isLit regVals + rows = chunksOf 40 pixels + display = fmap (fmap showPixel) rows + +apply :: [Operation] -> [Signal] +apply ops = zip [1..] $ scanl' (+) 1 $ concatMap applyOp ops + +applyOp :: Operation -> [Int] +applyOp Noop = [0] +applyOp (Addx d) = [0, d] + +extractSignals :: [Signal] -> [Signal] +extractSignals signals = filter (\(t, _n) -> (t + 20) `mod` 40 == 0) signals + +calculateSixSignals :: [Signal] -> Int +calculateSixSignals signals = sum [ (t * n) + | (t, n) <- signals + , t <= 220 + ] + + +isLit :: Signal -> Bool +isLit (n, x) = abs (x - c) <= 1 + where c = colummOf n + +colummOf :: Int -> Int +-- colummOf n = (n - 1) `mod` 40 + 1 +colummOf n = (n - 1) `mod` 40 + +showPixel :: Bool -> Char +-- showPixel True = '#' +-- showPixel False = '.' +showPixel True = '█' +showPixel False = ' ' + +-- Parse the input file + +operationsP :: Parser [Operation] +operationP, noopP, addxP :: Parser Operation + +operationsP = operationP `sepBy` endOfLine +operationP = noopP <|> addxP +noopP = Noop <$ "noop" +addxP = Addx <$> ("addx " *> signed decimal) + +successfulParse :: Text -> [Operation] +successfulParse input = + case parseOnly operationsP input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right ops -> ops