# Arrays Start at $\pi$

Your task is to take an array of numbers and a real number and return the value at that point in the array. Arrays start at $$\\pi\$$ and are counted in $$\\pi\$$ intervals. Thing is, we're actually going to interpolate between elements given the "index". As an example:

Index:    1π   2π   3π   4π   5π   6π
Array: [ 1.1, 1.3, 6.9, 4.2, 1.3, 3.7 ]


Because it's $$\\pi\$$, we have to do the obligatory trigonometry, so we'll be using cosine interpolation using the following formula:

$$\{\cos(i \mod \pi) + 1 \over 2} * (\alpha - \beta) + \beta\$$

where:

• $$\i\$$ is the input "index"
• $$\\alpha\$$ is the value of the element immediately before the "index"
• $$\\beta\$$ is the value of the element immediately after the "index"
• $$\\cos\$$ takes its angle in radians

# Example

Given [1.3, 3.7, 6.9], 5.3:

Index 5.3 is between $$\1\pi\$$ and $$\2\pi\$$, so 1.3 will be used for before and 3.7 will be used for after. Putting it into the formula, we get:

$$\{\cos(5.3 \mod \pi) + 1 \over 2} * (1.3 - 3.7) + 3.7\$$

Which comes out to 3.165

# Notes

• Input and output may be in any convenient format
• You may assume the input number is greater than $$\\pi\$$ and less than array length * $$\\pi\$$
• You may assume the input array will be at least 2 elements long.
• Your result must have at least two decimal points of precision, be accurate to within 0.05, and support numbers up to 100 for this precision/accuracy. (single-precision floats are more than sufficient to meet this requirement)

Happy Golfing!

• FYI golfers, it might be shorter to write rewrite $(\cos(x)+1)/2$ as $\cos(x/2)^2$ using the half-angle formula for $\cos$. – xnor Mar 2 at 17:47
• Can I take in a dictionary with doubles as its keys? The doubles will be whole numbers, of course. – Embodiment of Ignorance Mar 2 at 18:55
• @EmbodimentofIgnorance, sure. I doubt that's going to help you, but that's a perfectly reasonable representation of arrays since that's how Lua does it. – Beefster Mar 2 at 19:32
• @KevinCruijssen I don't see why that would matter. 3.7 is between pi and 2pi. – Beefster Mar 4 at 16:29

# Python 3.8 (pre-release), 85 74 bytes

-8 bytes thanks to @xnor
-2 bytes thanks to @Quintec

This takes advantage of the Python 3.8 pre-release's new := assignment operator. Other than that, this is really just the equation written out in Python.

import math
lambda l,i:cos(i%math.pi/2)**2*(l[(j:=int(i/pi))-1]-l[j])+l[j]


Usage:

>>> p=lambda l,i:cos(i%math.pi/2)**2*(l[(j:=int(i/pi))-1]-l[j])+l[j]
>>> print(p([1.3, 3.7, 6.9],5.3))
3.165249203414993


Try it online!

• You can just assign j the first place it's mentioned -- part of the power of assignment expressions is that they evaluate to the value as well as assigning it. – xnor Mar 2 at 17:10
• Another byte save: Use trig identities to convert (cos(i%pi)+1)/2 to cos(i%pi/2)**2 – xnor Mar 2 at 17:41
• @xnor Good point. I knew I was using that wrong – senox13 Mar 2 at 17:43
• You can drop the p= since anonymous functions are ok – Quintec Mar 2 at 19:35
• Forgot to update bytecount :) – Quintec Mar 2 at 20:42

# R, 59 56 bytes

function(x,i)(y=x[0:1+i%/%pi])-diff(y)*cos(i%%pi/2)^2


Try it online!

Nothing too clever here - just an R version of the formula in the question. Thanks @MickyT for saving a byte, and to @Giueseppe and indirectly @xnor for another two.

• I think you can drop a byte with ...*(cos(i%%pi)+1)/2 – MickyT Mar 4 at 18:24
• @MickyT thanks, I had originally put the +1 in the parentheses, but had added a redundant pair of parentheses so ending up with 60 bytes – Nick Kennedy Mar 4 at 18:27
• 56 bytes following xnor's comment about the half-angle formula. – Giuseppe Mar 6 at 18:43

# Jelly, 17 bytes

d©ØPṪÆẠ‘H×I_@Ḋ}®ị


A full program accepting $$\i\$$ and the array which prints the interpolated value.

Try it online!

### How?

Interpolates between all neighbours using $$\\frac{\cos(i \mod \pi)+1}2\$$ then picks the relevant value.

