22
\$\begingroup\$

Write a program or function that takes in two integers that represent the X and Y coordinates of a point on a Cartesian plane.

The input may come in any reasonable format as long as the X value comes before the Y. For example, 1 -2, (1,-2), [1, -2], or 1\n-2 would all be fine for X = 1, Y = -2.

Print or return a single character string (followed by an optional trailing newline) that describes the location of the point in the plane:

  • 1 if the point is in quadrant I
  • 2 if the point is in quadrant II
  • 3 if the point is in quadrant III
  • 4 if the point is in quadrant IV
  • X if the point is on the x-axis (lowercase x is not allowed)
  • Y if the point is on the y-axis (lowercase y is not allowed)
  • O if the point is on the origin (that's a capital letter "oh", not zero)

The shortest code in bytes wins. Tiebreaker goes to the higher voted answer.

Test Cases

(1,-2) -> 4
(30,56) -> 1
(-2,1) -> 2
(-89,-729) -> 3
(-89,0) -> X
(0,400) -> Y
(0,0) -> O
(0,1) -> Y
(0,-1) -> Y
(1,0) -> X
(-1,0) -> X
(1,1) -> 1
(1,-1) -> 4
(-1,1) -> 2
(-1,-1) -> 3
\$\endgroup\$
  • \$\begingroup\$ So for the purposes of this challenge, X and Y axis are in no quadrant? \$\endgroup\$ – Rɪᴋᴇʀ Jan 29 '16 at 22:02
  • \$\begingroup\$ @RikerW Right. Otherwise the point (0, 9) could be said to be quadrant I or II. \$\endgroup\$ – Calvin's Hobbies Jan 29 '16 at 22:05
  • \$\begingroup\$ Is a complex number (or a string representation of it, like "30+56i") a valid input format? \$\endgroup\$ – Level River St Jan 29 '16 at 23:21
  • \$\begingroup\$ @steveverrill Yes \$\endgroup\$ – Calvin's Hobbies Jan 29 '16 at 23:50
  • \$\begingroup\$ Can the input be in the form of a complex number? (e.g. 1+2j) \$\endgroup\$ – Digital Trauma Jan 30 '16 at 19:47

13 Answers 13

16
\$\begingroup\$

Jelly, 14 bytes

Ṡḅ3ị“Y4X13X2YO

Try it online!

How it works

Ṡḅ3ị“Y4X13X2YO    Main link. Input: [x, y]

Ṡ                 Apply the sign function to both coordinates.
 ḅ3               Convert the resulting pair from base 3 to integer.
                  Because of how base conversion is implemented in Jelly, this maps
                  [a, b] to (3a + b), even if a and b aren't valid ternary digits.
                  Therefore:
                      [0, 1]   ->  1
                      [1, -1]  ->  2
                      [1, 0]   ->  3
                      [1, 1]   ->  4
                      [-1, -1] -> -4
                      [-1, 0]  -> -3
                      [-1, 1]  -> -2
                      [0, -1]  -> -1
                      [0, 0]   ->  0
   ị“Y4X13X2YO    Retrieve the character at that index from the string.
                Indexing is 1-based and modular in Jelly, so 1ị retrieves the
                first character, -1ị the penultimate, and 0ị the last.
\$\endgroup\$
  • 6
    \$\begingroup\$ Joining the Jelly from phone club. \$\endgroup\$ – Dennis Jan 29 '16 at 22:14
  • 3
    \$\begingroup\$ Aaaaaand Jelly wins once again... \$\endgroup\$ – ETHproductions Jan 29 '16 at 22:16
  • \$\begingroup\$ Very good approach! \$\endgroup\$ – Luis Mendo Jan 29 '16 at 23:40
11
\$\begingroup\$

Ruby, 35 bytes

->x,y{%w[OY X14 X23][x<=>0][y<=>0]}

Leveraging the "spaceship" (<=>) operator.

x <=> 0 will return

  • 0 if x == 0
  • 1 if x > 0
  • -1 if x < 0

Hence,

  • if x == 0, we return 'OY'[y<=>0]. This is

    • O if y == 0 (string indexing at 0)

    • Y if y != 0 (this is true because both 1 and -1 will result in Y when indexing on this string, as -1 refers to the last character in the string, which also happens to be the one at index 1)

  • if x > 0, we return 'X14'[y<=>0]. This is X if y == 0, 1 if y > 0, and 4 if y < 0 (see explanation above).

  • if x < 0, we return 'X23'[y<=>0].

\$\endgroup\$
6
\$\begingroup\$

JavaScript, 44 bytes

(x,y)=>x?y?x>0?y>0?1:4:y>0?2:3:'X':y?'Y':'O'

f=(x,y)=>x?
            y?
                x>0?
                    y>0?1
                    :4
                :y>0?2:3
            :'X'
        :y?'Y':'O'

document.body.innerHTML = '<pre>' +
    'f(1,-2) -> ' + f(1,-2) + '<br>' +
    'f(30,56) -> ' + f(30,56) + '<br>' +
    'f(-2,1) -> ' + f(-2,1) + '<br>' +
    'f(-89,-729) -> ' + f(-89,-729) + '<br>' +
    'f(-89,0) -> ' + f(-89,0) + '<br>' +
    'f(0,400) -> ' + f(0,400) + '<br>' +
    'f(0,0) -> ' + f(0,0) + '<br>' +
    'f(0,1) -> ' + f(0,1) + '<br>' +
    'f(0,-1) -> ' + f(0,-1) + '<br>' +
    'f(1,0) -> ' + f(1,0) + '<br>' +
    'f(-1,0) -> ' + f(-1,0) + '<br>' +
    'f(1,1) -> ' + f(1,1) + '<br>' +
    'f(1,-1) -> ' + f(1,-1) + '<br>' +
    'f(-1,1) -> ' + f(-1,1) + '<br>' +
    'f(-1,-1) -> ' + f(-1,-1) + '<br>' +
'</pre>';

\$\endgroup\$
  • 3
    \$\begingroup\$ My eyes hurt, that's one long chain of ternary operators \$\endgroup\$ – andlrc Jan 29 '16 at 23:10
  • 1
    \$\begingroup\$ afaik its allowed to write an anonymous function (s/^f=//) \$\endgroup\$ – andlrc Jan 29 '16 at 23:13
5
\$\begingroup\$

ES6, 43 bytes

(x,y)=>"OYYX32X41"[3*!!x+3*(x>0)+!!y+(y>0)]

A whole byte shorter than all of those ternaries!

\$\endgroup\$
3
\$\begingroup\$

Japt, 30 22 bytes

"3Y2XOX4Y1"g4+3*Ug +Vg

Inspired by @Dennis' Jelly answer before he added an explanation. Test it online!

Fun fact: this would be two bytes shorter if I had added support for negative numbers in the g function for strings.

Another attempt, closer to the Jelly one (23 bytes):

"3Y2XOX4Y1"gNmg m+1 ¬n3

Sadly, incrementing a list costs 4 bytes...

\$\endgroup\$
2
\$\begingroup\$

MATL, 22 bytes

'3X2YOY4X1'iZSQI1h*sQ)

This uses current release (10.2.1) of the language/compiler.

Try it online!

Explanation

This shamelessly borrows the great approach in Dennis' answer.

'3X2YOY4X1'     % literal string. Will be indexed into to produce result
i               % input array of two numbers
ZS              % sign of each number in that array. Gives -1, 0 or 1
Q               % add 1 to produce 0, 1 or 2
I1h             % array [3 1]
*s              % multiply both arrays element-wise and compute sum
Q               % add 1. Gives a value from 1 to 9
)               % index into string. Display
\$\endgroup\$
2
\$\begingroup\$

