diff --git a/composer.json b/composer.json
index cad6a59..334bc26 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,9 @@
 {
     "minimum-stability": "dev",
     "prefer-stable": true,
+    "require": {
+        "beberlei/assert": "^3.2"
+    },
     "require-dev": {
         "pestphp/pest": "^0.2.3",
         "phpunit/phpunit": "^9.0"
diff --git a/composer.lock b/composer.lock
index 7756a38..d821cc4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,71 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "bfb10a7a41c18e92587c515155e29ab5",
-    "packages": [],
+    "content-hash": "aebfcacf1a8ee688656954bd83cb1c5b",
+    "packages": [
+        {
+            "name": "beberlei/assert",
+            "version": "v3.2.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/beberlei/assert.git",
+                "reference": "d63a6943fc4fd1a2aedb65994e3548715105abcf"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/beberlei/assert/zipball/d63a6943fc4fd1a2aedb65994e3548715105abcf",
+                "reference": "d63a6943fc4fd1a2aedb65994e3548715105abcf",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "php": "^7"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "*",
+                "phpstan/phpstan-shim": "*",
+                "phpunit/phpunit": ">=6.0.0 <8"
+            },
+            "suggest": {
+                "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Assert\\": "lib/Assert"
+                },
+                "files": [
+                    "lib/Assert/functions.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-2-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Richard Quadling",
+                    "email": "rquadling@gmail.com",
+                    "role": "Collaborator"
+                }
+            ],
+            "description": "Thin assertion library for input validation in business models.",
+            "keywords": [
+                "assert",
+                "assertion",
+                "validation"
+            ],
+            "time": "2019-12-19T17:51:41+00:00"
+        }
+    ],
     "packages-dev": [
         {
             "name": "doctrine/instantiator",
diff --git a/src/RomanNumeralsConverter.php b/src/RomanNumeralsConverter.php
new file mode 100644
index 0000000..07eabe4
--- /dev/null
+++ b/src/RomanNumeralsConverter.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App;
+
+use Assert\Assert;
+
+final class RomanNumeralsConverter
+{
+    private static $map = [
+        1000 => 'M',
+        900 => 'CM',
+        500 => 'D',
+        400 => 'CD',
+        100 => 'C',
+        90 => 'XC',
+        50 => 'L',
+        40 => 'XL',
+        10 => 'X',
+        9 => 'IX',
+        5 => 'V',
+        4 => 'IV',
+        3 => 'III',
+        2 => 'II',
+        1 => 'I',
+    ];
+
+    public static function convert(int $input): string
+    {
+        Assert::that($input)
+            ->greaterOrEqualThan(0, 'Cannot convert negative numbers');
+
+        $letters = '';
+
+        while ($input > 0) {
+            foreach (static::$map as $number => $letter) {
+                if ($input >= $number) {
+                    // Add the appropriate numeral and reduce the value of
+                    // $input accordingly.
+                    $letters .= $letter;
+                    $input = ($input - $number);
+                    break;
+                }
+            }
+        }
+
+        return $letters;
+    }
+}
diff --git a/tests/RomanNumeralsConverterTest.php b/tests/RomanNumeralsConverterTest.php
new file mode 100644
index 0000000..d09785a
--- /dev/null
+++ b/tests/RomanNumeralsConverterTest.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+use App\RomanNumeralsConverter;
+use Assert\AssertionFailedException;
+
+it('converts numbers to roman numerals', function (int $number, string $expected): void {
+    assertSame($expected, RomanNumeralsConverter::convert($number));
+})->with([
+    [1, 'I'],
+    [2, 'II'],
+    [3, 'III'],
+    [4, 'IV'],
+    [5, 'V'],
+    [9, 'IX'],
+    [10, 'X'],
+    [15, 'XV'],
+    [19, 'XIX'],
+    [20, 'XX'],
+    [21, 'XXI'],
+    [40, 'XL'],
+    [50, 'L'],
+    [80, 'LXXX'],
+    [90, 'XC'],
+    [100, 'C'],
+    [110, 'CX'],
+    [400, 'CD'],
+    [500, 'D'],
+    [700, 'DCC'],
+    [900, 'CM'],
+    [1000, 'M'],
+    [1986, 'MCMLXXXVI'],
+    [1990, 'MCMXC'],
+    [2020, 'MMXX'],
+]);
+
+it('cannot convert negative numbers', function (): void {
+    RomanNumeralsConverter::convert(-1);
+})->throws(AssertionFailedException::class, 'Cannot convert negative numbers');