diff --git a/inputs/day02-example1.txt b/inputs/day02-example1.txt
new file mode 100644
index 0000000..b7172ac
--- /dev/null
+++ b/inputs/day02-example1.txt
@@ -0,0 +1,6 @@
+forward 5
+down 5
+forward 8
+up 3
+down 8
+forward 2
diff --git a/inputs/day02.txt b/inputs/day02.txt
new file mode 100644
index 0000000..feeceec
--- /dev/null
+++ b/inputs/day02.txt
@@ -0,0 +1,1000 @@
+forward 2
+down 7
+down 8
+forward 9
+down 8
+forward 9
+forward 8
+down 3
+forward 8
+forward 5
+up 2
+down 9
+down 4
+forward 4
+forward 3
+down 8
+down 9
+forward 5
+down 1
+up 1
+forward 4
+up 5
+forward 2
+down 6
+forward 9
+forward 3
+forward 7
+down 6
+down 1
+forward 8
+down 3
+forward 1
+up 6
+down 1
+down 2
+forward 9
+down 7
+down 1
+down 7
+down 7
+up 5
+down 8
+forward 6
+up 8
+up 2
+forward 6
+up 1
+down 9
+forward 8
+forward 4
+up 3
+forward 7
+down 2
+down 8
+forward 5
+down 9
+up 4
+forward 7
+forward 5
+down 5
+down 5
+forward 3
+forward 2
+down 2
+up 4
+up 7
+down 8
+up 8
+forward 1
+up 4
+forward 4
+down 2
+forward 5
+forward 7
+down 4
+forward 8
+down 2
+forward 5
+forward 9
+forward 6
+forward 5
+down 5
+forward 4
+forward 3
+down 7
+down 8
+forward 9
+forward 7
+down 3
+down 6
+forward 4
+down 7
+up 9
+down 8
+up 7
+up 3
+forward 6
+forward 9
+down 2
+down 3
+down 1
+down 3
+forward 8
+forward 3
+forward 9
+down 5
+up 1
+up 2
+down 9
+up 9
+down 5
+down 9
+forward 1
+down 3
+down 5
+down 1
+forward 7
+down 6
+forward 7
+forward 4
+up 2
+up 1
+forward 9
+down 2
+down 6
+down 5
+down 6
+forward 8
+down 5
+forward 1
+forward 2
+down 7
+down 5
+down 7
+up 9
+down 9
+up 4
+down 7
+up 8
+down 9
+forward 3
+down 6
+down 2
+forward 9
+down 4
+up 7
+forward 3
+down 5
+forward 8
+forward 9
+down 2
+up 5
+forward 2
+forward 9
+up 5
+down 2
+forward 8
+forward 6
+down 7
+down 3
+forward 4
+forward 3
+forward 9
+up 4
+up 4
+forward 7
+up 3
+forward 6
+down 7
+up 8
+forward 2
+up 1
+down 6
+forward 4
+up 6
+up 6
+up 3
+forward 4
+forward 2
+forward 5
+forward 8
+down 9
+down 4
+down 3
+down 1
+down 6
+down 4
+down 5
+down 7
+down 5
+up 4
+forward 3
+down 4
+down 7
+down 7
+down 2
+forward 2
+forward 9
+up 6
+down 3
+up 9
+forward 8
+down 9
+up 2
+up 2
+up 2
+up 1
+down 6
+forward 9
+forward 2
+forward 2
+forward 2
+forward 5
+up 3
+down 7
+down 6
+down 8
+up 3
+up 9
+down 3
+forward 1
+forward 7
+down 7
+down 1
+forward 3
+down 7
+down 9
+down 7
+down 3
+up 2
+down 6
+up 6
+down 1
+up 2
+forward 7
+up 2
+down 7
+up 2
+down 9
+down 3
+forward 6
+down 5
+down 1
+forward 5
+down 2
+down 6
+down 1
+down 3
+down 3
+down 5
+forward 2
+forward 4
+forward 8
+forward 6
+forward 4
+forward 9
+up 8
+down 5
+forward 1
+down 1
+forward 1
+forward 6
+up 1
+down 6
+down 3
+forward 9
+forward 5
+forward 4
+up 3
+up 7
+down 2
+up 4
+up 2
+down 1
+forward 6
+forward 9
+forward 4
+forward 2
+down 8
+forward 4
+forward 3
+up 5
+down 4
+forward 3
+down 8
+down 5
+down 5
+forward 1
+forward 6
+forward 4
+forward 5
+forward 9
+forward 5
+down 4
+forward 3
+forward 8
+down 8
+down 1
+up 4
+down 4
+up 7
+forward 2
+forward 6
+down 3
+down 5
+down 5
+down 8
+up 3
+down 2
+forward 4
+forward 2
+forward 4
+forward 9
+up 2
+down 7
+up 7
+down 2
+forward 4
+up 7
+forward 4
+down 2
+forward 7
+up 2
+down 3
+forward 5
+down 7
+down 2
+up 2
+up 1
+up 7
+up 9
+down 3
+forward 1
+forward 3
+down 2
+down 3
+forward 6
+down 7
+forward 9
+down 9
+forward 3
+forward 2
+down 1
+up 9
+down 4
+forward 4
+up 4
+forward 7
+up 3
+down 4
+down 9
+down 3
+forward 7
+down 6
+down 7
+down 6
+up 5
+forward 3
+forward 9
+up 2
+up 4
+up 9
+down 2
+forward 5
+up 1
+down 7
+down 5
+up 2
+forward 8
+down 8
+up 3
+forward 4
+down 9
+forward 6
+down 9
+down 5
+forward 6
+down 8
+up 6
+down 3
+forward 6
+forward 3
+down 3
+down 5
+down 7
+down 1
+down 5
+down 7
+down 5
+forward 3
+down 2
+forward 4
+up 4
+up 1
+up 7
+forward 1
+forward 5
+down 4
+down 8
+down 3
+forward 4
+down 3
+up 7
+down 6
+forward 9
+up 8
+forward 2
+forward 5
+down 6
+up 4
+forward 8
+forward 5
+down 6
+forward 2
+down 7
+forward 3
+forward 1
+forward 6
+down 9
+up 6
+down 4
+down 2
+up 8
+forward 4
+down 8
+forward 8
+up 9
+forward 7
+down 6
+up 9
+down 4
+up 6
+down 4
+down 3
+up 7
+up 4
+forward 5
+up 9
+down 9
+up 6
+down 3
+forward 8
+down 9
+forward 7
+up 3
+up 9
+forward 8
+down 3
+forward 3
+forward 5
+down 6
+forward 3
+down 4
+up 6
+forward 3
+forward 7
+down 1
+down 6
+down 4
+forward 6
+up 6
+down 5
+down 6
+down 4
+up 2
+down 7
+down 9
+down 2
+down 6
+forward 3
+forward 4
+down 5
+up 5
+down 5
+forward 3
+forward 6
+down 4
+down 7
+up 2
+forward 7
+down 7
+up 6
+up 3
+forward 9
+forward 8
+up 6
+forward 2
+down 2
+forward 8
+forward 4
+up 6
+forward 6
+down 8
+up 3
+up 5
+forward 6
+up 8
+down 1
+down 4
+up 9
+forward 6
+up 5
+down 6
+down 8
+down 9
+forward 5
+up 3
+down 7
+forward 3
+forward 6
+down 3
+down 1
+down 9
+up 9
+down 4
+down 7
+forward 2
+forward 4
+down 7
+forward 7
+up 5
+down 9
+up 7
+down 4
+forward 6
+down 5
+forward 4
+up 8
+down 4
+down 7
+forward 3
+down 6
+down 1
+forward 3
+down 4
+up 6
+up 5
+up 7
+forward 5
+down 4
+forward 7
+up 1
+down 4
+forward 4
+down 2
+down 6
+forward 1
+up 3
+up 8
+forward 6
+forward 6
+down 5
+forward 7
+down 6
+down 8
+forward 6
+down 6
+forward 3
+forward 5
+down 9
+down 5
+up 4
+down 5
+down 1
+forward 1
+forward 5
+down 2
+forward 5
+forward 2
+forward 5
+up 3
+forward 5
+up 8
+forward 9
+forward 3
+down 2
+up 2
+forward 7
+down 5
+up 1
+down 3
+down 7
+up 2
+forward 8
+forward 6
+forward 1
+forward 6
+forward 6
+down 5
+forward 4
+down 5
+forward 9
+forward 7
+down 7
+down 7
+down 9
+forward 4
+down 4
+forward 3
+down 6
+forward 5
+down 9
+forward 6
+up 7
+down 3
+up 4
+up 4
+down 1
+down 2
+up 5
+forward 6
+forward 2
+down 7
+up 6
+up 3
+down 8
+forward 1
+down 3
+up 9
+down 2
+forward 6
+forward 1
+forward 4
+up 1
+down 8
+down 2
+down 9
+down 5
+forward 3
+down 1
+down 6
+down 5
+down 3
+forward 1
+forward 9
+up 2
+down 3
+down 3
+down 9
+down 7
+forward 6
+forward 8
+forward 4
+up 7
+down 2
+forward 3
+forward 1
+up 4
+forward 8
+up 9
+forward 8
+forward 2
+down 5
+forward 2
+down 6
+down 6
+down 4
+forward 8
+down 6
+forward 2
+forward 8
+down 7
+down 6
+forward 2
+down 1
+down 8
+forward 2
+forward 9
+up 6
+forward 6
+down 3
+down 2
+up 5
+up 6
+down 6
+up 7
+forward 5
+forward 7
+down 1
+forward 7
+forward 9
+down 3
+forward 4
+forward 5
+down 1
+up 3
+forward 2
+up 5
+forward 2
+forward 1
+down 5
+down 4
+down 8
+up 8
+forward 3
+down 3
+forward 4
+down 6
+up 8
+down 5
+up 2
+down 1
+up 3
+forward 8
+up 6
+forward 9
+up 9
+down 5
+forward 2
+forward 9
+up 6
+forward 1
+down 2
+forward 4
+forward 4
+forward 1
+forward 5
+forward 1
+forward 4
+down 5
+down 1
+down 2
+down 2
+forward 7
+down 7
+down 7
+down 4
+down 7
+down 4
+down 3
+up 7
+up 1
+forward 2
+forward 3
+down 4
+down 5
+forward 9
+up 7
+forward 6
+down 1
+forward 6
+forward 6
+forward 8
+down 3
+forward 2
+down 6
+forward 9
+up 6
+up 6
+forward 7
+down 5
+down 6
+up 3
+down 5
+up 4
+forward 3
+down 7
+forward 9
+up 1
+down 1
+up 6
+down 3
+up 2
+down 5
+forward 3
+forward 6
+down 9
+down 4
+forward 7
+down 1
+up 1
+forward 3
+forward 5
+up 7
+down 3
+up 9
+up 9
+down 4
+up 4
+forward 8
+up 9
+down 8
+forward 6
+forward 4
+forward 9
+forward 8
+down 2
+forward 3
+forward 2
+down 3
+up 1
+forward 6
+down 3
+down 7
+down 3
+down 5
+down 9
+up 9
+forward 8
+forward 6
+down 8
+forward 3
+down 4
+down 2
+down 9
+forward 4
+forward 2
+up 4
+forward 1
+up 8
+up 1
+down 4
+up 2
+down 1
+up 7
+down 2
+down 4
+up 4
+forward 2
+down 3
+forward 2
+forward 3
+down 5
+forward 9
+forward 7
+down 1
+up 3
+down 3
+forward 3
+down 6
+forward 5
+up 3
+up 3
+up 1
+forward 7
+forward 1
+forward 2
+forward 2
+down 4
+up 7
+forward 1
+forward 1
+forward 6
+down 8
+up 8
+down 8
+down 4
+down 6
+forward 8
+forward 4
+forward 5
+down 2
+down 3
+forward 7
+down 6
+forward 4
+forward 1
+up 7
+up 5
+up 2
+forward 1
+forward 8
+forward 2
+up 9
+forward 4
+forward 5
+down 2
+forward 5
+forward 7
+down 3
+forward 1
+down 3
+up 5
+up 2
+up 2
+up 2
+forward 4
+forward 4
+forward 8
+forward 2
+down 3
+up 7
+down 4
+down 2
+down 7
+forward 2
+down 2
+forward 7
+up 9
+up 7
+forward 7
+forward 7
+down 3
+down 4
+up 4
+down 2
+down 8
+forward 4
+down 1
+up 6
+forward 4
+down 2
+up 8
+down 1
+down 8
+down 6
+up 9
+forward 4
+up 1
+down 2
+down 9
+down 7
+down 4
+down 8
+down 8
+up 1
+down 5
+up 5
+down 7
+up 7
+forward 5
+down 3
+forward 7
+up 5
+down 3
+forward 9
+up 5
+down 7
+forward 8
+forward 8
+down 2
+forward 7
+forward 8
+down 4
+up 7
+down 2
+up 7
+forward 5
+down 1
+down 3
+forward 9
+up 4
+forward 6
+forward 4
+down 5
+down 7
+forward 2
+forward 4
+down 2
+forward 1
+down 5
+up 2
+down 8
+down 1
+down 4
+down 8
+down 6
+forward 9
+forward 2
+forward 6
+forward 4
+down 1
+forward 8
+up 4
+forward 6
+down 4
+forward 4
+forward 3
+forward 6
+forward 9
+forward 8
+down 1
+forward 5
+down 8
+forward 7
+up 1
+down 3
+up 6
+forward 5
+forward 8
+forward 8
+forward 5
+forward 5
+forward 1
+up 9
+forward 7
+up 3
+down 2
+down 4
+forward 6
+up 2
+forward 5
+up 8
+forward 8
+forward 2
+forward 6
+forward 3
+up 4
+forward 3
+forward 6
diff --git a/puzzles/day02.py b/puzzles/day02.py
new file mode 100644
index 0000000..245b734
--- /dev/null
+++ b/puzzles/day02.py
@@ -0,0 +1,93 @@
+"""
+Advent of Code 2021 - Day 02
+
+Run with:
+    python puzzles/day02.py inputs/day02.txt
+
+This is overly complicated to keep tests similar while also using dataclasses for learning
+"""
+
+import pathlib
+import sys
+from typing import List, Tuple
+
+from dataclasses import dataclass
+
+
+@dataclass
+class Location:
+    horizontal = 0
+    depth = 0
+    aim = 0
+
+    def run(self, inputs: List[str]) -> int:
+        for line in inputs:
+            # forward 20 -> self.forward(20)
+            step = line.split()
+            getattr(self, step[0])(int(step[1]))
+
+        return self.calculate()
+
+    def calculate(self) -> int:
+        return self.horizontal * self.depth
+
+
+class Part1(Location):
+    def forward(self, distance: int) -> None:
+        self.horizontal += distance
+
+    def up(self, distance: int) -> None:
+        self.depth -= distance
+
+    def down(self, distance: int) -> None:
+        self.depth += distance
+
+
+class Part2(Location):
+    def forward(self, distance: int) -> None:
+        self.horizontal += distance
+        self.depth += self.aim * distance
+
+    def up(self, distance: int) -> None:
+        self.aim -= distance
+
+    def down(self, distance: int) -> None:
+        self.aim += distance
+
+
+def part1(inputs: List[int]) -> int:
+    puzzle = Part1()
+    return puzzle.run(inputs)
+
+
+def part2(inputs: List[int]) -> int:
+    puzzle = Part2()
+    return puzzle.run(inputs)
+
+
+def parse(inputs: str) -> List[str]:
+    """Parse the input string"""
+    return inputs.split("\n")
+
+
+def solve(path: str) -> Tuple[int, int]:
+    """Solve the puzzle"""
+    puzzle_input = parse(pathlib.Path(path).read_text().strip())
+    part1_result = part1(puzzle_input)
+    part2_result = part2(puzzle_input)
+
+    return part1_result, part2_result
+
+
+def main() -> None:
+    for path in sys.argv[1:]:
+        print(f"Input File: {path}")
+
+        part1_result, part2_result = solve(path)
+
+        print(f"Part 1 Result: {part1_result}")
+        print(f"Part 2 Result: {part2_result}")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/puzzles/test_day02.py b/puzzles/test_day02.py
new file mode 100644
index 0000000..8705b94
--- /dev/null
+++ b/puzzles/test_day02.py
@@ -0,0 +1,32 @@
+import pathlib
+import pytest
+import day02 as aoc
+
+INPUTS_DIR = f"{pathlib.Path(__file__).parent.parent}/inputs"
+
+@pytest.fixture
+def example_data():
+    input_path = f"{INPUTS_DIR}/day02-example1.txt"
+    return aoc.parse(pathlib.Path(input_path).read_text().strip())
+
+
+@pytest.fixture
+def day02_data():
+    input_path = f"{INPUTS_DIR}/day02.txt"
+    return aoc.parse(pathlib.Path(input_path).read_text().strip())
+
+
+def test_example1(example_data):
+    assert aoc.part1(example_data) == 150
+
+
+def test_example2(example_data):
+    assert aoc.part2(example_data) == 900
+
+
+def test_part1(day02_data):
+    assert aoc.part1(day02_data) == 1670340
+
+
+def test_part2(day02_data):
+    assert aoc.part2(day02_data) == 1954293920