Pyth, 18 bytes

@"OY4X13X2Y"i._RQ3

Explanation:

                   - Autoassign Q = eval(input())
             ._RQ  - map(cmp, Q)
            i    3 - convert to base 3
@"OY4X13X2Y"       - "OY4X13X2Y"[^] (A lookup table)

Try it here.

Or the whole test suite

\$\endgroup\$
1
\$\begingroup\$

Python 2, 75 bytes

lambda x,y,b=bool:[['OX','YO'][b(y)][b(x)],[[1,2],[4,3]][y<0][x<0]][b(x*y)]

Pretty straightforward.

\$\endgroup\$
1
\$\begingroup\$

Mathematica 81 bytes

Switch[Sign@#,{1,-1},4,{1,1},1,{-1,1},2,{-1,-1},3,{0,0},"O",{_,0},"X",{0,_},"Y"]&

%/@{{1, -2}, {30, 56}, {-2, 1}, {-89, -729}, {-89, -0}, {0, 400}, {0, 0},{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}

{4, 1, 2, 3, "X", "Y", "O", "Y", "Y", "X", "X", 1, 4, 2, 3}

\$\endgroup\$
1
\$\begingroup\$

Retina, 52

This is a simple substitution-based method:

^0 0
O
^0.*
Y
.* 0
X
-.*-.*
3
^-.*
2
.*-.*
4
.* .*
1

Try it online. The extra m` at the start of some lines is only needed to test multiple inputs in one go, so are not counted in the score.


Previously I tried this more interesting approach, but its quite a bit longer (about 65 without the m modifiers):

[1-9]\d*
1
-1
2
(.) (.)
$1$*3$2$*1
3
111
m`^(.)*$
$#1
T`d`OYYX14X23
  • substitute all non-zero numbers to 1, leaving - signs in place
  • Substitute -1 with 2
  • Convert 1st and 2nd numbers unary with 3 and 1 respectively as the unary digits . This effectively gives 2 base3 digits, expressed in unary
  • Convert to 3s to 111. This effectively gives the a single unary number that corresponds to each of the quadrants, axes and origin
  • Convert the unary to one decimal digit
  • Transpose the decimal digit to the appropriate output char.
\$\endgroup\$
  • 1
    \$\begingroup\$ I don't think the X stage needs $ since there won't be leading zeroes in the input. \$\endgroup\$ – Martin Ender Jan 30 '16 at 10:10
  • 1
    \$\begingroup\$ The more interesting approach can be shortened to at least 40 bytes. Now I will look at it tomorrow some more. \$\endgroup\$ – randomra Jan 31 '16 at 0:28
  • \$\begingroup\$ For batch run you need some tweaking. \$\endgroup\$ – randomra Jan 31 '16 at 0:28
1
\$\begingroup\$

Octave, 34 bytes

@(p)['3X2YOY4X1'](sign(p)*[3;1]+5)

The old base-3 trick through vector multiplication (although I had to add 5 to account for 1-based array indices) plus some Octave indexing magic.

Input is a vector of the form [1, -2] (with or without the comma), so when assigned to a variable w:

>> w([1 -2])
ans = 4

Here it is on ideone.

\$\endgroup\$
  • \$\begingroup\$ Ideone seems to be working again. Did you do anything special to use it? \$\endgroup\$ – Luis Mendo Feb 1 '16 at 20:35
  • \$\begingroup\$ @LuisMendo This one uses an anonymous function. Named functions are still borked for me. :( \$\endgroup\$ – beaker Feb 1 '16 at 21:17
  • \$\begingroup\$ Aah, you are right. It was named functions that were not working. So still the same :-/ \$\endgroup\$ – Luis Mendo Feb 1 '16 at 21:54
1
\$\begingroup\$

Pyth, 24

Too long, but perhaps an interesting approach:

?Q?sQ?eQh%/yPQ.n04\X\Y\O

The input must be specified as a complex number, e.g. 1-2j. Basically a nested ternary to test:

  • if input is zero - output O
  • else if real part is zero - output Y
  • else if imaginary part is zero - output X
  • else calculate the complex phase, multiply by 2, integer divide by π, then mod and add to give the appropriate quadrant number.

Try it online.

\$\endgroup\$
1
\$\begingroup\$

Java 8, 64 bytes

this is a lambda expression for a BiFunction<Integer,Integer,String>.

(x,y)->"OYYX14X23".charAt(3*(x>0?1:x<0?2:0)+(y>0?1:y<0?2:0))+"";

3 bytes could be saved by returning a Character instead of a String but i'm not completely sure if autoboxing will play nicely with the lambda.

\$\endgroup\$
  • 1
    \$\begingroup\$ Oh neat, this answer using the PCCG Handicap System scores better (1.5598) than Dennis's Jelly answer (1.5929). \$\endgroup\$ – Draco18s Feb 10 '16 at 17:59
  • \$\begingroup\$ that's quite interesting. thanks for pointing that out \$\endgroup\$ – Jack Ammo Feb 10 '16 at 18:49
  • 1
    \$\begingroup\$ Ran the values for a few entries on this one out of curiosity (all scores were between 1.5 and 2, for reference). \$\endgroup\$ – Draco18s Feb 10 '16 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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