Refactor 2015 Day 07
This commit is contained in:
		
							parent
							
								
									e6e5da368a
								
							
						
					
					
						commit
						0e049e7b83
					
				@ -1,3 +1,5 @@
 | 
			
		||||
{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
 | 
			
		||||
 | 
			
		||||
import Aoc
 | 
			
		||||
import Data.Char ( isDigit )
 | 
			
		||||
import Data.Bits
 | 
			
		||||
@ -22,27 +24,27 @@ eval AND = (.&.)
 | 
			
		||||
eval SHIFTR = shiftR
 | 
			
		||||
eval SHIFTL = shiftL
 | 
			
		||||
eval CONST = const
 | 
			
		||||
eval NOT = \a _-> complement a
 | 
			
		||||
eval NOT = const' complement
 | 
			
		||||
 | 
			
		||||
eval' :: Op -> Int -> Int -> Int
 | 
			
		||||
eval' op arg1 arg2 = (.&. 0xFFFF) $ eval op arg1 arg2
 | 
			
		||||
 | 
			
		||||
eval'' :: [(String, (Op, String, String))] -> [(String, Int)] -> String -> (Int, [(String, Int)])
 | 
			
		||||
eval'' wires memos label = case lookup label memos of
 | 
			
		||||
    Just value -> (value, memos)
 | 
			
		||||
    Nothing -> case lookup label wires of
 | 
			
		||||
evalM :: [(String, (Op, String, String))] -> MemoF String Int
 | 
			
		||||
evalM wires = memoise $ \values label ->
 | 
			
		||||
    case lookup label wires of
 | 
			
		||||
        Just (op, arg1, arg2) ->
 | 
			
		||||
            let (val1, memos1) = eval'' wires memos arg1 in
 | 
			
		||||
            let (val2, memos2) = eval'' wires memos1 arg2 in
 | 
			
		||||
            let val = eval' op val1 val2 in
 | 
			
		||||
            (val, (label, val):memos2)
 | 
			
		||||
        Nothing -> (if all isDigit label then read label else undefined, memos) -- if null label then 0 else 
 | 
			
		||||
            let 
 | 
			
		||||
                (arg1', values') = evalM wires values arg1 
 | 
			
		||||
                (arg2', values'') = evalM wires values' arg2
 | 
			
		||||
            in
 | 
			
		||||
                (eval op arg1' arg2' .&. 0xFFFF, values'')
 | 
			
		||||
        Nothing ->
 | 
			
		||||
            if all isDigit label 
 | 
			
		||||
                then (read label, values)
 | 
			
		||||
                else error label
 | 
			
		||||
 | 
			
		||||
part1 :: [(String, (Op, String, String))] -> Int
 | 
			
		||||
part1 wires = fst $ eval'' wires [] "a"
 | 
			
		||||
part1 wires = unmemo (evalM wires) "a"
 | 
			
		||||
 | 
			
		||||
part2 :: [(String, (Op, String, String))] -> Int -> Int
 | 
			
		||||
part2 wires part1Answer = fst $ eval'' wires [("b", part1Answer)] "a"
 | 
			
		||||
part2 wires part1Answer = fst $ evalM wires [("b", part1Answer)] "a"
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = aocMain' parseFile (dup . part1) part2
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user