diff options
author | tomsmeding <tom.smeding@gmail.com> | 2019-12-13 12:52:34 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2019-12-13 12:52:34 +0100 |
commit | 90429c61705b597aa4499e470d836efd6fa66143 (patch) | |
tree | b1bf52c75ff6f7f9594ca17ee5353bd959423fe5 | |
parent | 72b0a55c2ae0076dc3138a1c35af1bf798aa7bab (diff) |
Day 13
-rw-r--r-- | 2019/13.hs | 83 | ||||
-rw-r--r-- | 2019/13.in | 1 |
2 files changed, 84 insertions, 0 deletions
diff --git a/2019/13.hs b/2019/13.hs new file mode 100644 index 0000000..29fb9b9 --- /dev/null +++ b/2019/13.hs @@ -0,0 +1,83 @@ +{-# LANGUAGE MultiWayIf #-} +module Main where + +import Data.List +import qualified Data.Map.Strict as Map +import Data.Maybe + +import Input +import IntCode + + +blockBy :: Show a => Int -> [a] -> [[a]] +blockBy _ [] = [] +blockBy n l = case splitAt n l of + (pre, post@(_:_)) -> pre : blockBy n post + (pre, []) -> [pre] + +printMap :: (Integral i, Integral j) => Map.Map (i, i) j -> [String] +printMap mp = + let keys = Map.keys mp + (minx, maxx) = (minimum (map fst keys), maximum (map fst keys)) + (miny, maxy) = (minimum (map snd keys), maximum (map snd keys)) + in [[".#+=O" !! (fromIntegral (fromMaybe 0 (Map.lookup (x, y) mp))) + | x <- [minx..maxx]] + | y <- [miny..maxy]] + +type Pos = (Int, Int) +data AI = + AI { aiBall :: [Pos] + , aiPad :: [Int] + , aiScreen :: Map.Map Pos Int + , aiScore :: Integer } + +pos :: Integral i => (i, i) -> Pos +pos (a, b) = (fromIntegral a, fromIntegral b) + +initAI :: AI +initAI = AI [] [] Map.empty (-1) + +processOutput :: (Integer, Integer, Integer) -> AI -> AI +processOutput (-1, 0, score) ai = ai { aiScore = score } +processOutput (x, y, v) ai = + let p = pos (x, y) + removed = fromMaybe 0 (Map.lookup p (aiScreen ai)) + screen' = Map.insert (pos (x, y)) (fromIntegral v) (aiScreen ai) + ball' = if removed == 4 then aiBall ai \\ [p] else aiBall ai + ball'' = if v == 4 then p : ball' else ball' + pad' = if removed == 3 then aiPad ai \\ [fromIntegral x] else aiPad ai + pad'' = if v == 3 then fromIntegral x : pad' else pad' + in ai { aiScreen = screen', aiBall = ball'', aiPad = pad'' } + +provideInput :: AI -> Integer +provideInput ai = + case (aiBall ai, aiPad ai) of + ([(x, _)], [pad]) -> if | x < pad -> -1 + | x > pad -> 1 + | otherwise -> 0 + _ -> error "Ambiguous pad/ball!" + +main :: IO () +main = do + program <- parse . head <$> getInput 13 + + print $ let output = snd (run program []) + bd = foldl (\mp [x,y,t] -> Map.insert (x, y) t mp) + Map.empty (blockBy 3 output) + in length (filter (== 2) (Map.elems bd)) + + let program' = 2 : tail program + loop ai mcont output = do + let ai1 = foldl' (\ai' [a,b,c] -> processOutput (a, b, c) ai') ai (blockBy 3 output) + putStr "\x1B[H\x1B[2J" + putStr (unlines (printMap (aiScreen ai1))) + case mcont of + Just cont -> case runContinue cont [provideInput ai1] of + Left (cont', out) -> loop ai1 (Just cont') out + Right (_, out) -> loop ai1 Nothing out + Nothing -> return (aiScore ai1) + + score <- case runInterruptible program' [] of + Left (cont, output) -> loop initAI (Just cont) output + Right (_, output) -> loop initAI Nothing output + print score diff --git a/2019/13.in b/2019/13.in new file mode 100644 index 0000000..b3228a5 --- /dev/null +++ b/2019/13.in @@ -0,0 +1 @@ +1,380,379,385,1008,2341,437598,381,1005,381,12,99,109,2342,1101,0,0,383,1102,0,1,382,21001,382,0,1,21002,383,1,2,21102,37,1,0,1105,1,578,4,382,4,383,204,1,1001,382,1,382,1007,382,37,381,1005,381,22,1001,383,1,383,1007,383,23,381,1005,381,18,1006,385,69,99,104,-1,104,0,4,386,3,384,1007,384,0,381,1005,381,94,107,0,384,381,1005,381,108,1105,1,161,107,1,392,381,1006,381,161,1101,-1,0,384,1105,1,119,1007,392,35,381,1006,381,161,1101,1,0,384,20102,1,392,1,21101,0,21,2,21101,0,0,3,21102,138,1,0,1105,1,549,1,392,384,392,21001,392,0,1,21102,21,1,2,21101,3,0,3,21102,1,161,0,1105,1,549,1101,0,0,384,20001,388,390,1,21001,389,0,2,21101,180,0,0,1106,0,578,1206,1,213,1208,1,2,381,1006,381,205,20001,388,390,1,21001,389,0,2,21102,1,205,0,1106,0,393,1002,390,-1,390,1101,0,1,384,20102,1,388,1,20001,389,391,2,21101,0,228,0,1106,0,578,1206,1,261,1208,1,2,381,1006,381,253,21001,388,0,1,20001,389,391,2,21102,253,1,0,1106,0,393,1002,391,-1,391,1101,1,0,384,1005,384,161,20001,388,390,1,20001,389,391,2,21102,279,1,0,1106,0,578,1206,1,316,1208,1,2,381,1006,381,304,20001,388,390,1,20001,389,391,2,21101,304,0,0,1106,0,393,1002,390,-1,390,1002,391,-1,391,1102,1,1,384,1005,384,161,20102,1,388,1,21001,389,0,2,21102,1,0,3,21102,338,1,0,1105,1,549,1,388,390,388,1,389,391,389,21002,388,1,1,21001,389,0,2,21101,4,0,3,21101,0,365,0,1106,0,549,1007,389,22,381,1005,381,75,104,-1,104,0,104,0,99,0,1,0,0,0,0,0,0,344,16,18,1,1,18,109,3,22101,0,-2,1,21202,-1,1,2,21101,0,0,3,21101,0,414,0,1106,0,549,22101,0,-2,1,22101,0,-1,2,21101,0,429,0,1105,1,601,2101,0,1,435,1,386,0,386,104,-1,104,0,4,386,1001,387,-1,387,1005,387,451,99,109,-3,2106,0,0,109,8,22202,-7,-6,-3,22201,-3,-5,-3,21202,-4,64,-2,2207,-3,-2,381,1005,381,492,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,481,21202,-4,8,-2,2207,-3,-2,381,1005,381,518,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,507,2207,-3,-4,381,1005,381,540,21202,-4,-1,-1,22201,-3,-1,-3,2207,-3,-4,381,1006,381,529,21201,-3,0,-7,109,-8,2105,1,0,109,4,1202,-2,37,566,201,-3,566,566,101,639,566,566,2101,0,-1,0,204,-3,204,-2,204,-1,109,-4,2106,0,0,109,3,1202,-1,37,593,201,-2,593,593,101,639,593,593,21002,0,1,-2,109,-3,2105,1,0,109,3,22102,23,-2,1,22201,1,-1,1,21102,431,1,2,21101,653,0,3,21102,851,1,4,21102,630,1,0,1106,0,456,21201,1,1490,-2,109,-3,2105,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,2,2,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,0,2,0,1,1,0,2,0,2,2,0,2,2,0,0,2,2,0,2,2,2,2,0,2,2,2,2,0,2,0,2,2,0,2,0,2,2,2,2,0,1,1,0,0,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,2,0,0,2,0,1,1,0,0,2,2,2,2,0,2,2,2,0,2,2,0,2,2,2,2,2,2,2,2,0,2,2,0,2,0,2,2,0,2,2,2,0,1,1,0,2,2,2,0,2,0,2,0,2,2,2,0,0,0,2,0,2,2,2,2,2,2,0,2,0,2,0,2,2,2,2,2,2,0,1,1,0,2,2,2,2,2,2,0,2,0,2,0,0,0,2,0,2,2,2,2,0,2,2,0,2,2,0,2,2,0,0,2,2,0,0,1,1,0,2,0,0,2,2,0,2,2,2,0,0,0,0,2,2,2,2,2,2,0,0,0,2,0,2,2,2,2,2,0,0,0,0,0,1,1,0,2,0,0,2,2,0,0,2,2,2,2,2,2,2,2,0,2,0,2,2,0,2,2,2,0,2,0,2,2,0,2,2,2,0,1,1,0,0,2,2,2,2,2,0,2,2,0,0,0,0,2,2,2,2,0,2,2,0,2,2,0,2,0,0,2,2,2,2,2,2,0,1,1,0,2,0,2,0,2,2,0,2,0,0,2,2,2,0,0,2,2,0,2,0,2,2,2,0,2,2,2,2,0,2,2,0,0,0,1,1,0,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,0,0,2,2,2,2,0,0,1,1,0,2,0,2,2,0,0,0,0,2,2,2,2,0,2,2,0,0,2,0,2,0,2,0,2,0,2,0,0,2,0,2,2,2,0,1,1,0,2,0,2,2,2,2,0,2,2,0,2,2,2,0,2,0,2,0,2,0,2,2,2,2,0,2,2,2,0,2,2,0,0,0,1,1,0,2,2,2,0,2,2,0,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,0,2,2,2,0,2,2,2,2,0,0,2,2,2,0,2,0,2,2,0,0,2,2,2,0,2,2,0,2,2,2,2,2,2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,68,85,54,62,55,66,45,25,17,78,41,1,66,35,5,38,72,17,31,57,18,19,35,53,33,17,10,15,46,71,34,46,84,46,71,81,9,64,73,66,65,89,6,86,23,81,19,13,59,12,2,83,74,11,82,9,80,27,22,85,92,3,91,79,47,85,68,45,39,50,80,14,7,34,68,98,67,63,10,15,40,85,3,87,14,91,76,37,45,78,77,8,64,62,83,74,48,54,61,76,5,89,27,96,78,60,86,45,97,11,21,62,49,52,24,74,23,19,82,28,6,14,1,14,45,37,13,9,61,74,67,18,62,13,6,24,27,67,60,80,68,25,53,80,31,67,41,8,93,23,93,95,6,47,4,25,33,45,56,37,12,62,75,85,42,83,16,40,78,38,87,1,96,18,73,96,91,29,44,58,47,71,90,28,74,12,97,15,32,86,9,81,54,92,94,95,36,34,67,48,71,57,60,39,50,31,7,58,5,43,63,98,55,56,87,83,70,92,63,51,72,11,73,26,94,81,62,38,15,92,4,38,91,32,12,34,26,46,46,54,51,16,36,98,65,68,79,65,3,34,6,24,70,49,27,78,41,50,38,46,23,27,53,11,45,5,24,94,56,56,40,85,13,52,36,86,31,92,16,72,66,77,12,5,2,7,56,7,88,67,49,31,73,10,19,83,87,96,47,86,35,91,38,85,24,6,32,78,20,28,88,8,5,97,9,17,32,91,52,74,92,13,92,1,35,62,68,17,44,4,51,93,61,60,65,46,52,91,7,85,78,28,68,31,16,7,70,10,64,56,73,57,49,19,1,54,62,50,68,98,76,48,39,62,19,50,34,46,41,36,54,47,5,37,86,6,22,22,21,32,98,54,29,41,86,78,52,78,53,28,39,24,65,40,3,25,85,19,81,1,82,56,40,33,87,48,77,3,67,27,89,22,87,30,14,82,72,90,86,49,57,79,27,41,34,35,90,90,51,80,77,75,45,52,93,17,8,12,17,45,94,92,86,7,15,42,70,14,91,4,88,86,94,5,96,74,2,48,80,14,43,78,96,53,65,46,8,52,64,79,39,3,44,42,31,96,41,40,75,7,83,84,70,86,97,31,56,1,60,78,58,20,15,35,18,48,54,15,66,11,87,20,65,4,10,28,10,1,52,2,88,64,31,47,57,29,92,8,91,82,73,7,17,2,92,10,11,31,19,44,71,6,9,17,97,11,50,5,61,74,18,21,73,32,81,64,81,37,23,97,15,34,85,18,64,46,74,39,14,65,47,10,26,31,77,35,55,30,59,78,86,35,85,80,51,9,11,1,46,81,37,55,3,59,28,2,89,68,32,82,73,7,64,63,25,34,96,37,67,53,1,98,74,20,14,41,29,3,25,9,8,5,96,60,53,4,14,40,94,72,25,95,9,56,12,3,46,75,39,64,75,59,23,13,69,90,40,12,69,5,94,86,23,73,23,22,45,46,20,66,97,68,56,25,55,14,39,78,23,84,58,34,36,4,10,72,95,83,22,81,5,23,32,72,33,58,52,87,28,12,93,1,2,97,76,43,78,98,73,76,23,13,79,51,65,27,9,21,44,4,11,88,93,82,93,91,93,3,53,55,95,64,59,26,3,95,61,25,87,72,80,35,70,79,82,38,3,86,90,85,78,25,3,42,18,63,96,60,49,65,68,2,57,27,70,37,97,90,5,4,31,17,8,27,39,77,67,45,44,59,60,66,84,75,60,18,61,71,64,92,97,43,25,94,7,50,67,78,43,93,66,25,27,5,93,2,4,85,21,9,84,67,6,81,93,16,38,90,84,29,41,38,95,75,5,41,28,16,7,8,33,13,64,60,18,93,58,74,45,49,4,33,24,43,76,38,3,32,36,3,32,3,64,96,85,19,80,56,96,65,83,12,27,64,91,14,65,52,8,49,48,437598 |