# Find Roman numerals up to 100 that do not contain “I"

The question is from Elementary Introduction to the Wolfram Language, section 28 Tests and Conditionals: Find Roman numerals up to 100 that do not contain “I”.

What am I doing wrong that the following code is not returning the desired output?

Select[RomanNumeral[Range[100]], MemberQ[#, "I"]&]


I can't quite figure out where I am going wrong.

Thanks!

• MemberQ is for lists. So, you could split the string into characters first (and use Not). Or you could just use StringFreeQ on the roman numeral strings. Jun 7 at 16:40

The Roman numerals are strings, not lists (or another expression). So MemberQ will return False.

Select[RomanNumeral[Range[100]],
! MemberQ[Characters@#, "I"] &]


Or:

Select[RomanNumeral[Range[100]], StringFreeQ["I"]]


Also:

RomanNumeral[Range[5, 100, 5]]


• Roman zero N gets no respect. 😉 Jun 9 at 16:04
• @chux-ReinstateMonica Mma respects it: RomanNumeral[Range[0, 100, 5]]. It's unclear whether nulla was considered a number, or even whether N was used by the Romans since, according to the Wiki article, "the earliest attested instances are medieval." Jun 9 at 16:52
• Much of the rules about Roman numbers achieved their greater uniformity (as in this good answer) long after Roman times. Else XXXX, (and the like) should be on the list too. Jun 9 at 17:51

I include some variations.

rn100 = RomanNumeral@Range@100;

Cases[rn100, _?(StringFreeQ["I"])]

DeleteCases[rn100, _?(StringContainsQ["I"])]

DeleteCases[rn100, _?(StringMatchQ[___ ~~ "I" ~~ ___])]

Complement[rn100, Cases[rn100, _?(StringMatchQ[___ ~~ "I" ~~ ___])]] //
SortBy[#, FromRomanNumeral] &

Pick[rn100, StringMatchQ["*I*"] /@ rn100, False]

Pick[rn100, StringMatchQ[Except["I"] ..]@rn100]

Select[rn100, # == StringDelete[#, "I"] &]

Select[rn100, StringPosition[#, "I"] == {} &]


Result:

{"V", "X", "XV", "XX", "XXV", "XXX", "XXXV", "XL", "XLV", "L", "LV",
"LX", "LXV", "LXX", "LXXV", "LXXX", "LXXXV", "XC", "XCV", "C"}

• Now that's just flexing. Jun 9 at 9:16

Another way using GroupBy and Extract:

rn100 = RomanNumeral@Range@100;

Extract[GroupBy[rn100, FreeQ[Characters[#], "I"] &], Key[True]]


Or using GroupBy and Lookup:

Lookup[GroupBy[rn100, FreeQ[Characters[#], "I"] &], True]


Or using ReplaceAll:

rn100 /. x_?StringQ /; ! StringFreeQ[x, "I"] :> Nothing


Or use regex.

"Now you have two problems"

Range[100] // RomanNumeral // Select[StringMatchQ[RegularExpression["[^I]*"]]]


https://xkcd.com/1171/ Perl Problems