diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a2465eacd3d11e4fa56c7a234db2e2e4b8b8fb35..e5587b3faf105f7f9c75a59009e2a828d44827e0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -98,8 +98,15 @@ day_4_question_1:
   stage: run
   script:
     - pipenv run python3 day_4/resolve_4_1.py
+  when: manual
 
 day_4_question_2:
   stage: run
   script:
-    - pipenv run python3 day_4/resolve_4_2.py
\ No newline at end of file
+    - pipenv run python3 day_4/resolve_4_2.py
+  when: manual
+
+day_5_question_1:
+  stage: run
+  script:
+    - pipenv run python3 day_5/resolve_5_1.py
diff --git a/day_5/resolve.material b/day_5/resolve.material
new file mode 100644
index 0000000000000000000000000000000000000000..0ac4ffdf4cf5dcdb72814d28314ebaa22ff52282
--- /dev/null
+++ b/day_5/resolve.material
@@ -0,0 +1 @@
+3,225,1,225,6,6,1100,1,238,225,104,0,1101,78,5,225,1,166,139,224,101,-74,224,224,4,224,1002,223,8,223,1001,224,6,224,1,223,224,223,1002,136,18,224,101,-918,224,224,4,224,1002,223,8,223,101,2,224,224,1,224,223,223,1001,83,84,224,1001,224,-139,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1102,55,20,225,1101,53,94,225,2,217,87,224,1001,224,-2120,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,102,37,14,224,101,-185,224,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1101,8,51,225,1102,46,15,225,1102,88,87,224,1001,224,-7656,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1101,29,28,225,1101,58,43,224,1001,224,-101,224,4,224,1002,223,8,223,1001,224,6,224,1,224,223,223,1101,93,54,225,101,40,191,224,1001,224,-133,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1101,40,79,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,226,677,224,1002,223,2,223,1005,224,329,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,344,1001,223,1,223,8,677,226,224,1002,223,2,223,1006,224,359,1001,223,1,223,1108,226,677,224,1002,223,2,223,1006,224,374,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,389,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,404,101,1,223,223,1007,226,226,224,1002,223,2,223,1006,224,419,101,1,223,223,107,677,226,224,1002,223,2,223,1006,224,434,1001,223,1,223,1007,226,677,224,102,2,223,223,1005,224,449,101,1,223,223,1107,226,226,224,1002,223,2,223,1005,224,464,1001,223,1,223,107,226,226,224,102,2,223,223,1006,224,479,101,1,223,223,108,226,226,224,1002,223,2,223,1006,224,494,101,1,223,223,107,677,677,224,102,2,223,223,1005,224,509,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,524,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,539,1001,223,1,223,108,677,226,224,102,2,223,223,1006,224,554,1001,223,1,223,1108,677,226,224,102,2,223,223,1005,224,569,1001,223,1,223,8,677,677,224,1002,223,2,223,1005,224,584,1001,223,1,223,7,677,677,224,1002,223,2,223,1005,224,599,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,614,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,629,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,644,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,659,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,674,101,1,223,223,4,223,99,226
diff --git a/day_5/resolve_5_1.py b/day_5/resolve_5_1.py
new file mode 100644
index 0000000000000000000000000000000000000000..13f3a654a5fa0b9798e91da13a3b7f4b3a5f3f44
--- /dev/null
+++ b/day_5/resolve_5_1.py
@@ -0,0 +1,186 @@
+"""Resolution for the day 5 question 1."""
+from abc import ABC, abstractmethod
+
+
+def main():
+    """Main function for day 5 question 1."""
+    data_set = get_data()
+    compute_program(data_set, 1)
+
+
+def patch_program(program, noun, verb):
+    """Apply the replaces requested."""
+    new_program = program.copy()
+    new_program[1] = noun
+    new_program[2] = verb
+    return new_program
+
+
+def get_data():
+    """Get data from file."""
+    data_set = None
+    with open("day_5/resolve.material") as material:
+        raw_data_set = material.read().replace("\n", "")
+
+        data_set = [int(data) for data in raw_data_set.split(",")]
+    return data_set
+
+
+def compute_program(program, parameter=None):
+    """Computes the given program."""
+    machine = Intcode(program, parameter)
+    machine.run_next()
+    return machine.program
+
+
+class Intcode:
+    """Defines the intcode machine."""
+
+    def __init__(self, program, program_input=None):
+        """Initializes the machine."""
+        self.program = program
+        self.parameter_pointer = 0
+        self.input = program_input
+        self.output = None
+
+    def run_next(self):
+        """Runs the next iteration for our program."""
+        if self.operation == 1:
+            action = Opcode1(self)
+            action.run()
+        elif self.operation == 2:
+            action = Opcode2(self)
+            action.run()
+        elif self.operation == 3:
+            action = Opcode3(self)
+            action.run()
+        elif self.operation == 4:
+            action = Opcode4(self)
+            action.run()
+        elif self.operation != 99:
+            raise ValueError
+
+    @property
+    def operation(self):
+        """Returns the operation."""
+        first = self.program[self.parameter_pointer]
+        operation = int(str(first)[-2:])
+        return operation
+
+
+class Opcode(ABC):
+    """Metaclass to implement opcodes."""
+
+    def __init__(self, intcode_prog):
+        """Initialize our opcode."""
+        self.intcode_prog = intcode_prog
+        self.length = 0
+
+    @property
+    def parameters(self):
+        """Returns all parameters based on length."""
+        return self.intcode_prog.program[
+            self.intcode_prog.parameter_pointer : self.intcode_prog.parameter_pointer
+            + self.length
+        ]
+
+    @property
+    def parameter_modes(self):
+        """Returns a list to know the sequence for immediate and positionnal."""
+        first = self.intcode_prog.program[self.intcode_prog.parameter_pointer]
+        parameter_modes = str(first)[:-2].zfill(self.length)
+        return parameter_modes
+
+    @property
+    def values(self):
+        """Returns for this opcode block for parameter either the real value, value at position, or value if immediate."""
+        values = []
+        for i in range(self.length):
+            value = None
+            try:
+                if self.parameter_modes[-i] == "0":
+                    value = self.intcode_prog.program[self.parameters[i]]
+                else:
+                    value = self.parameters[i]
+                values.append(value)
+            except IndexError:
+                values.append(None)
+        return values
+
+    @abstractmethod
+    def run(self):
+        """Do actions for this opcode."""
+        pass
+
+    def next(self):
+        """Sends pointer to next opcode."""
+        self.intcode_prog.parameter_pointer += self.length
+
+
+class Opcode1(Opcode):
+    """Opcode 1 is an addition."""
+
+    def __init__(self, intcode_prog):
+        """Initialize for opcode 1."""
+        super().__init__(intcode_prog)
+        self.length = 4
+
+    def run(self):
+        """Do the addititon."""
+        value_1 = self.values[1]
+        value_2 = self.values[2]
+        self.intcode_prog.program[self.parameters[3]] = value_1 + value_2
+        self.next()
+        self.intcode_prog.run_next()
+
+
+class Opcode2(Opcode):
+    """Opcode 2 is an multiplication."""
+
+    def __init__(self, intcode_prog):
+        """Initialize for opcode 2."""
+        super().__init__(intcode_prog)
+        self.length = 4
+
+    def run(self):
+        """Do the multiplication."""
+        value_1 = self.values[1]
+        value_2 = self.values[2]
+        self.intcode_prog.program[self.parameters[3]] = value_1 * value_2
+        self.next()
+        self.intcode_prog.run_next()
+
+
+class Opcode3(Opcode):
+    """Opcode 3 is parameter reading."""
+
+    def __init__(self, intcode_prog):
+        """Initialize for opcode 3."""
+        super().__init__(intcode_prog)
+        self.length = 2
+
+    def run(self):
+        """Do the insert input."""
+        self.intcode_prog.program[self.parameters[1]] = self.intcode_prog.input
+        self.next()
+        self.intcode_prog.run_next()
+
+
+class Opcode4(Opcode):
+    """Opcode 4 is parameter writing."""
+
+    def __init__(self, intcode_prog):
+        """Initialize for opcode 4."""
+        super().__init__(intcode_prog)
+        self.length = 2
+
+    def run(self):
+        """Do the save output."""
+        self.intcode_prog.output = self.values[1]
+        print(self.intcode_prog.output)
+        self.next()
+        self.intcode_prog.run_next()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/day_5/test_resolve_5_1.py b/day_5/test_resolve_5_1.py
new file mode 100644
index 0000000000000000000000000000000000000000..39aa9af4f62e960a2a9e480d7fddeac5d6ce4334
--- /dev/null
+++ b/day_5/test_resolve_5_1.py
@@ -0,0 +1,250 @@
+"""Tests for question 2 day 2."""
+import pytest
+from contextlib import nullcontext
+import copy
+from unittest.mock import patch, mock_open, MagicMock
+from day_5 import resolve_5_1
+
+
+def concreter(A):
+    """Makes an abstract class concrete."""
+    if "__abstractmethods__" not in A.__dict__:
+        return A
+    new_dict = A.__dict__.copy()
+    for abstractmethod in A.__abstractmethods__:
+        new_dict[abstractmethod] = lambda x, *args, **kwargs: (x, args, kwargs)
+    return type("dummy_concrete_{}".format(A.__name__), (A,), new_dict)
+
+
+def test_main(capsys):
+    """Test for the main function."""
+    real = None
+    resolve_5_1.main()
+
+    captured = capsys.readouterr()
+    real_raw = captured.out
+    real = real_raw.split("\n")[0:-2]
+    expected = ["0"] * len(real)
+    assert real == expected
+
+
+def test_patch_program():
+    """Test for the patch_program function."""
+    material = [0, 0, 0, 0]
+    expected = [0, 12, 2, 0]
+
+    real = resolve_5_1.patch_program(material, 12, 2)
+
+    assert real == expected
+
+
+def test_get_data():
+    """Test for the get_data function."""
+    material = "3, 4\n\n"
+    expected = [3, 4]
+
+    real = None
+    with patch("builtins.open", mock_open(read_data=material)):
+        real = resolve_5_1.get_data()
+
+    assert real == expected
+
+
+@pytest.mark.parametrize(
+    "material, expected",
+    [
+        (
+            [1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
+            [3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50],
+        ),
+        ([1, 0, 0, 0, 99], [2, 0, 0, 0, 99]),
+        ([2, 3, 0, 3, 99], [2, 3, 0, 6, 99]),
+        ([2, 4, 4, 5, 99, 0], [2, 4, 4, 5, 99, 9801]),
+        ([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99]),
+    ],
+)
+def test_compute_program(material, expected):
+    """Test for the compute_program function."""
+    real = resolve_5_1.compute_program(material)
+
+    assert real == expected
+
+
+class TestIntcode:
+    """Test the Intcode class."""
+
+    def test_init(self):
+        """Test the init function."""
+        material = [1, 2, 3, 2, 99]
+        test_object = resolve_5_1.Intcode(material)
+        assert test_object.program == material
+        assert test_object.parameter_pointer == 0
+
+    @pytest.mark.parametrize(
+        "material, expected, context",
+        [
+            ([1, 2, 3, 2, 99], [1, 2, 5, 2, 99], nullcontext()),
+            ([2, 2, 3, 2, 99], [2, 2, 6, 2, 99], nullcontext()),
+            ([5, 2, 3, 2, 99], [5, 2, 3, 2, 99], pytest.raises(ValueError)),
+        ],
+    )
+    def test_run_next(self, material, expected, context):
+        """Test the run_next function."""
+        test_object = resolve_5_1.Intcode(material)
+        with context:
+            test_object.run_next()
+        assert test_object.program == expected
+
+    @pytest.mark.parametrize(
+        "material, expected",
+        [([1, 2, 3, 2, 99], 1), ([2, 2, 3, 2, 99], 2), ([10101, 2, 3, 2, 99], 1)],
+    )
+    def test_operation(self, material, expected):
+        """Test the operation method."""
+        test_object = resolve_5_1.Intcode(material)
+        result = test_object.operation
+        assert result == expected
+
+
+class TestOpcode:
+    """Test the Opcode virtual class."""
+
+    OpcodeTester = concreter(resolve_5_1.Opcode)
+    test_material = [1, 2, 3]
+    test_intcode = resolve_5_1.Intcode(test_material)
+    test_object = OpcodeTester(test_intcode)
+
+    def test_init(self):
+        """Test the init function."""
+        assert self.test_object.length == 0
+        assert self.test_object.intcode_prog == self.test_intcode
+
+    @pytest.mark.parametrize(
+        "position, length, expected", [(0, 0, [],), (0, 1, [1]), (1, 2, [2, 3])]
+    )
+    def test_parameters(self, position, length, expected):
+        """Test the parameters virtual property."""
+        cur_test_object = copy.deepcopy(self.test_object)
+        cur_test_object.intcode_prog.parameter_pointer = position
+        cur_test_object.length = length
+        assert cur_test_object.parameters == expected
+
+    @pytest.mark.parametrize(
+        "pointer, length,program, expected",
+        [(0, 4, [10101, 2, 2, 1, 99], "0101"), (0, 4, [1, 2, 2, 1, 99], "0000")],
+    )
+    def test_parameter_modes(self, pointer, length, program, expected):
+        """Test the parameters virtual property."""
+        cur_test_object = copy.deepcopy(self.test_object)
+        cur_test_object.intcode_prog.parameter_pointer = pointer
+        cur_test_object.length = length
+        cur_test_object.intcode_prog.program = program
+        assert cur_test_object.parameter_modes == expected
+
+    @pytest.mark.parametrize(
+        "pointer, length, program, expected",
+        [
+            (0, 4, [10101, 2, 2, 1, 99], [None, 2, 2, 1]),
+            (0, 4, [1, 2, 2, 1, 99], [2, 2, 2, 2]),
+        ],
+    )
+    def test_values(self, pointer, length, program, expected):
+        """Test the parameters virtual property."""
+        cur_test_object = copy.deepcopy(self.test_object)
+        cur_test_object.intcode_prog.parameter_pointer = pointer
+        cur_test_object.length = length
+        cur_test_object.intcode_prog.program = program
+        assert cur_test_object.values == expected
+
+    @pytest.mark.parametrize(
+        "position, length, expected", [(0, 0, 0,), (0, 1, 1), (1, 2, 3)]
+    )
+    def test_next(self, position, length, expected):
+        """Test the next function."""
+        cur_test_object = copy.deepcopy(self.test_object)
+        cur_test_object.intcode_prog.parameter_pointer = position
+        cur_test_object.length = length
+        cur_test_object.next()
+        assert cur_test_object.intcode_prog.parameter_pointer == expected
+
+
+class TestOpcode1:
+    """Test the Opcode1 class."""
+
+    test_material = [1, 2, 3, 2]
+    test_intcode = resolve_5_1.Intcode(test_material)
+    test_object = resolve_5_1.Opcode1(test_intcode)
+
+    def test_init(self):
+        """Test the init function."""
+        assert self.test_object.intcode_prog == self.test_intcode
+        assert self.test_object.length == 4
+
+    def test_run(self):
+        """Test the run function."""
+        self.test_object.intcode_prog.run_next = MagicMock()
+        self.test_object.run()
+        self.test_object.intcode_prog.run_next.assert_called_once()
+        assert self.test_object.intcode_prog.program == [1, 2, 5, 2]
+
+
+class TestOpcode2:
+    """Test the Opcode2 class."""
+
+    test_material = [1, 2, 3, 2]
+    test_intcode = resolve_5_1.Intcode(test_material)
+    test_object = resolve_5_1.Opcode2(test_intcode)
+
+    def test_init(self):
+        """Test the init function."""
+        assert self.test_object.intcode_prog == self.test_intcode
+        assert self.test_object.length == 4
+
+    def test_run(self):
+        """Test the run function."""
+        self.test_object.intcode_prog.run_next = MagicMock()
+        self.test_object.run()
+        self.test_object.intcode_prog.run_next.assert_called_once()
+        assert self.test_object.intcode_prog.program == [1, 2, 6, 2]
+
+
+class TestOpcode3:
+    """Test the Opcode3 class."""
+
+    test_material = [3, 2, 3, 2]
+    test_input = 43
+    test_intcode = resolve_5_1.Intcode(test_material, test_input)
+    test_object = resolve_5_1.Opcode3(test_intcode)
+
+    def test_init(self):
+        """Test the init function."""
+        assert self.test_object.intcode_prog == self.test_intcode
+        assert self.test_object.length == 2
+
+    def test_run(self):
+        """Test the run function."""
+        self.test_object.intcode_prog.run_next = MagicMock()
+        self.test_object.run()
+        self.test_object.intcode_prog.run_next.assert_called_once()
+        assert self.test_object.intcode_prog.program == [3, 2, 43, 2]
+
+
+class TestOpcode4:
+    """Test the Opcode3 class."""
+
+    test_material = [4, 2, 3, 2]
+    test_intcode = resolve_5_1.Intcode(test_material)
+    test_object = resolve_5_1.Opcode4(test_intcode)
+
+    def test_init(self):
+        """Test the init function."""
+        assert self.test_object.intcode_prog == self.test_intcode
+        assert self.test_object.length == 2
+
+    def test_run(self):
+        """Test the run function."""
+        self.test_object.intcode_prog.run_next = MagicMock()
+        self.test_object.run()
+        self.test_object.intcode_prog.run_next.assert_called_once()
+        assert self.test_object.intcode_prog.program == [4, 2, 3, 2]
+        assert self.test_object.intcode_prog.output == 3