Done part 1
[advent-of-code-19.git] / advent17 / src / advent17.hs
diff --git a/advent17/src/advent17.hs b/advent17/src/advent17.hs
new file mode 100644 (file)
index 0000000..bef9ddf
--- /dev/null
@@ -0,0 +1,123 @@
+import Debug.Trace
+
+import Intcode
+
+import qualified Data.Text.IO as TIO
+
+import qualified Data.Map.Strict as M
+import Data.Map.Strict ((!))
+import Data.List
+import qualified Data.Set as S
+-- import Data.Char
+import Data.List
+
+type Position = (Integer, Integer) -- x, y
+type Boundary = [Position]
+data Direction = North | East | South | West deriving (Show, Eq, Ord)
+data ReturnValue = Static | Moved | Goal deriving (Show, Eq, Ord)
+
+data Droid = Droid
+    { _machine :: Machine
+    , _executionState :: ExecutionState
+    , _currentInput :: [Integer]
+    , _machineOutput :: [Integer]
+    } deriving (Eq)
+
+instance Show Droid where
+  show d = "Droid {<m>, _executionState = " ++ show (_executionState d) ++
+           ", _currentInput = " ++ show (_currentInput d) ++
+           ", _machineOutput = " ++ show (_machineOutput d) ++
+           " }"
+
+type Scaffold = S.Set Position
+
+data ScaffoldBuilder = ScaffoldBuilder { _scaffold :: Scaffold
+                     , _r :: Integer
+                     , _c :: Integer
+                     , _droidPos :: Position
+                     , _droidDirection :: Direction
+                     } deriving (Show, Eq)
+
+
+main :: IO ()
+main = do 
+        text <- TIO.readFile "data/advent17.txt"
+        let mem = parseMachineMemory text
+        -- print mem
+        let sb = buildScaffold mem
+        print $ part1 sb
+        -- print $ part2 mem
+
+
+part1 sb = S.foldl (+) 0 $ S.map alignmentParam intersections
+    where scaffold = _scaffold sb
+          intersections = S.filter (isIntersection scaffold) scaffold
+
+
+buildScaffold mem = foldl' addGridChar emptyScaffoldBuilder output
+    where (_, _, output) = runProgram [] mem
+          emptyScaffoldBuilder = ScaffoldBuilder {_scaffold = S.empty, _r = 0, _c = 0, 
+                    _droidPos = (0, 0), _droidDirection = North }
+
+
+addGridChar sb 10  = sb { _r = _r sb + 1, _c = 0 }
+addGridChar sb 46  = sb { _c = _c sb + 1 }
+addGridChar sb 35  = sb { _scaffold = S.insert (_r sb, _c sb) $ _scaffold sb, 
+                            _c = _c sb + 1 }
+addGridChar sb 94  = sb { _scaffold = S.insert (_r sb, _c sb) $ _scaffold sb, 
+                            _c = _c sb + 1,
+                            _droidPos = (_r sb, _c sb), _droidDirection = North }
+addGridChar sb 118 = sb { _scaffold = S.insert (_r sb, _c sb) $ _scaffold sb, 
+                            _c = _c sb + 1,
+                            _droidPos = (_r sb, _c sb), _droidDirection = South }
+addGridChar sb 60  = sb { _scaffold = S.insert (_r sb, _c sb) $ _scaffold sb, 
+                            _c = _c sb + 1,
+                            _droidPos = (_r sb, _c sb), _droidDirection = West }
+addGridChar sb 61  = sb { _scaffold = S.insert (_r sb, _c sb) $ _scaffold sb, 
+                            _c = _c sb + 1,
+                            _droidPos = (_r sb, _c sb), _droidDirection = East }
+
+
+isIntersection :: Scaffold -> Position -> Bool
+isIntersection scaffold (r, c) = neighbours `S.isSubsetOf` scaffold
+    where  neighbours = [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]
+
+alignmentParam :: Position -> Integer
+alignmentParam (r, c) = r * c
+
+
+-- runDroid :: Droid -> Direction -> (Droid, ReturnValue)
+-- runDroid droid direction = (droid', found)
+--     where   ci = _currentInput droid
+--             droid' = runDroidMachine (droid {_currentInput = ci ++ [commandOf direction]})
+--             found = returnValue $ last $ _machineOutput droid'
+
+
+-- runDroidMachine :: Droid -> Droid
+-- runDroidMachine d = d { _machine = machine'
+--                       , _executionState = halted
+--                       , _machineOutput = output
+--                       }
+--     where   machine = _machine d
+--             input = _currentInput d
+--             (halted, machine', output) = runMachine input machine
+
+
+showHull :: Hull -> String
+showHull screen = unlines rows
+    where   minX = minimum $ map fst $ M.keys screen
+            minY = minimum $ map snd $ M.keys screen
+            maxX = maximum $ map fst $ M.keys screen
+            maxY = maximum $ map snd $ M.keys screen
+            rows = [showHullRow screen minX maxX y | y <- [minY..maxY]]
+
+showHullRow :: Hull -> Integer -> Integer -> Integer -> String
+showHullRow screen minX maxX y = [showHullCell screen x y | x <- [minX..maxX]] 
+
+showHullCell :: Hull -> Integer -> Integer -> Char
+showHullCell screen x y = 
+    case (M.findWithDefault Unknown (x, y) screen) of 
+        Empty _ _ True -> 'O'
+        Empty _ _ _ -> '.'
+        Wall -> '\x2588'
+        Unknown -> ' '