9
$\begingroup$

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!

$\endgroup$
1
  • 2
    $\begingroup$ 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. $\endgroup$
    – lericr
    Jun 7 at 16:40

4 Answers 4

12
$\begingroup$

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]]

Mathematica graphics

$\endgroup$
3
  • $\begingroup$ Roman zero N gets no respect. 😉 $\endgroup$ Jun 9 at 16:04
  • $\begingroup$ @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." $\endgroup$
    – Michael E2
    Jun 9 at 16:52
  • $\begingroup$ 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. $\endgroup$ Jun 9 at 17:51
10
$\begingroup$

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"}

$\endgroup$
1
  • $\begingroup$ Now that's just flexing. $\endgroup$ Jun 9 at 9:16
4
$\begingroup$

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
$\endgroup$
2
$\begingroup$

Or use regex.

"Now you have two problems"

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

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.