6
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Maths homework this time? \$\endgroup\$ – Okx May 22 '17 at 12:23
  • \$\begingroup\$ @Okx Of course xD \$\endgroup\$ – Beta Decay May 22 '17 at 12:24
  • 10
    \$\begingroup\$ Grrr, angular degrees are evil. \$\endgroup\$ – Dennis May 22 '17 at 12:45
  • 1
    \$\begingroup\$ I think the 3 points precision here is ruining the challange, because it becomes a brute force instead of angles translation \$\endgroup\$ – Uriel May 23 '17 at 18:16
  • 1
    \$\begingroup\$ @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 \$\endgroup\$ – Beta Decay May 23 '17 at 19:13
2
\$\begingroup\$

APL, 51 46 40 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
\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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}

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Greg Martin May 22 '17 at 18:50
1
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$

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.