diff --git a/src/Interpreter/Definitions.hs b/src/Interpreter/Definitions.hs
new file mode 100644
index 0000000000000000000000000000000000000000..b7c97b77ddf86cde71254db68deed2b84dd40ec4
--- /dev/null
+++ b/src/Interpreter/Definitions.hs
@@ -0,0 +1,13 @@
+module Interpreter.Definitions where
+
+
+data InterpreterCode = 
+    InterAdd Integer
+    | InterMov Integer
+    | InterSet Integer
+    | InterRead
+    | InterWrite
+    | InterLoop [InterpreterCode]
+    deriving (Eq, Show)
+
+type InterpreterCodeBlock = [InterpreterCode]
\ No newline at end of file
diff --git a/src/Interpreter/Interpreter.hs b/src/Interpreter/Interpreter.hs
index 8fe81cd9e95562e144334fee9d3748d9e6daa66b..3b04be35a96a0b6a6bf6c6bef754557c9d301472 100644
--- a/src/Interpreter/Interpreter.hs
+++ b/src/Interpreter/Interpreter.hs
@@ -5,6 +5,8 @@ import           Text.Trifecta
 import           Parser.LangParser
 import           Parser.Definitions
 import           Control.Monad.State
+import           Interpreter.Optimizer
+import           Interpreter.Definitions
 
 
 data InterpreterState = InterpreterState{
@@ -14,14 +16,9 @@ data InterpreterState = InterpreterState{
     offset :: Integer
 } deriving (Show)
 
-data Direction =
-    LeftDirection | RightDirection
-    deriving (Eq, Show)
-
-
 -- Initial buffer length and expanding rate
 replicaFactor :: Int
-replicaFactor = 3000
+replicaFactor = 350
 
 io :: IO a -> StateT InterpreterState IO a
 io = liftIO
@@ -34,22 +31,21 @@ prompt text = do
 
 defaultState :: InterpreterState
 defaultState = InterpreterState { buffer      = replicate replicaFactor 0
-                         , inputNumber = 0
-                         , index       = 0
-                         , offset      = 0
-                         }
+                                , inputNumber = 0
+                                , index       = 0
+                                , offset      = 0
+                                }
 
 updateListElement :: [Integer] -> Integer -> (Integer -> Integer) -> [Integer]
 updateListElement list index update = do
-    let element = update $ list !! fromInteger index
-    let (x,_:ys) = splitAt (fromInteger index) list
+    let element     = update $ list !! fromInteger index
+    let (x, _ : ys) = splitAt (fromInteger index) list
     x ++ element : ys
 
 expandIfNeeded :: [Integer] -> Integer -> [Integer]
--- Expand buffer to travel left but index is less than zero
-expandIfNeeded old_buffer (-1)      = replicate replicaFactor 0 ++ old_buffer
--- Expand buffer in need to travel Right
-expandIfNeeded old_buffer new_index = old_buffer
+expandIfNeeded old_buffer new_index
+    | new_index < 0 = replicate replicaFactor 0 ++ old_buffer
+    | new_index >= 0 =  old_buffer
     ++ needed (new_index - toInteger (length old_buffer))
   where
     needed len | len >= 0 = replicate replicaFactor 0
@@ -58,76 +54,49 @@ expandIfNeeded old_buffer new_index = old_buffer
 increaseInputNumber :: InterpreterState -> InterpreterState
 increaseInputNumber state = state { inputNumber = inputNumber state + 1 }
 
--- Fuction to update state accordingly to walk direction
-walkUpdate :: Direction -> InterpreterState -> InterpreterState
--- Walk left with buffer expnding if needed
-walkUpdate LeftDirection old_state = do
-    let update_func t = t - 1
+-- Fuction to update state accordingly to pointer movement 
+walkUpdate :: Integer -> InterpreterState -> InterpreterState
+walkUpdate steps old_state = do
+    let update_func t = t + steps
     let updated_buffer =
             expandIfNeeded (buffer old_state) (update_func $ index old_state)
     -- Finding diff because we need to update current index correctly
     let len_diff =
             toInteger $ length updated_buffer - length (buffer old_state)
-    old_state { buffer = updated_buffer
-              , index  = update_func $ index old_state + len_diff
-              , offset = update_func $ offset old_state
-              }
+    -- Finding new index of our pointer
+    let new_index = case () of
+            _ | steps < 0 -> update_func $ index old_state + len_diff
+              | steps > 0 -> update_func $ index old_state
 
-walkUpdate RightDirection old_state = do
-    let update_func t = t + 1
-    let updated_buffer =
-            expandIfNeeded (buffer old_state) (update_func $ index old_state)
     old_state { buffer = updated_buffer
-              , index  = update_func $ index old_state
+              , index  = new_index
               , offset = update_func $ offset old_state
               }
 
 updateStateCell :: (Integer -> Integer) -> InterpreterState -> InterpreterState
 updateStateCell update_func old_state = do
-    let new_buffer = updateListElement (buffer old_state) (index old_state) update_func
-    old_state{
-        buffer = new_buffer
-    }
+    let new_buffer =
+            updateListElement (buffer old_state) (index old_state) update_func
+    old_state { buffer = new_buffer }
 
