Imagine I have an infinite number of homework problems (!) each given an integer number.
Math Problem Notation is a notation for describing subsets of the problem using problem specifiers.
An MPN expression can consist of several things:
- A single value. This represents a set containing the number:
99 -> {99}
. - A simple range. This represents the set containing all the numbers from the beginning to the end of the range:
10~13 -> {10, 11, 12, 13}
. If the left or right sides are missing, then they are assumed to be -Infinity or Infinity respectively:~10 -> {x|x ≤ 10}
;~ -> ℤ
. - An MPN expression, followed by "skip" and another MPN expression. This represents the difference of the two sets:
10~20 skip 12~14 -> {10, 11, 15, 16, 17, 18, 19, 20}
. - Two MPN expressions, separated by a comma. This represents the union of two sets:
1,8~9,15~17 -> {1,8,9,15,16,17}
.
The "skip" operator binds tighter than the comma operator, so 16,110~112 skip 16 -> {16,110,111,112}
(16 is not included in the set {110,111,112}
, so the excluding 16 does not matter.)
You can also put expressions in parentheses for disambiguation:
1~9 skip (2~8 skip (3~7 skip (4~6 skip 5))) -> {1,3,5,7,9}
This is the grammar:
<expr> ::= "(" <expr> ")"
|| <number>
|| [<number>] "~" [<number>]
|| <expr> "skip" <expr>
|| <expr> "," <expr>
Your task is to write a program that takes two inputs:
- An MPN expression
- A number
and outputs some truthy or falsey value depending on whether that problem is in the set described by the MPN expression.
Specifications
- You can assume that the first input is a well-formed MPN expression (i.e. that it matches the above grammar)
- Numbers in an MPN expression are always integers. They can be negative or zero, but will never have a fractional part.
- This is code-golf, so the shortest valid submission (measured in bytes) wins.
- You can use different characters for
~
and,
, if you want.
Test Cases
10~20 14 -> True
10~20 20 -> True
10~20 skip 14~18 17 -> False
~ skip 6 8 -> True
16,17 skip 16 16 -> True
(16,17) skip 16 16 -> False
~10,5~ 8 -> True
~10,5~ 4 -> True
6 skip 6,~ 6 -> True
~
and,
, but not forskip
. \$\endgroup\$6 skip 6,~
which I believe I've interpreted correctly. The other 2 answers so far don't satisfy it (again, assuming I'm interpreting correctly). If I've misunderstood please correct it and clarify, but from my understanding, it should match anything (it's the union of a set that matches nothing with a set that matches everything). These are the kinds of cases I was talking about earlier that I think could help out a lot when testing our solutions. \$\endgroup\$