# The ultimate inequality challenge

Given two positive integers a, b and a Unicode mathematical inequality symbol c, determine if a c b is true.

You many take the character or its Unicode codepoint for the input c. You may output your language's truthy/falsy values, or two distinct values for true and false respectively.

Standard rules apply. The shortest code in bytes wins.

## List of symbols to support

Symbol  |  Hex   |  Dec   |  Name
--------+--------+--------+-------------
<       |  003C  |  60    |  Less than
=       |  003D  |  61    |  Equal to
>       |  003E  |  62    |  Greater than
≠       |  2260  |  8800  |  Not equal to
≤       |  2264  |  8804  |  Less than or equal to
≥       |  2265  |  8805  |  Greater than or equal to
≮       |  226E  |  8814  |  Not less than
≯       |  226F  |  8815  |  Not greater than
≰       |  2270  |  8816  |  Neither less than nor equal to
≱       |  2271  |  8817  |  Neither greater than nor equal to


The last four symbols may look broken in Chrome. They are four symbols <>≤≥ with slash overstrike, indicating negation.

## Truthy test cases

1 < 2
1 = 1
2 > 1
1 ≠ 2
2 ≠ 1
1 ≤ 1
1 ≤ 2
2 ≥ 1
1 ≥ 1
2 ≮ 1
1 ≮ 1
1 ≯ 1
1 ≯ 2
2 ≰ 1
1 ≱ 2


## Falsy test cases

1 < 1
2 < 1
1 = 2
2 = 1
1 > 1
1 > 2
1 ≠ 1
2 ≤ 1
1 ≥ 2
1 ≮ 2
2 ≯ 1
1 ≰ 1
1 ≰ 2
2 ≱ 1
1 ≱ 1

• I'm pleased to report that Mathematica does not have built-in support for the symbol ≱. Apr 17 '20 at 7:36
• There must be some language where the empty program will work here.
– JDL
Apr 17 '20 at 8:14
• @GregMartin It does support that symbol and detect that it is the NotGreaterEqual function, but it doesn't have a built-in meaning :( Apr 17 '20 at 12:54
• This would be a lot more "fun" if it included complex numbers, NaN, or something else lacking a total order, so that ≮ wouldn't be equivalent to ≥. Apr 18 '20 at 20:35
• @NithinDanday It's your choice to pick one of them to support. Sep 23 '20 at 22:57

# JavaScript (ES6),  58 45  42 bytes

Saved 3 bytes thanks to @Neil

Expects the Unicode code point for $$\c\$$. Returns $$\0\$$ or $$\1\$$.

(a,c,b)=>'14353426'[c%61%9]>>(a>b?2:b>a)&1


Try it online!

### How?

Each comparison character is assigned a 3-bit mask describing if it should be truthy for a > b, a < b or a == b.

 char. | code | meaning                           | > | < | = | mask
-------+------+-----------------------------------+---+---+---+------
<   |   60 | Less than                         | 0 | 1 | 0 |  2
=   |   61 | Equal to                          | 0 | 0 | 1 |  1
>   |   62 | Greater than                      | 1 | 0 | 0 |  4
≠   | 8800 | Not equal to                      | 1 | 1 | 0 |  6
≤   | 8804 | Less than or equal to             | 0 | 1 | 1 |  3
≥   | 8805 | Greater than or equal to          | 1 | 0 | 1 |  5
≮   | 8814 | Not less than                     | 1 | 0 | 1 |  5
≯   | 8815 | Not greater than                  | 0 | 1 | 1 |  3
≰   | 8816 | Neither less than nor equal to    | 1 | 0 | 0 |  4
≱   | 8817 | Neither greater than nor equal to | 0 | 1 | 0 |  2


We store these masks in a 8-character lookup string whose index is computed by applying two consecutive modulos to the code point:

 code | mod 61 | mod 9 | mask
------+--------+-------+------
60 |   60   |   6   |  2
61 |    0   |   0   |  1
62 |    1   |   1   |  4
8800 |   16   |   7   |  6
8804 |   20   |   2   |  3
8805 |   21   |   3   |  5
8814 |   30   |   3   |  5
8815 |   31   |   4   |  3
8816 |   32   |   5   |  4
8817 |   33   |   6   |  2

• 42 bytes: '14353426'[c%61%9]>>(b<a?2:b>a)&1
– Neil
Apr 16 '20 at 12:54
• @Neil This is precisely what I was trying to do, but I got bogged down with the lookup update. Thanks! Apr 16 '20 at 13:01