-updateCell :: (Integer->Integer) -> StateT InterpreterState IO ()
+updateCell :: (Integer -> Integer) -> StateT InterpreterState IO ()
 updateCell update_func = modify (updateStateCell update_func)
 
-walk :: Direction -> StateT InterpreterState IO ()
-walk direction = do
-    modify (walkUpdate direction)
+walk :: Integer -> StateT InterpreterState IO ()
+walk steps = do
+    modify (walkUpdate steps)
     return ()
 
 doAction :: REPLCode -> State InterpreterState ()
 doAction = undefined
 
 
-getBufferSlice :: Integer -> Integer ->  [Integer] -> [Integer]
+getBufferSlice :: Integer -> Integer -> [Integer] -> [Integer]
 getBufferSlice size current_index current_buffer = do
-    let start        = fromInteger $ current_index - size
-    let end          = fromInteger $ current_index + size
+    let start = fromInteger $ current_index - size
+    let end   = fromInteger $ current_index + size
     drop start $ take end current_buffer
 
-runHelper :: REPLHelpers -> StateT InterpreterState IO ()
-runHelper PrintState = do
-    current_state <- get
-    let buffer_slice = getBufferSlice 5 (index current_state) (buffer current_state)
-    io $ putStrLn $ "Current index: " ++ show (index current_state)
-    io $ putStrLn $ "Offset from start: " ++ show (offset current_state)
-    io $ putStrLn $ "part of curren buffer: \n" ++ show buffer_slice
-    return ()
-
-runHelper PrintBuf = do
-    current_state <- get
-    let buffer_slice = getBufferSlice 5 (index current_state) (buffer current_state)
-    io $ print buffer_slice
-    return ()
-
-runHelper PrintBufChars  = do
-    current_state <- get
-    let buffer_slice = getBufferSlice 5 (index current_state) (buffer current_state)
-    io $ print $ map (\t -> toEnum (fromInteger t) :: Char) buffer_slice
-    return ()
-
 getCell :: StateT InterpreterState IO Integer
 getCell = do
     state <- get
@@ -146,29 +115,30 @@ readCell = do
     updateCell (const $ toInteger $ fromEnum char)
     return ()
 
-runBrainCodeLoop :: BrainBreakBlock -> StateT InterpreterState IO ()
-runBrainCodeLoop  code = do
+runInterpreterLoop :: InterpreterCodeBlock -> StateT InterpreterState IO ()
+runInterpreterLoop code = do
     cell <- getCell
     case cell of
-        0 -> return ()
-        val -> runBrainBreakCode code
+        0   -> return ()
+        val -> runInterpreterCode code
     cell <- getCell
-    case cell of 
-        0 -> return ()
-        val -> runBrainCodeLoop code
-
-runBrainBreakOperation :: BrainBreakOperation -> StateT InterpreterState IO ()
-runBrainBreakOperation MoveLeft         = walk LeftDirection
-runBrainBreakOperation MoveRight        = walk RightDirection
-runBrainBreakOperation Increment        = updateCell (+1)
-runBrainBreakOperation Decrement        = updateCell (\t -> t - 1)
-runBrainBreakOperation Write            = printCell
-runBrainBreakOperation Read             = readCell
-runBrainBreakOperation (Loop code)      = runBrainCodeLoop code
-runBrainBreakOperation Comment          = return ()
+    case cell of
+        0   -> return ()
+        val -> runInterpreterLoop code
+
+runInterpreterOperation :: InterpreterCode -> StateT InterpreterState IO ()
+runInterpreterOperation (InterAdd value) = updateCell (+ value)
+runInterpreterOperation (InterMov step ) = walk step
+runInterpreterOperation (InterSet value) = updateCell (const value)
+runInterpreterOperation InterRead        = readCell
+runInterpreterOperation InterWrite       = printCell
+runInterpreterOperation (InterLoop code) = runInterpreterLoop code
+
+runInterpreterCode :: InterpreterCodeBlock -> StateT InterpreterState IO ()
+runInterpreterCode (x : xs) = do
+    runInterpreterOperation x
+    runInterpreterCode xs
+runInterpreterCode _ = return ()
 
 runBrainBreakCode :: BrainBreakBlock -> StateT InterpreterState IO ()
-runBrainBreakCode (x : xs) = do
-    runBrainBreakOperation x
-    runBrainBreakCode xs
-runBrainBreakCode [] = return ()
+runBrainBreakCode = runInterpreterCode . optimize
diff --git a/src/Interpreter/Optimizer.hs b/src/Interpreter/Optimizer.hs
index 66af1c1497d26a9ca5cfde0e9187ac8d3a020db6..4061bac3caf9a56d36ae2e885691ac2da1ebc293 100644
--- a/src/Interpreter/Optimizer.hs
+++ b/src/Interpreter/Optimizer.hs
@@ -1,5 +1,11 @@
-module Interpreter.Optimizer where 
+module Interpreter.Optimizer
+    ( optimize
+    )
+where
 
