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

6

1

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.

Beta Decay

Posted 2017-05-22T12:14:51.977

Reputation: 21 478

1Maths homework this time? – Okx – 2017-05-22T12:23:01.627

@Okx Of course xD – Beta Decay – 2017-05-22T12:24:35.783

10Grrr, angular degrees are evil. – Dennis – 2017-05-22T12:45:47.153

>

  • Can we go beyond 3 decimal places? 2. Do the outputs have to be in ascending order?
  • < – HyperNeutrino – 2017-05-22T13:11:56.917

    @HyperNeutrino 1. No, you must stick to 3 decimal places. 2. Outputs can be in any order – Beta Decay – 2017-05-22T13:27:49.347

    One can use arcsin()? – RosLuP – 2017-05-22T14:02:08.497

    Can we return 1.0 instead of 1.000? – Erik the Outgolfer – 2017-05-22T14:08:45.750

    @mbomb007 I've fixed the examples – Beta Decay – 2017-05-22T15:42:34.727

    @Uriel Not particularly – Beta Decay – 2017-05-22T19:51:22.850

    1I think the 3 points precision here is ruining the challange, because it becomes a brute force instead of angles translation – Uriel – 2017-05-23T18:16:06.593

    1@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 – Beta Decay – 2017-05-23T19:13:17.860

    For me less is specified better it is – RosLuP – 2017-05-24T10:02:37.183

    Answers

    2

    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
    

    Uriel

    Posted 2017-05-22T12:14:51.977

    Reputation: 11 708

    3

    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}

    J42161217

    Posted 2017-05-22T12:14:51.977

    Reputation: 15 931

    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. – Greg Martin – 2017-05-22T18:50:10.103

    3

    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
    

    waffleston

    Posted 2017-05-22T12:14:51.977

    Reputation: 71

    1

    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

    Jörg Hülsermann

    Posted 2017-05-22T12:14:51.977

    Reputation: 13 026

    0

    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

    mbomb007

    Posted 2017-05-22T12:14:51.977

    Reputation: 21 944

    0

    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
    

    RosLuP

    Posted 2017-05-22T12:14:51.977

    Reputation: 3 036

    0

    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.

    JayCe

    Posted 2017-05-22T12:14:51.977

    Reputation: 2 655