39 lines
1.2 KiB
Haskell
39 lines
1.2 KiB
Haskell
import GHC.Utils.Misc (chunkList)
|
|
|
|
data Instruction = Add Int | Noop
|
|
deriving (Eq, Show)
|
|
|
|
crtWidth = 40
|
|
crtHeight = 6
|
|
|
|
parseInstruction :: String -> Instruction
|
|
parseInstruction s = case head split of
|
|
"addx" -> Add (read $ split !! 1)
|
|
"noop" -> Noop
|
|
instr -> error $ "unknown instruction " ++ instr
|
|
where split = words s
|
|
|
|
parse :: String -> [Instruction]
|
|
parse = map parseInstruction . lines
|
|
|
|
executeProgram :: [Instruction] -> [Int]
|
|
executeProgram = concat . scanl exec [1]
|
|
where exec :: [Int] -> Instruction -> [Int]
|
|
exec xs instr = case instr of
|
|
(Add y) -> [x, x + y]
|
|
Noop -> [x]
|
|
where x = last xs
|
|
|
|
drawScreen :: [Int] -> String
|
|
drawScreen cycles = unlines $ chunkList crtWidth $ map drawChar [0 .. (crtWidth * crtHeight - 1)]
|
|
where drawChar :: Int -> Char
|
|
drawChar i = if xDist <= 1 then '#' else '.'
|
|
where xScan = i `mod` crtWidth
|
|
xSprite = cycles !! (i)
|
|
xDist = abs (xScan - xSprite)
|
|
|
|
main = interact $
|
|
(++ "\ni hope it is understandable for this to be an exception to the \"program must output something that's copypastable into aoc's output field\" rule that i've set for myself. read!!!!\n")
|
|
. drawScreen
|
|
. executeProgram
|
|
. parse |