# Python 2, 45 bytes

lambda a,o,b:o%83*45%555%16%6+1>>cmp(a,b)+1&1


Try it online!

Improved based on @Arnauld's answer, make sure to upvote him!

The bitmask here is a different from @Arnauld's answer because bit 0 and 1 are swapped. As usual, the lookup table is replaced by some cool magic numbers.

# Python 3, 51 48 47 bytes

lambda a,o,b:o%83*45%555%16%6+1>>(a>b)+(a>=b)&1


Try it online!

# Python 2, 47 46 bytes

lambda a,o,b:(cmp(a,b)==1-o*6%43%7%3)^o*3%58%3


Try it online!

Every operation can be expressed by (cmp(a,b)==a)^b. For example, a<b iff (cmp(a,b)==-1)^0. We then use some dirty magic numbers to compress a and b.

# Python 3, 51 49 48 bytes

lambda a,o,b:((a<b)+(a<=b)==o*6%43%7%3)^o*3%58%3


Try it online!

# 05AB1E, 34332423 18 bytes

•1P42•b3ôs61%èŠ.Sè


-9 bytes by porting @ovs' Python 3 answer, so make sure to upvote him!
-6 bytes thanks to @Grimmy.

Input of the character as codepoint integer. Input-order as c,b,a.

Explanation:

•1P42•             # Push compressed integer 18208022
b            # Convert it to binary 1000101011101010100010110
3ô          # Split it in parts of size 3:
#  [100,"010",101,110,101,"010","001","011",0]
s         # Take the first codepoint input
61%      # Take modulo-61
è     # Index it into the binary list (0-based and with wraparound)
Š    # Triple-swap to take the next two inputs
.S  # Compare them (-1 if a<b; 0 if a==b; 1 if a>b)
è # And use that to index into the triplet (where -1 is the last item)
# (after which the result is output implicitly)


See this 05AB1E tip of mine (sections How to compress large integers?) to understand why •1P42• is 18208022.

• Here's 18 Apr 24 '20 at 6:14

# Python 3, 99 82 bytes

17 bytes saved thanks to @ovs!

Uses the operator similarities a<b <=> a≱b, etc.

lambda a,o,b:[a<b,a>b,a<=b,a>=b,a==b,a!=b]['<≱>≰≤≯≥≮= ≠'.find(o)//2]


Try it online!

# Python 2, 4241 38 bytes

Takes in as input two operands $$\ a \$$ and $$\ b \$$, and the operator $$\ c \$$ in codepoint form. Test cases nicely borrowed from @newbie.

lambda a,c,b:(cmp(a,b)+63)*c%1895%57&1


Try it online!

The idea is the same as @newbie's, generating pseudorandom numbers until they match the output. The cmp function returns -1, 0, or 1 if the left argument is less, equal to, or greater than the right argument, respectively. And also because MathJax looks nice, here is the formula in MathJax:

$$((((\text{cmp}(a,b) + 63) * c) \bmod 1895) \bmod 57) \bmod 2$$

• Nice :))))))))) Apr 17 '20 at 8:19
• 39 bytes, i guess i'll leave my answer unchanged Apr 17 '20 at 9:35
• @newbie That's a great answer, but I think you should post it as yours, since you found it. Apr 17 '20 at 18:55

# Python 3, 68 59 bytes

Takes the unicode code point of the operator as input.

lambda a,o,b:[a==b,a>b,a<=b,a>=b,a<=b,a>b,a<b,a!=b][o%61%9]


Try it online!

# APL (Dyalog Unicode), 50 bytes

{⍎('≥≤><',⍵)[⍵⍳⍨'≮≯≰≱',⍵]}


Try it online! (the test cases)

Dyalog APL supports many of those operators and a simple "eval()" ⍎ will handle them as given. This answer swaps the last four which are not supported '≮≯≰≱' with replacements that are supported, e.g. "not less than" becomes "greater than or equal to", then "eval()"'s the resulting string. Output is 1 for true, 0 for false.

