Given two ranges:

   



[

a

1


,

a

2


]


{\displaystyle [a_{1},a_{2}]}

   and 
   



[

b

1


,

b

2


]


{\displaystyle [b_{1},b_{2}]}

; 
   then a value   



s


{\displaystyle s}

   in range   



[

a

1


,

a

2


]


{\displaystyle [a_{1},a_{2}]}


   is linearly mapped to a value   



t


{\displaystyle t}

   in range   



[

b

1


,

b

2


]


{\displaystyle [b_{1},b_{2}]}


   where:



   



t
=

b

1


+



(
s
−

a

1


)
(

b

2


−

b

1


)


(

a

2


−

a

1


)





{\displaystyle t=b_{1}+{(s-a_{1})(b_{2}-b_{1}) \over (a_{2}-a_{1})}}




Task

Write a function/subroutine/... that takes two ranges and a real number, and returns the mapping of the real number from the first to the second range.

Use this function to map values from the range    [0, 10]    to the range    [-1, 0]. 



Extra credit

Show additional idiomatic ways of performing the mapping, using tools available to the language.




 
(lib 'plot) ;; interpolation functions
(lib 'compile)
 
;; rational version
(define (q-map-range x xmin xmax ymin ymax) (+ ymin (/ ( * (- x xmin) (- ymax ymin)) (- xmax xmin))))
 
;; float version
(define (map-range x xmin xmax ymin ymax) (+ ymin (// ( * (- x xmin) (- ymax ymin)) (- xmax xmin))))
; accelerate it
(compile 'map-range "-vf")
 
(q-map-range 4 0 10 -1 0)
    → -3/5
(map-range 4 0 10 -1 0)
    → -0.6
(linear 4 0 10 -1 0) ;; native
    → -0.6
 
(for [(x (in-range 0 10))] (writeln x (q-map-range x 0 10 -1 0) (map-range x 0 10 -1 0)))
 
0     -1     -1    
1     -9/10     -0.9    
2     -4/5     -0.8    
3     -7/10     -0.7    
4     -3/5     -0.6    
5     -1/2     -0.5    
6     -2/5     -0.4    
7     -3/10     -0.3    
8     -1/5     -0.2    
9     -1/10     -0.1    
 