+import           Parser.Definitions
+import           Parser.LangParser
+import           Interpreter.Definitions
 {- 
 Optiomization plans:
  * Instruction merging
@@ -29,4 +35,71 @@ Optiomization plans:
     [-]+++ => Set 0, Add 3 => Set 3
     +++[-] => Set 0
     Also sequential Set instructions may be merged.
--}
\ No newline at end of file
+-}
+
+mapCodes :: BrainBreakOperation -> InterpreterCode
+mapCodes Increment          = InterAdd 1
+mapCodes Decrement          = InterAdd (-1)
+mapCodes MoveRight          = InterMov 1
+mapCodes MoveLeft           = InterMov (-1)
+mapCodes Read               = InterRead
+mapCodes Write              = InterWrite
+mapCodes (Loop [Decrement]) = InterSet 0
+mapCodes (Loop vals       ) = InterLoop $ map mapCodes $ filterComments vals
+
+
+canBeMerged :: InterpreterCode -> InterpreterCode -> Bool
+canBeMerged (InterMov  _) (InterMov  _) = True
+canBeMerged (InterAdd  _) (InterAdd  _) = True
+canBeMerged (InterSet  _) (InterSet  _) = True
+canBeMerged (InterSet  _) (InterAdd  _) = True
+canBeMerged (InterAdd  _) (InterSet  _) = True
+canBeMerged (InterLoop _) (InterLoop _) = True
+canBeMerged _             _             = False
+
+
+mergeOperations :: InterpreterCode -> InterpreterCode -> InterpreterCode
+mergeOperations (InterMov  a) (InterMov  b) = InterMov (a + b)
+mergeOperations (InterAdd  a) (InterAdd  b) = InterAdd (a + b)
+mergeOperations (InterSet  a) (InterSet  b) = InterSet b
+mergeOperations (InterSet  a) (InterAdd  b) = InterSet (a + b)
+mergeOperations (InterAdd  a) (InterSet  b) = InterSet b
+mergeOperations (InterLoop a) (InterLoop b) = InterLoop a
+mergeOperations _             _             = error "Operations can't be merged"
+
+isNoAction :: InterpreterCode -> Bool
+isNoAction action | action == InterMov 0   = True
+                  | action == InterAdd 0   = True
+                  | action == InterLoop [] = True
+                  | otherwise              = False
+
+isOpositeMovement :: InterpreterCode -> InterpreterCode -> Bool
+isOpositeMovement (InterMov 1) (InterMov (-1)) = True
+isOpositeMovement _            _               = False
+
+optimizer
+    :: InterpreterCodeBlock -> InterpreterCodeBlock -> InterpreterCodeBlock
+optimizer processed []    = processed
+optimizer []        other = optimizer [head other] (tail other)
+optimizer processed (x : xs)
+    | canBeMerged (last processed) x = optimizer
+        (init processed ++ [mergeOperations (last processed) x])
+        xs
+    | otherwise = optimizer (processed ++ [x]) xs
+
+
+removeStartLoops :: InterpreterCodeBlock -> InterpreterCodeBlock
+removeStartLoops [] = []
+removeStartLoops (x : xs) | canBeMerged x (InterLoop []) = removeStartLoops xs
+                          | otherwise                    = xs
+
+preprocess :: BrainBreakBlock -> InterpreterCodeBlock
+preprocess = map mapCodes
+
+optimize :: BrainBreakBlock -> InterpreterCodeBlock
+optimize =
+    filter (not . isNoAction)
+        . optimizer []
+        . removeStartLoops
+        . preprocess
+        . filterComments
diff --git a/src/Interpreter/REPL.hs b/src/Interpreter/REPL.hs
index a05b28a19f835660e3176d487845b5a3620a34dc..78f2a78b30535873c93b1aa44b26322a3c50b186 100644
--- a/src/Interpreter/REPL.hs
+++ b/src/Interpreter/REPL.hs
@@ -7,6 +7,29 @@ import           Parser.Definitions
 import           Control.Monad.State
 import           Interpreter.Interpreter
 
+runHelper :: REPLHelpers -> StateT InterpreterState IO ()
+runHelper PrintState = do
+    current_state <- get
+    let buffer_slice =
+            getBufferSlice 5 (index current_state) (buffer current_state)
+    io $ putStrLn $ "Current index: " ++ show (index current_state)
+    io $ putStrLn $ "Offset from start: " ++ show (offset current_state)
+    io $ putStrLn $ "part of curren buffer: \n" ++ show buffer_slice
+    return ()
+
+runHelper PrintBuf = do
+    current_state <- get
+    let buffer_slice =
+            getBufferSlice 5 (index current_state) (buffer current_state)
+    io $ print buffer_slice
+    return ()
+
+runHelper PrintBufChars = do
+    current_state <- get
+    let buffer_slice =
+            getBufferSlice 5 (index current_state) (buffer current_state)
+    io $ print $ map (\t -> toEnum (fromInteger t) :: Char) buffer_slice
+    return ()
 
 
 replCodeRunner :: REPLCode -> StateT InterpreterState IO ()