14
3
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
Is it possible to use other characters to represent operators?.For example using # instead of ~ – rahnema1 – 2017-03-05T21:25:13.220
1@rahnema1 For
~
and,
, but not forskip
. – Esolanging Fruit – 2017-03-05T22:17:04.5003Why is ~10,5~ false for 4? Because that is the union of -infinity to 10 and 5 to infinity, the first of which includes 4 – ev3commander – 2017-03-05T22:48:53.667
@ev3commander Edited. I always mess up on my test cases. I bet my challenges would be clearer if I didn't add them :P – Esolanging Fruit – 2017-03-05T23:14:19.143
@Challenger5 it doesn't look like it was updated. In any case, I think you need a bunch more test cases for the trickier aspects (mostly revolving around the infinities and them being able to be anywhere), like
10~20,~ skip 15
. I can think of easier solutions that can handle all the listed test cases but will fail on strange placing of open-ended ranges. – briantist – 2017-03-05T23:56:33.267@briantist Funny, it must not have updated. – Esolanging Fruit – 2017-03-06T06:00:21.273
1@Challenger5 I've added a test case
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. – briantist – 2017-03-06T15:24:45.523