(NB. on the score: It's only 26 characters which would be competitive, however because it has ≮≯≰≱ characters in it, it does not fit in a pre-existing 8-bit APL character set so must be scored with the UTF-8 byte count instead of the number of characters).

⍎⍵
≮
≯
≰
≱
≥
≤
>
<


Try it online!

Simply replaces the redundant symbols with their simpler equivalents, and then evaluates as APL.

## Dyalog APL, 23 bytes.

⎕(⍎'=>≤≥≤><≠'[9|61|⎕])⎕


With Adám's assistance. Try it online! (the test cases)

Explained: The ⎕ are prompts for numeric input, it takes the numbers on the outsides, and the codepoint of the comparison operator in the middle. Codepoint modulo | 61 then 9 produces indices into the string ''[] which pick the comparison operator to run. This maps the unsupported ones (≮ ≯ ≰ ≱) to their supported equivalents ("not less than" maps to "greater than or equal to", etc).

Code demonstrates an unusual APL feature: 1 (⍎'<') 2 where the string '<' evaluates ⍎ to a function which can be called in-place like any other 1 f 2 dyadic APL function call.

NB. I'm submitting this as a separate answer both because it's a different approach to my other APL answer, and because it does not contain the unsupported comparison characters in it, which means it fits in a pre-existing 8-bit APL character set, and can be scored as 1-byte-per-character instead of UTF-8 byte count, for a much lower score.

# Sledgehammer, 17 bytes

16.75, to be overly specific

⣕⢌⢲⢼⠴⢺⢟⢼⣑⣮⣊⠞⠀⢄⡕⡝⢥


There's no point in trying to read that, so here's the corresponding Mathematica code with a reasonable explanation:

ToExpression@StringReplace[ToString@FullForm@ToExpression@Input[],"ot"->"ot@"]


The code evaluates the expression first. Unfortunately, the ≱ operator (and a few other similar ones) is not supported, and is kept verbatim. The code then rewrites the expression into a prefix-ish form (NotGreaterEqual[1, 1]), and replaces ot with ot@, turning NotGreaterEqual[1, 1] into Not@GreaterEqual[1, 1], a call of the function Not on the result of GreaterEqual. Of course, since that was a string replacement, the result is then evaluated once again.

# Io, 90 bytes

method(a,o,b,list(a<b,a>b,a<=b,a>=b,a==b,a!=b)at("<≱>≰≤≯≥≮= ≠"findSeq(o)/2))


Try it online!

# Retina 0.8.2, 80 bytes

\d+
$* ≠ <> ≤|≯ <= ≥|≮ => ≰ > ≱ < ^(1+)(<.?1\1|.?>(?!\1)|<?=>?\1$)


Try it online! Link includes test suite. Takes input as acb, but the test suite deletes spaces to make the input more readable. Explanation:

\d+
$*  Convert to unary. ≠ <> ≤|≯ <= ≥|≮ => ≰ > ≱ <  Replace the Unicode operators with ASCII-based logical operators. The => is reversed to make the final condition golfier. ^(1+)(<.?1\1|.?>(?!\1)|<?=>?\1$)


Match the first number, then check whether one of the relations can be fulfilled.

• If the character after the first number is a <, then after an optional > or =, then to fulfil this relation the second number needs to equal 1 or more than the first number.
• If after an optional < or =, there is a > before the second number, then to fulfil this relation the second number must not be at least equal to the first number.
• If after an optional < there is an = before an optional >, then to fulfil this relation the second number must be equal to the first number.

# C (gcc), 46 bytes

f(a,c,b){a="14353426"[c%61%9]>>(a>b?2:b>a)&1;}


Try it online!

# VyxalD, 16 bytes

4ɾ8813+C≥≤><ĿĖ


Try it Online!

Luckily, Vyxal supports all but the last four characters as operations.

               Ė # Evaluate...
Ŀ  # The input, with characters in...
C         # The charcodes of
4ɾ               # 1...4
8813+          # + 8813
Ŀ  # Replaced...
≥≤><   # with the cooresponding character


# Charcoal, 38 bytes

Ｎθ≔Ｉ§”←⧴LH⎚G₂ⅉυ”℅ＳηＮζ⁼§⟦‹θζ⁼θζ›θζ⟧η÷η³


Try it online! Link is to verbose version of code. Takes input as a c b and outputs a Charcoal boolean, i.e. - for true, nothing for false. Explanation:

Ｎθ


Input a.

≔Ｉ§”←⧴LH⎚G₂ⅉυ”℅Ｓη


Input c and cyclically look up its ordinal in the compressed string __20__345___02531_ (the _s are arbitrary; the linked code uses spaces) and save its value.

Ｎζ


Input b.

⁼§⟦‹θζ⁼θζ›θζ⟧η÷η³


Make a list of the comparisons a<b, a=b, a>b, cyclically index using the c value, and negate the result if the c value is less than 3.