# Solve sin(θ) = x in the range a ≤ θ ≤ b

## Challenge

Given a number, x where -1 ≤ x ≤ 1, and the integers a and b, where b > a, solve the equation sin(θ) = x for θ, giving all solutions in the range a° ≤ θ ≤ b°.

## Rules

x will have a maximum of three decimal places of precision. The output, θ, must also be to three decimal places, no more, no less.

Your output may be as a list or separated output.

You may use built-in​ trig functions.

You may not use radians for a and b.

You will never be given invalid input.

Output may be in any order.

## Examples

x, a, b => outputs
0.500, 0, 360 => 30.000, 150.000
-0.200, 56, 243 => 191.537
0.000, -1080, 1080 => 0.000, 180.000, 360.000, 540.000, 720.000, 900.000, 1080.000, -1080.000 -900.000, -720.000, -540.000, -360.000, -180.000


## Winning

Shortest code in bytes wins.

• Maths homework this time?
– Okx
May 22, 2017 at 12:23
• @Okx Of course xD May 22, 2017 at 12:24
• Grrr, angular degrees are evil. May 22, 2017 at 12:45
• I think the 3 points precision here is ruining the challange, because it becomes a brute force instead of angles translation May 23, 2017 at 18:16
• @Uriel Huh, that's a shame. When you don't specify a challenge enough, people complain, when you specify the challenge, the challenge is a bit rubbish :P May 23, 2017 at 19:13

# Fortran 95 (gfortran), 180 bytes

#define G >=i)write(*,'(f9.3)')
#define H read(*,*)
program a
H x
H i
H j
o=ASIN(x)*57.2957
p=o-180+o
q=o-360*999
do
r=q-p
if(r<=j.and.r G r
if(q>=j)exit
if(q G q
q=q+360
enddo
end


Structure ungolfed:

program a
implicit none
real :: x
integer :: i
integer :: j
real :: o
real :: r
real :: q
real :: p

read(*,*) x
read(*,*) i
read(*,*) j

o=ASIN(x)*57.2957
p=o-180+o
q=o-360*999

do
r=q-p
if(r<=j.and.r >=i) then
write(*,'(f9.3)') r
endif
if(q>=j) then
exit
endif
if(q >=i) then
write(*,'(f9.3)') q
endif
q = q + 360
end do
end program a


## Mathematica, 60 bytes

NumberForm[t/.NSolve[Sin[t/180Pi]==#&&#2<=t<=#3,{t}],{9,3}]&


input

[0, -1080, 1080]

output

{-1080.000,-900.000,-720.000,-540.000,-360.000,-180.000,0.000,180.000,360.000,540.000,720.000,900.000,1080.000}

• Note that this solution doesn't work for large integers, for two reasons: the 9 limits the accuracy for large solutions, and also NumberForm displays the answer in scientific notation which erodes the accuracy (a constant annoyance from Mathematica). That being said, do you need ,Reals at all? You can also save a byte by replacing t Degree with t/180Pi, which (despite appearances) evaluates to πt/180. May 22, 2017 at 18:50

# APL, 514640 39 bytes

3 bytes saved thanks to @KritixiLithos

6 7 bytes saved thanks to @Adám

{3⍕⍵/⍨1E¯6>|⎕-1○○⍵÷180}⊢+1E3÷⍨(⍳1001×-)


Called as a dyad with a as left argument and b as right argument, prompts for x.

Requires ⎕IO←0.

How?

                         ⊢+1E3÷⍨(⍳1001×-)  ⍝ build the range a to b with step of 0.001
1001×-   ⍝ 1001 * (b - a)
⍳         ⍝ range
1E3÷⍨           ⍝ divide every element by 1000
⊢+                ⍝ add a back

{3⍕⍵/⍨1E¯6>|⎕-1○○⍵÷180}                  ⍝ filter the solutions
○⍵÷180                   ⍝ convert to radian - π * ⍵ / 180
1○                          ⍝ compute sine
|⎕-                           ⍝ distance from x
1E¯6>                                ⍝ small enough
⍵/⍨                                    ⍝ compress with the original list
3⍕                                        ⍝ format to 3 decimal places


# PHP>=7.1, 88 Bytes

for([,$s,$f,$t]=$argv;$f<=$t;$f+=.001)round(sin(deg2rad($f)),5)!=$s?:printf("%.3f_",$f);


Online Version

# Python 2, 100 bytes

from math import*
x,a,b=input()
while a<=b:
if round(sin(pi*a/180),5)==x:print a
a=round(a+.001,3)


Try it online

# Axiom, 266 215 210 bytes

g(y,a,b)==(r:List Float:=[];t:=y+truncate((a-y)/360)*360;repeat(t>b=>break;if t>=a then r:=append(r,[t]);t:=t+360);r)
f(x,a,b)==(abs(x)>1 or a>b=>[];y:=asin(x)*180/%pi;z:=180-y;sort(append(g(y,a,b),g(z,a,b))))


ungolf and test

-- g/180=r/pi  => r=pi*g/180
--y+k*360=a
--    a-y
-- k=------
--    360
-- find all angles of the same class of angles [y+k*360] in interval [a,b]
gg(y,a,b)==
r:List Float:=[]
t:=y+truncate((a-y)/360)*360 --truncate(1.9)=1, truncate(-3.1)=-4 is ok
repeat
t>b=>break
if t>=a then r:=append(r,[t])
t:=t+360
r

-- ff returns the list of solution y of sin(y)=x with y in the interval [a,b]
ff(x,a,b)==
abs(x)>1 or a>b =>[]
y:=asin(x)*180/%pi -- z and y are the only 2 solutions in one 360 Len interval
z:=180-y
sort(append(gg(y,a,b),gg(z,a,b)))

(6) -> f(0.5, 0, 360)
(6)  [30.0,150.0]
Type: List Float
(7) -> f(-0.2, 56, 243)
(7)  [191.5369590328 1548769]
Type: List Float
(8) -> f(0.0, -1080, 1080)
(8)
[- 1080.0, - 900.0, - 720.0, - 540.0, - 360.0, - 180.0, 0.0, 180.0, 360.0,
540.0, 720.0, 900.0, 1080.0]

(14) -> m:=f(-0.1, -2035, -243)
(14)
[- 1974.2608295227 33214, - 1805.7391704772 66786, - 1614.2608295227 33214,
- 1445.7391704772 66786, - 1254.2608295227 33214, - 1085.7391704772 66786,
- 894.2608295227 332137, - 725.7391704772 667863, - 534.2608295227 332137,
- 365.7391704772 667863]
Type: List Float
(15) -> map(x+->sin(%pi*x/180), m)
(15)
[- 0.0999999999 9999999987, - 0.1000000000 0000000016,
- 0.0999999999 9999999986 2, - 0.1000000000 0000000028,
- 0.0999999999 9999999985 4, - 0.1000000000 0000000018,
- 0.0999999999 999999999, - 0.1000000000 0000000019,
- 0.0999999999 9999999989 2, - 0.1000000000 0000000014]
Type: List Float


# R, 74 bytes

function(x,a,b,u=seq(a,b,.001))sprintf("%.3f",u[abs(sinpi(u/180)-x)<1e-6])


Try it online!

The tolerance 1e-6 was chosen to fit the second test case, so is somewhat arbitrary. This answer takes advantage of R's vectorized functions.