philippus / julius   1.2.0

Mozilla Public License 2.0 GitHub

♊️ Roman Numerals library in Scala

Scala versions: 3.x 2.13

Julius - Roman Numerals

build codecov Current Version Scala Steward badge license

Julius is a library for working with Roman Numerals in Scala. It was started to get more comfortable with functional programming, Scala and property based testing.

It aims to:

  • provide a pleasant API to the users of the library.
  • provide the basic operations of addition, subtraction, multiplication and division.
  • do as the Romans do: the implemented algorithms are only allowed to manipulate the Roman symbols directly, so no converting back and forth from integers.
  • use idiomatic Scala
  • use functional style of programming
  • use property based testing with ScalaCheck

Installation

Julius is published for Scala 2.13 and Scala 3. To start using it add the following to your build.sbt:

libraryDependencies += "nl.gn0s1s" %% "julius" % "1.2.0"

Specification

A Roman Numeral is either the value nulla (Latin for "none") or consists of one or more Roman Digits:

romanNumeral ::= nulla | romanDigit {romanDigit}
romanDigit ::= 'M' | 'D' | 'C' | 'L' | 'X' | 'V' | 'I'

Constructing a Roman Numeral

There are several ways to construct a Roman Numeral.

Directly, by supplying a List[RomanDigit] to RomanNumeral(). This list is treated as an unordered collection of Roman Digits.

After importing RomanNumeral.RomanNumeralFromInt or RomanNumeral.RomanNumeralFromString the following ways are available:

Using the method toRomanNumeral on Int (resulting in a RomanNumeral) or String which will result in an Option[RomanNumeral]. Note that this last method expects compacted Roman Numerals (f.e. IV instead of IIII).

import nl.gn0s1s.julius.RomanDigit._
import nl.gn0s1s.julius.RomanNumeral
RomanNumeral(List(I, I, X, I)) // res0: RomanNumeral = XIII
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromInt
1666.toRomanNumeral // res1: RomanNumeral = MDCLXVI
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromString
"XIV".toRomanNumeral // res2: Option[RomanNumeral] = Some(XIV)

Nulla

The special value nulla (zero) can also be constructed similarly:

import nl.gn0s1s.julius.RomanNumeral
RomanNumeral() // res3: RomanNumeral = nulla
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromInt
0.toRomanNumeral // res4: RomanNumeral = nulla
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromString
"nulla".toRomanNumeral // res5: Option[RomanNumeral] = Some(nulla)

Operators and expressions

Julius makes the +, -, * and / operators available for Roman Digits and Numerals, which can be freely combined to construct expressions. This is also yet another way to construct a Roman Numeral.

some examples:

import nl.gn0s1s.julius.RomanDigit._
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralOps
M + M + X + V + I // res6: RomanNumeral = MMXVI
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromInt
(3.toRomanNumeral * C / V) - L - X // res7: RomanNumeral = nulla
import nl.gn0s1s.julius.RomanNumeral.RomanNumeralFromString
"XX".toRomanNumeral.get * V // res8: RomanNumeral = C

Links

Roman Numerals:

Scala related references:

License

The code is available under the Mozilla Public License, version 2.0.