Skip to content

Commit 7046e09

Browse files
committed
solution 8.1 uploaded, 8.2 implemented but not correct
1 parent 24f889b commit 7046e09

File tree

3 files changed

+806
-5
lines changed

3 files changed

+806
-5
lines changed

7.hs

+2-4
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,8 @@ getFirst f = head . filter f
104104
getContainedBags :: Rule -> [Rule] -> Int
105105
getContainedBags b r = fix
106106
(\rec (Rule n bs) ->
107-
let res = sum
108-
$ map (\(b', n) ->
109-
n * (1+ rec (getFirst (\(Rule x _) -> x == b') r))) bs
110-
in res)
107+
sum $ map (\(b', n) ->
108+
n * (1+ rec (getFirst (\(Rule x _) -> x == b') r))) bs)
111109
$ b
112110

113111
searchForBags :: Bag -> [Rule] -> [(Bag, Int)]

8.hs

+176-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,179 @@
1+
{-# LANGUAGE DeriveGeneric #-}
2+
{-# LANGUAGE TypeApplications #-}
3+
{-# LANGUAGE ScopedTypeVariables #-}
4+
import Lib
5+
import Data.Char
6+
import Control.DeepSeq
7+
import Data.Maybe
8+
import GHC.Generics
9+
import Data.Function
10+
import Control.Monad.Fix
11+
import Debug.Trace
112

13+
dummyInput = [ "nop +0"
14+
, "acc +1"
15+
, "jmp +4"
16+
, "acc +3"
17+
, "jmp -3"
18+
, "acc -99"
19+
, "acc +1"
20+
, "jmp -4"
21+
, "acc +6" ]
222

3-
data Band a = Band (Band a) a (Band a)
23+
dummyBand = fromJust $ toBand dummyInput
24+
where toBand = sequence . map ((fmap (flip (,) False)) . parseInstruction)
425

26+
main = do
27+
let toBand = sequence . map ((fmap (flip (,) False)) . parseInstruction)
28+
dummyBand = fromJust $ toBand dummyInput
29+
--print $ toBand dummyInput
30+
--print $ runState (fixState eval dummyBand) $ EvalState 0 0
31+
32+
contents <- readFile "8.input"
33+
let band = fromJust $ toBand $ lines contents
34+
--print $ runState (fixState eval band) $ EvalState 0 0
35+
36+
putStrLn "fixing bug:"
37+
let res = untilLastExecuted band 0
38+
print res
39+
print $ (!!627) . fst $ res
40+
41+
untilLastExecuted :: Band (ArithFunc Int) -> Int -> (Band (ArithFunc Int), EvalState)
42+
untilLastExecuted band i =
43+
let result = runState (fixState eval band) $ EvalState 0 0
44+
in if (snd . last . fst $ result)
45+
then result
46+
else untilLastExecuted (changeIth i band) (i+1)
47+
48+
changeIth :: Int -> Band (ArithFunc Int) -> Band (ArithFunc Int)
49+
changeIth _ [] = []
50+
changeIth 0 ((Jmp x,b):t) = (Nop x,b) : t
51+
changeIth 0 ((Nop x,b):t) = (Jmp x,b) : t
52+
changeIth i (instr@(Jmp _,_):t) = instr : changeIth (i-1) t
53+
changeIth i (instr@(Nop _,_):t) = instr : changeIth (i-1) t
54+
changeIth i (h:t) = h : changeIth i t
55+
56+
parseArithFunc :: forall a. Read a => String -> Maybe (ArithFunc a)
57+
parseArithFunc (a:s)
58+
| a == '+' = Just $ Plus rest
59+
| a == '-' = Just $ Minus rest
60+
| a == '*' = Just $ Times rest
61+
| otherwise = Nothing
62+
where
63+
rest = read @a s
64+
65+
parseInstruction :: String -> Maybe (Instruction (ArithFunc Int))
66+
parseInstruction s = case inst of
67+
"jmp" -> Jmp <$> f
68+
"acc" -> Acc <$> f
69+
"nop" -> Nop <$> f
70+
_ -> Nothing
71+
where inst = take 3 s
72+
f = parseArithFunc $ drop 4 s
73+
74+
data Instruction a = Nop a | Acc a | Jmp a
75+
deriving (Show, Generic, Read)
76+
77+
instance NFData a => NFData (Instruction a)
78+
79+
type Band a = [(Instruction a, Bool)]
80+
81+
data EvalState = EvalState { instrPointer :: Int
82+
, accumulator :: Int }
83+
deriving (Show, Generic, Eq)
84+
85+
incr :: EvalState -> EvalState
86+
incr (EvalState i a) = EvalState (i+1) a
87+
88+
modAcc :: (Int -> Int) -> EvalState -> EvalState
89+
modAcc f (EvalState i a) = EvalState i $ f a
90+
91+
modInstr :: (Int -> Int) -> EvalState -> EvalState
92+
modInstr f (EvalState i a) = EvalState (f i) a
93+
94+
newtype State s a = State { runState :: s -> (a, s) }
95+
96+
contramap :: (a -> b) -> (a, c) -> (b, c)
97+
contramap f (a, c) = (f a, c)
98+
99+
instance Functor (State s) where
100+
f `fmap` (State s) = State $ contramap f . s
101+
102+
instance Applicative (State s) where
103+
pure a = State $ \s -> (a, s)
104+
(State s1) <*> s2 = State $ \s -> (fst . ($s) . runState $ (fst . s1) s `fmap` s2, s)
105+
106+
instance Monad (State s) where
107+
(State act) >>= f = State $ \s ->
108+
let (a, s') = act s
109+
in runState (f a) s'
110+
111+
{-
112+
instance MonadFix (State s) where
113+
mfix f = mfix $ \st -> f st
114+
-}
115+
116+
get :: State s s
117+
get = State $ \s -> (s,s)
118+
119+
put :: s -> State s ()
120+
put x = State $ \sth -> ((), x)
121+
122+
modify :: (s -> s) -> State s ()
123+
modify f = do
124+
x <- get
125+
put (f x)
126+
127+
(!!!) :: NFData a => [a] -> Int -> Maybe a
128+
(!!!) l a = deepTry (l!!) a
129+
130+
data ArithFunc a = Plus a | Minus a | Times a
131+
deriving (Show, Generic)
132+
133+
instance NFData a => NFData (ArithFunc a)
134+
135+
toFunc :: Num a => ArithFunc a -> (a -> a)
136+
toFunc (Plus a) = ((+) a)
137+
toFunc (Minus a) = (flip (-) a)
138+
toFunc (Times a) = (*a)
139+
140+
firstBy :: Eq a => (a -> a -> Bool) -> [a] -> a
141+
firstBy f (a:as) = fa as a
142+
where
143+
fa (a:as) b
144+
| f a b = b
145+
| otherwise = fa as a
146+
147+
modList :: Int -> (a -> a) -> [a] -> [a]
148+
modList i f l
149+
| length l > i = take (i) l ++ [f $ l!!i] ++ (drop (i+1) l )
150+
| otherwise = l
151+
152+
fixState :: (Eq a, Show a) => (b -> State a b) -> b -> State a b
153+
fixState action lastOutput = do
154+
last <- get
155+
newOutput <- action lastOutput
156+
new <- get
157+
if last == new --compare states
158+
then return lastOutput
159+
else fixState action newOutput
160+
{-
161+
let now = f last
162+
valNow = fst $ runState (now >> get) $ last
163+
in if valNow == last
164+
then now
165+
else fixState f valNow
166+
-}
167+
eval :: Band (ArithFunc Int) -> State EvalState (Band (ArithFunc Int))
168+
eval instructions = do
169+
s@(EvalState p a) <- get
170+
let newEval =
171+
(case instructions !!! p of
172+
Nothing -> s
173+
(Just (_, True)) -> s
174+
(Just (Nop f, _)) -> EvalState (p+1) a
175+
(Just (Acc f, _)) -> EvalState (p+1) (toFunc f $ a)
176+
(Just (Jmp f, _)) -> EvalState (toFunc f $ p) a )
177+
178+
put $ newEval
179+
return $ modList p (\(a, _) -> (a, True)) instructions

0 commit comments

Comments
 (0)