d©ØPṪÆẠ‘H×I_@Ḋ}®ị - Link: number, i; list of numbers, A
ØP              - pi (ish) = 3.141592653589793
d                 - divmod = [i//pi, i%pi]
©                - (copy to register for later)
Ṫ             - tail (gets i%pi leaving register copy as [i//pi])
ÆẠ           - cosine = cos(i%pi)
‘          - increment
H         - halve
×        - multiply by A (vectorises)
I       - increments -- i.e. (cos(i%pi)+1)(r-l)/2 for neighbours [l,r]
Ḋ}   - dequeue A
_@     - swapped arg subtract (vectorises) -- i.e. r-(cos(i%pi)+1)(r-l)/2
-                                         = r+(cos(i%pi)+1)(l-r)/2
®  - recall value from the register
ị - index into (vectorises) -- i.e. [β+(cos(i%pi)+1)(α-β)/2]
- implicit print of Jelly representation (only 1 entry so [] wont appear)


# Röda, 51 bytes

f a,i{j=i//PI;[(cos(i%PI)+1)/2*(a[j-1]-a[j])+a[j]]}


Try it online!

# Stax, 17 bytes

≈ëBü☺ÆssÅ¢â)KjjïΔ


Run and debug it

Unpacked, ungolfed, and commented it looks like this.

VP|%    divmod with pi;  push div and mod results separately
|7^h    do (cos(modpart) + 1) / 2
sX      swap the original div result to top of stack, store it in the x register
v       decrement
;:-     pairwise differences of array
@       get element at index
N*      negate and multiply
;x@     get element from the original array at the x index, where x is the register
+       add


Run this one

# Japt, 4746 38 bytes

u0;J=V/MP[A=UgJc) nUgJf))½McVuMP)Ä]×+A


To be continued... (golfing)

Try it online!

# C# (Visual C# Interactive Compiler), 76 bytes

n=>m=>(Math.Cos(m%Math.PI)+1)/2*(n[t=(int)(m/Math.PI)-1]-n[++t])+n[t];int t;


I beat Python! Darn it, Python beat me.

Try it online!

• Look on the bright side. Neither of us stood a chance against Jelly – senox13 Mar 2 at 21:56
• @senox13 Except maybe Stax – Embodiment of Ignorance Mar 2 at 22:07

# APL+WIN, 39 37 bytes

2 bytes saved thanks to Adám

2⊃m+(-/m←⎕[0 1+⌊n÷○1])÷2÷1+2○(○1)|n←⎕


Try it online!Dyalog Classic

Explanation:

n←⎕ prompt for input of integer

2÷1+2○(○1)|n evaluate first term of formula

[0 1+⌊n÷○1] identify indices of alpha and beta

m←⎕[...] prompt for input of vector and select alpha and beta

-/m alpha-beta

2⊃m+ take result of adding beta to complete the equation


v!i|(c,r)<-properFraction$i/pi=cos(r*pi/2)^2*(v!!(c-1)-v!!c)+v!!c  Try it online! Note: the array is represented as a list. Thanks to @xnor for the half-angle tip. # Jelly, 2320 18 bytes ³%ØPÆẠ×_++H ÷ØPịÇ/  Try it online! ÷ØPịṁØ½µ³%ØPÆẠ×I_@SH Dyadic link, arguments x (index) and Z (array): ÷ØP x/pi ị Index (into Z). When x/pi is an integer, returns that elt of Z. Otherwise returns 2 elements at floor and ceiling. Ø½ [1,2] (generic 2 element array) ṁØ½ Mold; shape like [1,2] to ensure we have 2 elements. µ Start a new, monadic chain with the result [a,b] ³%ØPÆẠ×I_@SH Monadic chain ³ x %ØP x mod pi ÆẠ Unarccosine; cos(x mod pi). I Increment; b-a. ×I (b-a) cos(x mod pi) S a+b _@S a + b - (b-a) cos(x mod pi) H Halve; this is equivalent to our desired result.  # 05AB1E, 22 21 bytes žq‰;Å¾nU©èV®<èY-X*Y+  Try it online. 21-bytes alternative: žq‰Å¾>;sUI¥X<è(*IXè+  Try it online. Explanation: žq‰ # Take the divmod PI of the (implicit) input-decimal # (part = input integer-divided by PI, remainder = input modulo-PI) # i.e. 5.3 → [1,2.158...]  # Push both values separately to the stack ; # Halve the remainder # i.e. 2.158... → 1.079... Å¾ # Take the cosine of that # i.e. 1.079... → 0.472... n # Then the square of that # i.e. 0.472... → 0.222... U # Pop and store it in variable X © # Store the part in variable r (without popping) è # Index it into the (implicit) input-list # i.e. [1.3,3.7,6.9] and 1 → 3.7 V # Pop and store it in variable Y ®<è # Index r-1 also into the (implicit) input-list # i.e. [1.3,3.7,6.9] and 0 (1-1) → 1.3 Y- # Subtract variable Y from this # i.e. 1.3 - Y=3.7 → -2.4 X* # Then multiply it by variable X # i.e. X=0.222... * -2.4 → -0.534... Y+ # And add variable Y again # i.e. -0.534... + Y=3.7 → 3.165... # (then output implicitly as result)  # C (GCC) 99 bytes float P=2*acos(0); #define f(i,a)(cos(fmod(i,P))+1)/2*(a[(int)(i/P)-1]-a[(int)(i/P)])+a[(int)(i/P)]  Try it online Calling code int main() { float a = {1.3,3.7,6.9}; printf("%f\n", f(5.3,a)); }  note that it needed the compiler flag -lm to link with math libraries, so +3 bytes if you count that. # Attache, 54 bytes ${Cos[y%PI/2]^2*&-@(j:=x[1'-1*Floor[y'-y/PI]-1])+j@1}


Try it online!

## Explanation

${Cos[y%PI/2]^2*&-@(j:=x[1'-1*Floor[y'-y/PI]-1])+j@1}${                                                   }  parameters: x, y
Cos[y%PI/2]^2                                         the scaling function factor
*                                        times
j:=                                set j to
x[                     ]        the element in x at
1'-1*Floor[y'-y/PI]-1         the closest indices scaled by PI
&-@(                           )       spread subtraction over bounds
+j@1   add the upper bound