day7: it fucking works

This commit is contained in:
Arranun 2019-12-08 00:07:48 +01:00
parent f725b27953
commit f792faf44d

83
day7.hs
View File

@ -2,20 +2,19 @@ import Data.List.Split
import Data.Char as Char import Data.Char as Char
import Data.List as List import Data.List as List
import Data.Either as Either import Data.Either as Either
import Debug.Trace as Debug
main = do main = do
software <- getList <$> getContents software <- getList <$> getContents
--let output = operation state state 0 input [] --let output = operation state state 0 input []
let combs = [[9,8,7,6,5]] let combs = [[9,8,7,6,5]]
--mapM putStrLn(map show combs) --mapM putStrLn(map show combs)
mapM putStrLn(map show ( map (\x-> part2 $ prepareAmps x software ) combs )) mapM putStrLn(map show ( map (\x-> part2 ( prepareAmps x software) 0 ) combs ))
-- let output = calcthruster software [4,3,2,1,0] -- let output = calcthruster software [4,3,2,1,0]
data Amplifier = Amplifier{ state :: [Int] data Amplifier = Amplifier{ state :: [Int]
,index :: Int ,index :: Int
,input :: [Int] ,input :: [Int]
,output :: [Int] } deriving Show ,output :: [Int] } deriving Show
getList :: String -> [Int] getList :: String -> [Int]
getList = map read . splitOn "," getList = map read . splitOn ","
@ -28,25 +27,25 @@ prepareAmps (p1:p2:p3:p4:p5:_) software = do
let b = step (Amplifier software 0 [] []) [p2] let b = step (Amplifier software 0 [] []) [p2]
let c = step (Amplifier software 0 [] []) [p3] let c = step (Amplifier software 0 [] []) [p3]
let d = step (Amplifier software 0 [] []) [p4] let d = step (Amplifier software 0 [] []) [p4]
let e = step (Amplifier software 0 [] []) [p5] let e = step (Amplifier software 0 [] [0]) [p5]
let e = Amplifier (state e) (index e) (input e) [0] let e2 = Amplifier (state e) (index e) (input e) [0]
[a,b,c,d,e] [a,b,c,d,e2]
part2 :: [Amplifier] -> Int part2 :: [Amplifier] -> Int -> Int
part2 amps = do part2 amps lastOuput = do
let ampA = link (amps!!4) (amps!!0) let ampA = link (amps!!4) (amps!!0)
let ampB = link (ampA) (amps!!1) let ampB = link (ampA) (amps!!1)
let ampC = link (ampB) (amps!!2) let ampC = link (ampB) (amps!!2)
let ampD = link (ampC) (amps!!3) let ampD = link (ampC) (amps!!3)
let ampE = link (ampD) (amps!!4) let ampE = link (ampD) (amps!!4)
if state ampE == [88] if index ampE == -1
then head (output (amps!!4)) then lastOuput
else part2 (Debug.traceShowId([ampA,ampB,ampC,ampD,ampE])) else part2 ([ampA,ampB,ampC,ampD,ampE]) (head(output ampE))
link :: Amplifier -> Amplifier -> Amplifier link :: Amplifier -> Amplifier -> Amplifier
link left calc link left calc
| null (output left) = Amplifier ([88]) (index calc) (input calc) (output calc) | null (output left) = Amplifier (state calc) (-1) (input calc) (output calc)
| otherwise = step calc (Debug.traceShowId([last $ output left])) | index left == -1 = Amplifier (state calc) (-1) (input calc) (output calc)
| otherwise = step calc ([last $ output left])
step :: Amplifier -> [Int] -> Amplifier step :: Amplifier -> [Int] -> Amplifier
step amp input = operation (drop (index amp) (state amp)) (state amp) (index amp) input [] step amp input = operation (drop (index amp) (state amp)) (state amp) (index amp) input []
@ -54,7 +53,7 @@ step amp input = operation (drop (index amp) (state amp)) (state amp) (index amp
calcthrusters :: [Int] -> [Int] -> Int -> Int calcthrusters :: [Int] -> [Int] -> Int -> Int
calcthrusters software (p1:p2:p3:p4:p5:_) start = do calcthrusters software (p1:p2:p3:p4:p5:_) start = do
let outputA = operation software software 0 [p1, start] [] let outputA = operation software software 0 [p1, start] []
let outputB = operation software software 0 [p2, last $ output outputA] [] let outputB = operation software software 0 [p2, last $ output outputA] []
let outputC = operation software software 0 [p3, last $ output outputB] [] let outputC = operation software software 0 [p3, last $ output outputB] []
let outputD = operation software software 0 [p4, last $ output outputC] [] let outputD = operation software software 0 [p4, last $ output outputC] []
@ -67,51 +66,51 @@ operation (99:_) state i input output =
Amplifier state i input output Amplifier state i input output
operation (op:x:y:z:_) state i input output operation (op:x:y:z:_) state i input output
| last (digits op) == 1 = do | last (digits op) == 1 = do
let newindex = i + 4 let newindex = i + 4
let newstate = add (fillup (revertdigs op) 5) x y z state let newstate = add (fillup (revertdigs op) 5) x y z state
operation (Debug.traceShowId(drop newindex newstate)) (Debug.traceShowId(newstate)) newindex input output operation (drop newindex newstate) (newstate) newindex input output
| last (digits op) == 2 = do | last (digits op) == 2 = do
let newindex = i + 4 let newindex = i + 4
let newstate = mult (fillup (revertdigs op) 5) x y z state let newstate = mult (fillup (revertdigs op) 5) x y z state
operation (Debug.traceShowId((drop newindex newstate))) (Debug.traceShowId(newstate)) newindex input output operation ((drop newindex newstate)) (newstate) newindex input output
| last (digits op) == 3 = do | last (digits op) == 3 = do
if (Debug.traceShowId(length input)) == 0 if (length input) == 0
then (Debug.traceShowId(Amplifier state i input output)) then (Amplifier state i input output)
else do else do
let newindex = i + 2 let newindex = i + 2
let newstate = put (fillup (revertdigs op) 3) x (head input) state let newstate = put (fillup (revertdigs op) 3) x (head input) state
let newinput = drop 1 input let newinput = drop 1 input
operation (Debug.traceShowId((drop newindex newstate))) (Debug.traceShowId(newstate)) newindex newinput output operation (drop newindex newstate) (newstate) newindex newinput output
| last (digits op) == 4 = do | last (digits op) == 4 = do
let newindex = i + 2 let newindex = i + 2
let newoutput = out (fillup (revertdigs op) 3) output x state let newoutput = out (fillup (revertdigs op) 3) output x state
let newinput = drop 1 input let newinput = drop 1 input
operation (Debug.traceShowId((drop newindex state))) (Debug.traceShowId(state)) newindex input (newoutput) operation (drop newindex state) (state) newindex input (newoutput)
| (last (digits op) == 5 ) = do | (last (digits op) == 5 ) = do
let newindex = jumpif (fillup (revertdigs op) 4) x y i state let newindex = jumpif (fillup (revertdigs op) 4) x y i state
operation (Debug.traceShowId((drop newindex state))) (Debug.traceShowId(state)) newindex input output operation ((drop newindex state)) (state) newindex input output
| (last (digits op) == 6 ) = do | (last (digits op) == 6 ) = do
let newindex = jumpifnot (fillup (revertdigs op) 4) x y i state let newindex = jumpifnot (fillup (revertdigs op) 4) x y i state
operation (Debug.traceShowId((drop newindex state))) (Debug.traceShowId(state)) newindex input output operation (drop newindex state) (state) newindex input output
| (last (digits op) == 7 ) = do | (last (digits op) == 7 ) = do
let newindex = i + 4 let newindex = i + 4
let newstate = lessthan (fillup (revertdigs op) 5) x y z state let newstate = lessthan (fillup (revertdigs op) 5) x y z state
operation (Debug.traceShowId((drop newindex newstate))) (Debug.traceShowId(newstate)) newindex input output operation (drop newindex newstate) (newstate) newindex input output
| (last (digits op) == 8 ) = do | (last (digits op) == 8 ) = do
let newindex = i + 4 let newindex = i + 4
let newstate = equal (fillup (revertdigs op) 5) x y z state let newstate = equal (fillup (revertdigs op) 5) x y z state
operation (Debug.traceShowId((drop newindex newstate))) (Debug.traceShowId(newstate)) newindex input output operation (drop newindex newstate) (newstate) newindex input output
add :: [Int] -> Int -> Int -> Int -> [Int] -> [Int] add :: [Int] -> Int -> Int -> Int -> [Int] -> [Int]
add (op1:op2:m1:m2:m3:_) p1 p2 p3 state = add (op1:op2:m1:m2:m3:_) p1 p2 p3 state =
Main.insert state sum p3 Main.insert state sum p3
where where
sum = (getValue m1 p1 state) + (getValue m2 p2 state) sum = (getValue m1 p1 state) + (getValue m2 p2 state)
mult :: [Int] -> Int -> Int -> Int -> [Int] -> [Int] mult :: [Int] -> Int -> Int -> Int -> [Int] -> [Int]
mult (op1:op2:m1:m2:m3:_) p1 p2 p3 state = mult (op1:op2:m1:m2:m3:_) p1 p2 p3 state =
Main.insert state sum p3 Main.insert state sum p3
where where
sum = (getValue m1 p1 state) * (getValue m2 p2 state) sum = (getValue m1 p1 state) * (getValue m2 p2 state)
put :: [Int] -> Int -> Int -> [Int] -> [Int] put :: [Int] -> Int -> Int -> [Int] -> [Int]