Roman Numerals
Challenge: Printing and Parsing Roman Numerals
Roman numerals constitute a numeral system capable of expressing positive integers by additive values (rather than place-number notation). Additive series are produced by summing values in a series, as iii → 3, while subtractive values are produced by prepending certain smaller values ahead of a larger value, as ix → 9.
Produce a library which converts to and from Roman numeral representations according to the standard values:
CharacterValuei1
v5
x10
l50
c100
d500
m1,000
There are many incorrect formulations, as
iix→ 8 orid→ 499, and the code is not expected to parse these “correctly”. (It should not produce them!) However, bothivandiiiiare frequently used to represent 4 (e.g. look at a clock face), so you should support this variation.For this task, produce two files:
/lib/roman/hoonYour library
/lib/roman/hoonshould expose two arms:+parseaccepts a$tapetext string containing a Roman numeral expression in lower or upper case and returns the corresponding@udunsigned decimal value. On failure to parse, call!!zapzap.+yieldaccepts a@udunsigned decimal value and returns the corresponding$tapetext string in lower case.
/gen/roman/hoonProvide a
%saygenerator at/gen/roman/hoonwhich accepts a$tapetext string or a@udunsigned decimal value and performs the appropriate conversion on the basis of the sample's type.Note: This design pattern is not optimal since analysis over a union of some types can be difficult to carry out, and it would be better to either separate the generators or use a flag. In this case, the pattern works because we are distinguishing an atom from a cell.
Unit Tests
Following a principle of test-driven development, we compose a series of tests which allow us to rigorously check for expected behavior.
Solutions
These solutions were submitted by the Urbit community as part of a competition in ~2022.6. They are made available under both the MIT license and the CC0 license. We ask you to acknowledge authorship should you utilize these elsewhere.
Solution #1
This solution was produced by ~sidnym-ladrut. This code utilizes the Hoon parser tools like +cook and +scan, and in particular illustrates a strong ethic of function encapsulation.
/lib/roman.hoon
/gen/roman.hoon
Solution #2
This solution was produced by ~mocmex-pollen. It particularly illustrates the use of +cook and +pose in constructing a parser-based solution.
/lib/roman.hoon
/gen/roman.hoon
Solution #3
This solution was produced by ~mashex-masrex. Notice how it utilizes a well-structured parser based on +jest and +cold.
/lib/roman.hoon
/gen/roman.hoon
Solution #4
This solution was produced by ~fonnyx-nopmer. It comes sans comments, and particularly demonstrates how to produce legible and idiomatic Hoon code without requiring comments.
/lib/roman.hoon
/gen/roman.hoon
Last updated