Find the coterminal angle on [0, 2π)

2

1

This challenge is very simple:

Given an angle measure in degrees or radians (your choice), output the angle between 0 and 2π non-inclusive [0º, 360º) that is coterminal with it.

Input

A positive or negative angle measure. You can pick if you want to take it in degrees or in radians.

Output

The angle on [0, 2π) that is coterminal with the input angle. If you take the input in degrees, the output must also be in degrees; if you take it in radians, the output must be in radians too. The coterminal angle is essentially a the angle mod 360°.

Examples (in degrees)

745 -> 25
1728 -> 288
90 -> 90
0 -> 0
360 -> 0
-50 -> 310
-543.21 -> 176.79

Daniel

Posted 2017-05-04T13:08:04.797

Reputation: 6 425

9Please define "coterminal". – HyperNeutrino – 2017-05-04T13:15:00.990

I'm guessing on the basis of the examples that answers have to support floating point or fixed point input, but it would be good to have that in the spec (and rule out the GolfScript answer I would otherwise submit) – Peter Taylor – 2017-05-04T13:22:43.000

For reference of what a coterminal angle is: http://www.softschools.com/math/trigonometry/coterminal_angles/

– DimP – 2017-05-04T13:23:40.490

2

The test cases converted to radians: https://pastebin.com/hUuUkqqg

– Business Cat – 2017-05-04T13:57:01.983

5I feel like this challenge is too trivial. Honestly, a a % b challenge would be more interesting, although I feel like we've had that before. – Erik the Outgolfer – 2017-05-04T14:35:43.690

Your link took several minutes to open. It would be better to simply explain that you want us to take the input positive modulo 360 and output it. – Level River St – 2017-05-04T20:25:01.720

@LevelRiverSt, took a couple seconds for me – Daniel – 2017-05-04T20:25:44.200

Regardless of how long it takes to open, you should still put the meaning if coterminality (?) in the body of the question – Beta Decay – 2017-05-04T21:30:32.443

Answers

2

05AB1E, 4 bytes

360%

Try it online!

360  # push 360
   % # pop a,b: push (a % b)

Riley

Posted 2017-05-04T13:08:04.797

Reputation: 11 345

5

Python 3, 14 bytes

lambda n:n%360

Try it online!

ovs

Posted 2017-05-04T13:08:04.797

Reputation: 21 408

Wait, % always returns positive? – HyperNeutrino – 2017-05-04T13:42:21.367

2@HyperNeutrino As long as the divisor is positive, yes – ovs – 2017-05-04T13:44:38.073

1Oh, cool! (I'm still used to Java where it's the same sign lol). – HyperNeutrino – 2017-05-04T13:47:30.907

4

R, 11 bytes

takes input from stdin in degrees

scan()%%360

Try it online!

Giuseppe

Posted 2017-05-04T13:08:04.797

Reputation: 21 077

4

MATL, 5 4 bytes

360\

Try it online!

My first attempt with MATL!

-1 byte, just realised i is not necessary for recording the input...

DimP

Posted 2017-05-04T13:08:04.797

Reputation: 251

...How on earth does this work? :o – Beta Decay – 2017-05-04T18:02:14.733

@BetaDecay: Likely just a modulo with mathematically well-behaved behaviour for negative numbers. That's basically what the question is asking for. – None – 2017-05-05T11:41:47.877

Yeap, basically it uses Matlab's mod() function I think. – DimP – 2017-05-05T11:45:33.490

4

Python 3, 13 bytes

360..__rmod__

Explanation: num.__rmod__(x) is equivalent to x%num (rmod is modulo from the right.).

internet_user

Posted 2017-05-04T13:08:04.797

Reputation: 314

Do not works for the last test case -543.21 (or any other float number) -> NotImplemented – Rod – 2017-05-04T16:10:40.220

1360..__rmod__ works for floats as well. – Dennis – 2017-05-04T18:40:23.217

4

05AB1E, 4 bytes

Just because there were no answers using radians.

žq·%

Try it online!

Emigna

Posted 2017-05-04T13:08:04.797

Reputation: 50 798

3

CJam, 12 bytes

rd360:X%X+X%

All those extra bytes because CJam gives negative results for mods...

Try it online!

Business Cat

Posted 2017-05-04T13:08:04.797

Reputation: 8 927

2

Jelly, 4 bytes

%360

Try it online!

I was kind of hoping Æ°° would do it for 3.

Jonathan Allan

Posted 2017-05-04T13:08:04.797

Reputation: 67 804

2

Java 7, 44 43 bytes

