2019-12-05 18:35:01 +01:00
import Data.List.Split
2019-12-05 20:56:16 +01:00
import Data.Char as Char
2019-12-05 18:35:01 +01:00
main = do
2019-12-05 19:11:49 +01:00
let state = [ 3 , 0 , 4 , 0 , 99 ]
let input = [ 83 ]
let output = operation state state 0 input []
mapM putStrLn ( map show output )
2019-12-05 18:35:01 +01:00
getList :: String -> [ Int ]
getList = map read . splitOn " , "
changeInput :: [ Int ] -> Int -> Int -> [ Int ]
changeInput ( begin : _ : _ : input ) input1 input2 = [ begin ] ++ [ input1 ] ++ [ input2 ] ++ input
func :: [ Int ] -> Int -> Int -> Int
func xs x y = do
let input = changeInput xs x y
2019-12-05 19:11:49 +01:00
head ( compute input input 0 [] [] )
2019-12-05 18:35:01 +01:00
2019-12-05 19:11:49 +01:00
compute :: [ Int ] -> [ Int ] -> Int -> [ Int ] -> [ Int ] -> [ Int ]
compute ( 99 : _ ) state index input output = output
compute ( op : x : y : z : _ ) state index input output =
compute ( drop newindex state ) newstate newindex input output
2019-12-05 18:35:01 +01:00
where
sum = if op == 1 then
( state !! x ) + ( state !! y )
else
( state !! x ) * ( state !! y )
split = splitAt z state
newstate = ( fst split ) ++ [ sum ] ++ ( drop 1 ( snd split ) )
newindex = index + 4
2019-12-05 19:11:49 +01:00
operation :: [ Int ] -> [ Int ] -> Int -> [ Int ] -> [ Int ] -> [ Int ]
operation ( 99 : _ ) state index input output =
2019-12-05 20:56:16 +01:00
output
operation ( op : x : y : z : _ ) state index input output
| last ( digits op ) == 1 =
operation ( drop newindex state ) newstate newindex input output
where
newindex = index + 4
newstate = add ( fillup ( revertdigs op ) 5 ) x y z state
| last ( digits op ) == 2 =
operation ( drop newindex state ) newstate newindex input output
where
newindex = index + 4
newstate = mult ( fillup ( revertdigs op ) 5 ) x y z state
| last ( digits op ) == 3 =
operation ( drop newindex state ) newstate newindex newinput output
where
newindex = index + 2
newstate = input ( fillup ( revertdigs op ) 3 ) x ( head input ) state
newinput = drop 1 input
| last ( digits op ) == 4 =
operation ( drop newindex state ) state newindex input newoutput
where
newindex = index + 2
newoutput = log ( fillup ( revertdigs op ) 3 ) ouput x state
newinput = drop 1 input
add :: [ Int ] -> Int -> Int -> Int -> [ Int ] -> [ Int ]
add ( op1 : op2 : m1 : m2 : m3 ) p1 p2 p3 state =
insert state sum index
where
sum = ( getValue m1 p1 ) + ( getValue m2 p2 )
index = getValue m3 p3
mult :: [ Int ] -> Int -> Int -> Int -> [ Int ] -> [ Int ]
mult ( op1 : op2 : m1 : m2 : m3 ) p1 p2 p3 state =
insert state sum index
where
sum = ( getValue m1 p1 ) * ( getValue m2 p2 )
index = getValue m3 p3
input :: [ Int ] -> Int -> Int -> [ Int ] -> [ Int ]
input ( op1 : op2 : m1 ) p1 input state =
insert state input ( getValue m1 p1 )
log :: [ Int ] -> [ Int ] -> Int -> [ Int ] -> [ Int ]
log ( op1 : op2 : m1 ) output p1 state =
output ++ [ ( state !! ( getValue m1 p1 ) ) ]
2019-12-05 18:35:01 +01:00
insert :: [ Int ] -> Int -> Int -> [ Int ]
insert xs value index = do
let split = splitAt index xs
( fst split ) ++ [ value ] ++ ( drop 1 ( snd split ) )
2019-12-05 20:56:16 +01:00
digits :: Int -> [ Int ]
digits = map Char . digitToInt . show
revertdigs :: Int -> [ Int ]
digs 0 = []
digs x = x ` mod ` 10 : digs ( x ` div ` 10 )
fillup :: [ Int ] -> Int -> [ Int ]
fillup array x = x ++ ( replicate ( x - ( length array ) ) 0 )
getValue :: Int -> Int -> [ Int ] -> Int
getValue 0 index array = array !! index
getValue 1 index array = index