Mảng bắt đầu lúc


10

Nhiệm vụ của bạn là lấy một mảng các số và một số thực và trả về giá trị tại điểm đó trong mảng. Mảng bắt đầu từ π và được tính theo các khoảng π . Điều quan trọng là, chúng ta thực sự sẽ nội suy giữa các yếu tố được đưa ra "chỉ mục". Ví dụ:

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

Bởi vì đó là π , chúng ta phải thực hiện lượng giác bắt buộc, vì vậy chúng ta sẽ sử dụng phép nội suy cosin bằng công thức sau:

cos(imodπ)+12(αβ)+β

Ở đâu:

  • i là "chỉ mục" đầu vào
  • α is the value of the element immediately before the "index"
  • β 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π and 2π, 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.3modπ)+12(1.33.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 π and less than array length * π
  • 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!


8
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

Can I take in a dictionary with doubles as its keys? The doubles will be whole numbers, of course.
Embodiment of Ignorance

@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

@KevinCruijssen I don't see why that would matter. 3.7 is between pi and 2pi.
Beefster

Câu trả lời:


5

R, 59 53 bytes

function(x,i)x[0:1+i%/%pi]%*%c(a<-cos(i%%pi/2)^2,1-a)

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, and thanks to @RobinRyder for saving a further 3.


I think you can drop a byte with ...*(cos(i%%pi)+1)/2
MickyT

@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

56 bytes following xnor's comment about the half-angle formula.
Giuseppe


4

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!


1
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

1
Another byte save: Use trig identities to convert (cos(i%pi)+1)/2 to cos(i%pi/2)**2
xnor

@xnor Good point. I knew I was using that wrong
senox13

1
You can drop the p= since anonymous functions are ok
Quintec

1
Forgot to update bytecount :)
Quintec

3

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 cos(imodπ)+12 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)



1

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



1

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 


1

Haskell, 65 bytes

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.


0

Jelly, 23 20 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.

0

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

0

C (GCC) 99 79 bytes

-20 bytes ceilingcat

float P=3.141593;b;
#define f(i,a)(cos(fmod(i,P))+1)/2*(a[b=i/P-1]-a[++b])+a[b]

Try it online!

Calling code

int main() {
  float a[3] = {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.


0

05AB1E, 22 21 20 19 bytes

žq‰`ž>;UÝèÐÁ-θX*-θ

Try it online or verify some more test cases.

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
    ž     # Take the cosine of the remainder
           #  i.e. 2.158... → -0.554...
      >    # Increase it by 1
           #  i.e. -0.554... → 0.554...
       ;   # Halve it
           #  i.e. 0.554... → 0.222...
        U  # Pop and store it in variable `X`
    Ý      # Pop the part, and push a list in the range [0, part]
           #  i.e. 1 → [0, 1]
     è     # (0-based) index all of them into the (implicit) input-list
           #   i.e. [1.3, 3.7, 6.9] and [0, 1] → [1.3, 3.7]
Ð          # Triplicate this list
 Á         # Rotate the last copy once towards the right
           #  i.e. [1.3, 3.7] → [3.7, 1.3]
  -        # Subtract the values in the top two lists from one another
           #  i.e. [1.3, 3.7] and [3.7, 1.3] → [-2.4, 2.4]
   θ       # Pop and only leave the last value of this list
           #  i.e. [-2.4, 2.4] → 2.4
    X*     # Multiply it by `X`
           #  i.e. 2.4 * `X`=0.222... → 0.534...
     -     # Subtract it from each of the values in the list we triplicated
           #  i.e. [1.3, 3.7] - 0.534... → [0.765..., 3.165...]
      θ    # And only leave the last value of this list
           #  i.e. [0.765..., 3.165...] → 3.165...
           # (which is output implicitly as result)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.