Crossed out 44 is still regular 44 ;(

float c(float n){return(n%=360)<0?n+360:n;}

Explanation:

Java uses remainder instead of actual modulo for negative numbers (source). So we'll have to manually fix the negative cases.

float c(float n){    // Method with float input and float return-type
  return(n%=360)<0?  //  If input mod-360 is negative
   n+360             //   Return input mod-360 + 360
  :                  //  Else:
   n;                //   Return input mod-360
}                    // End of method

Test code:

Try it here.

class M{
  static float c(float n){return(n%=360)<0?n+360:n;}

  public static void main(String[] a){
    System.out.print(c(745) + "; ");
    System.out.print(c(1728) + "; ");
    System.out.print(c(90) + "; ");
    System.out.print(c(0) + "; ");
    System.out.print(c(360) + "; ");
    System.out.print(c(-50) + "; ");
    System.out.print(c(-543.21f));
  }
}

Output:

25.0; 288.0; 90.0; 0.0; 0.0; 310.0; 176.78998

Kevin Cruijssen

Posted 2017-05-04T13:08:04.797

Reputation: 67 575

float c(float n){return(n<0&&360)+n%360;} for 41 bytes. – Luke – 2017-05-04T14:18:06.190

@Luke That doesn't work in Java, unlike JavaScript for example, because n<0 is a boolean and 360 is an integer. So it gives this error: "The operator && is undefined for the argument type(s) boolean, int". – Kevin Cruijssen – 2017-05-04T14:35:18.170

Ah, yeah. Shouldn't have expected every language is as loosely typed as JS... – Luke – 2017-05-04T14:36:54.647

@Luke That doesn't work for -360 either. – Neil – 2017-05-04T17:05:24.833

On the other hand, I think (n%360+360)%360 is good. – Neil – 2017-05-04T17:06:29.527

2

Japt, 14 11 10 4 bytes

u#Ũ

Try it online!

Takes input in degrees.

Explanation

 u#Ũ
Uu360
U     # (implicit input)
 u    # modulo
  360 # 360
      # (implicit output)

Luke

Posted 2017-05-04T13:08:04.797

Reputation: 4 675

1Numbers have a u function for just this purpose, if I recall correctly, so u#Ũ) should work :-) (Also, Ũ is actually two bytes) – ETHproductions – 2017-05-04T17:49:48.150

Both TIO and your transpiler say it's just one byte... – Luke – 2017-05-04T19:50:52.703

2

C, 69 43 bytes

This seems like an excessively trivial challenge, and indeed in many languages it is. The trick is in the implementation details of the modulo operator.

When both modulo operands are positive, nothing interesting happens. But when one of the operands is negative, then the results start depending on your interpretation of what should happen. You can either always return a positive result, return a result whose sign depends on the dividend, or return a result whose sign depends on the divisor.

Programming languages are quite divided on which behavior they choose to implement. The lucky ones for this challenge are the ones that always return a positive result, since that's what the test cases call for.

If you happen to be golfing in a language that implements modulo dependent on the sign of the dividend, then you have to do extra work to compensate for negative inputs—and to make sure that this compensation does not break positive inputs!

Here's a further golfed implementation in C (thanks to ais523):

f(double*n){*n=fmod(fmod(*n,360)+360,360);}

Try it online!

Notice that C is also hobbled here by the unfortunate omission of a modulo operator (a la %) for floating-point operations. Instead, you have to call a library function.

Cody Gray

Posted 2017-05-04T13:08:04.797

Reputation: 2 639

2Several possible improvements: remove the #include (it's not required for the code to work, as all arguments to fmod have non-autopromoted types); remove the space after n,; instead of returning via the return value, take a float* as your argument, and return via assigning back to the argument (i.e. *n=…fmod(*n,360), not return…fmod(n,360)). – None – 2017-05-05T11:41:04.917

1My poor golfing skills are showing. Thanks for the suggestions, @ais523! I've incorporated them into my answer. I still feel incredibly dirty writing code like this. It's one thing to make things small and correct, but I'm not sure how I feel about making them small and dubious, taking advantage of implicit int with no actual return value. – Cody Gray – 2017-05-05T16:38:49.397

1

JavaScript (ES6), 21 19 18 bytes

Takes input in degrees.

n=>(n%360+360)%360
  • Saved 2 bytes thanks to Luke.
  • Saved 1 byte thanks to Neil.

Try it

f=
n=>(n%360+360)%360
i.addEventListener("input",_=>o.innerText=f(+i.value))
console.log(f(745)) // 25
console.log(f(1728)) // 288
console.log(f(90)) // 90
console.log(f(0)) // 0
console.log(f(360)) // 0
console.log(f(-50)) // 310
console.log(f(-543.21)) // 176.79
<input id=i type=number><pre id=o>

Shaggy

Posted 2017-05-04T13:08:04.797

Reputation: 24 623

1Beat me by 50 secs... 19 bytes: n=>n%360+(n<0&&360) – Luke – 2017-05-04T14:02:07.743

And you beat me to that improvement! Thanks, @Luke. – Shaggy – 2017-05-04T14:07:57.797

1I don't think that works for -360, but try (n%360+360)%360. – Neil – 2017-05-04T17:06:47.110

You're right. And you saved me a byte. Thanks, @Neil. – Shaggy – 2017-05-04T17:18:16.237

1

Fourier, 22 14 6 bytes

I%360o

Try it online!

Simply outputs the input modulo 360.

Note that since the interpreter for TIO is written in Python, this will not work on http://beta-decay.github.io/editor

Beta Decay

Posted 2017-05-04T13:08:04.797

Reputation: 21 478

1

Mathematica, 10 bytes

#~Mod~360&

Pure function taking any type of numerical input in degrees. Does what it says on the tin.

Greg Martin

Posted 2017-05-04T13:08:04.797

Reputation: 13 940

1

x86 Assembly (targeting the x87 FPU), 23 bytes

As is standard with 32-bit calling conventions, the double-precision floating-point parameter is passed on the stack, and returned at the top of the x87 FPU stack. Assemble with MASM:

.MODEL flat
.686                              ; fucomip requires a Pentium Pro or later CPU

CONST SEGMENT
divisor  DD  043b40000r           ; 360.0f
CONST ENDS

PUBLIC _CoterminalAngle
_TEXT SEGMENT
_CoterminalAngle PROC
   fld      DWORD PTR [divisor]   ; single-precision takes fewer bytes to store; we don't need the precision
   fld      QWORD PTR [esp + 4]   ; load parameter from stack

   fprem                          ; st(0) = parameter % 360
                                  ; st(1) = 360

   fldz
   fucomip  st(0), st(1)          ; st(0) < 0?
   jbe      Finished
   fadd     st(0), st(1)          ; fixup negative modulo by adding 360
Finished:

    fstp    st(1)                 ; discard st(1); result is left in st(0)
    ret
_CoterminalAngle ENDP
_TEXT ENDS

END 

To call from C:

extern double CoterminalAngle(double value);

In bytes:

43B40000

D9 05 00 00 00 00
DD 44 24 04
D9 F8
D9 EE
DF E9
76 02
D8 C1
DD D9
C3

Notes:

As the comment indicates, to minimize code size, I've stored the divisor constant (360.0f) as a single-precision floating-point value. This means it is half the length it would be if it were a double-precision value, and we don't need the precision to store a proper representation of the value. Upon loading, the x87 FPU will implicitly extend it to its native ten-byte extended-precision format.

We're also playing it fast-and-lose with the FPREM instruction for golfing purposes, assuming it does not need to reduce the exponent of the input value by more than 63. The careful (read: correct) way to call it would be iteratively, in a loop, continuing to execute it as long as the "parity" flag is set.
For example:

RemainderLoop:
   fprem
   fstsw  ax
   sahf
   jp     RemainderLoop

That would add 6 bytes to the total.


x86 Assembly (targeting AVX), 47 bytes

By way of comparison (and for completeness), here's an AVX implementation. It's more bytes, but also more efficient. The parameter is passed in XMM0, and the result is returned in the same register, as with any x86-64 or vector x86-32 calling convention.

43 B4 00 00    | divisor  DD  043b40000r           ; 360.0f
               | ; Load single-precision FP value, and convert it to double-precision.
C5 EA 5A 15 00 | vcvtss2sd  xmm2, xmm2, DWORD PTR [divisor]
    00 00 00   |
               | ; Divide input parameter (XMM0) by divisor (XMM2), and store result in XMM1.
C5 FB 5E CA    | vdivsd     xmm1, xmm0, xmm2
               |
               | ; Truncate the result of the division to the nearest integer.
C5 FB 2C C1    | vcvttsd2si eax, xmm1
C5 F3 2A C8    | vcvtsi2sd  xmm1, xmm1, eax
               |
               | ; Multiply the truncated result by divisor (XMM2).
C5 F3 59 CA    | vmulsd     xmm1, xmm1, xmm2
               |
               | ; Subtract this temporary value (XMM1) from the original input (XMM0).
C5 FB 5C C1    | vsubsd     xmm0, xmm0, xmm1
               |
               | ; See if the result is negative.
C5 F1 57 C9    | vxorpd     xmm1, xmm1, xmm1   ; xmm1 = 0
C5 F9 2F C8    | vcomisd    xmm1, xmm0         ; result < 0?
76 04          | jbe        Finished
C5 FB 58 C2    | vaddsd     xmm0, xmm0, xmm2   ; fixup negative modulo by adding divisor (XMM2)
               | 
               | Finished:
C3             | ret

Of course, it would be even more efficient to multiply by the reciprocal, instead of dividing. But that means more precision is required to store the divisor, and would thus slightly increase the size of the code.

Cody Gray

Posted 2017-05-04T13:08:04.797

Reputation: 2 639

0

PHP, 29 Bytes

<?=($v=$argn%360)>=0?:$v+360;

Jörg Hülsermann

Posted 2017-05-04T13:08:04.797

Reputation: 13 026

0

Python 2 REPL - 11 bytes

input()%360

If we've got a wierd input function, we might as well abuse it, right?

matsjoyce

Posted 2017-05-04T13:08:04.797

Reputation: 1 319

+6 bytes for printing the output – Julian Wolf – 2017-05-05T14:46:02.267

@JulianWolf Or cheat and say use the REPL :) – matsjoyce – 2017-05-05T15:58:41.393

0

Pyth - 5 bytes

%Q360

Would be shorter if %360 meant Q%360 instead of 360%Q, but oh well...

matsjoyce

Posted 2017-05-04T13:08:04.797

Reputation: 1 319