12
\$\begingroup\$

Integers in cosine

From trigonometry we know that

\$\sin(a) =-\cos(a + \frac{(4*m + 1)\pi}{2})\$

where \$a\$ is an angle and \$m\in\mathbb{Z}\$ (integer).

The task

For an input of a positive integer \$n\$ calculate the value of the integer \$k\$ with \$n\$ digits that minimizes the difference between \$\sin(a)\$ and \$-\cos(a + k)\$. Or in a simpler way, generate the sequence A308879.

First few values

1 digit : 8
2 digits: 33
3 digits: 699
4 digits: 9929
5 digits: 51819
6 digits: 573204

Output

You can create a function or print the result on the standard output. Your program needs to be able to calculate at least the 6 cases in the section above.

Scoring

This is , shortest code in bytes wins.

Reference

https://www.iquilezles.org/blog/?p=4760

\$\endgroup\$
3
  • 3
    \$\begingroup\$ This is A308879. You know, it's fairly obvious. \$\endgroup\$
    – user92069
    May 11, 2020 at 14:34
  • 2
    \$\begingroup\$ I tried searching for it and didn't find anything, thanks for finding me this :) \$\endgroup\$ May 11, 2020 at 15:01
  • \$\begingroup\$ Can the C code in OEIS really compute the answer for 12 digit \$\endgroup\$
    – user9207
    Jul 18, 2020 at 14:58

10 Answers 10

11
\$\begingroup\$

Wolfram Language (Mathematica), 25 bytes

This uses a trick: Mathematica doesn't expand Sin[51819] into a proper number even when Max is called on a list of such things, and because of how Last works, it doesn't care that Sin[51819] is not a list and simply returns 51819.

Last@Max@Sin@Range[10^#]&

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ -1 replacing Last@ with #&@@. \$\endgroup\$
    – att
    Jul 18, 2020 at 19:22
9
\$\begingroup\$

Ruby, 37 bytes

->n{(1..10**n).max_by{|k|Math.sin k}}

Try it online!

Minimising the difference between \$\sin(a)\$ and \$-\cos(a+k)\$ amounts to minimising \$|k-(4m+1)\pi/2|\$ for some \$m\$, or equivalently maximising \$\sin(k)\$.

Iterating over (1..10**n) works at least for \$n\le6\$, as required. More generally, according to the OEIS (reference courtesy of @Λ̸̸'s 05AB1E answer):

It is not guaranteed that each term in the sequence produces a better approximation than the previous one, although numerical evidence suggests so.

Iterating over (10**~-n...10**n) is guaranteed to work for any \$n\$, at a cost of 7 extra bytes.

\$\endgroup\$
4
  • \$\begingroup\$ This seems to work for n <= 8 for me. \$\endgroup\$ May 11, 2020 at 14:14
  • \$\begingroup\$ @mypronounismonicareinstate Hence why I said 'at least for \$n\le6\$'... admittedly I was too lazy to keep checking beyond that. Thanks for improving the upper bound :) \$\endgroup\$
    – Dingus
    May 11, 2020 at 14:20
  • \$\begingroup\$ Nice work, and +1. I think it would break for an n where the answer for n+1 is 10**n though (due to the inclusive range) - no idea if such an n exists, but I imagine it does. \$\endgroup\$ May 11, 2020 at 18:00
  • \$\begingroup\$ @JonathanAllan Yes, you're right. One of the 7 extra bytes in the last sentence of my answer is taken up by switching to an exclusive range. \$\endgroup\$
    – Dingus
    May 11, 2020 at 22:08
6
\$\begingroup\$

05AB1E, 7 bytes

Port of Dingus's answer. (It's A308879. From that page, it says that the sequence is also "the n-digit integer m that maximizes sin(m)"...)

°LΣŽ}θ

Try it online!

Explanation

°       10 ** n
 L      1 range
  Σ     Sort by:
   Ž}  Sine
      θ Maximum under that mapping
\$\endgroup\$
2
  • \$\begingroup\$ Nice approach with the sort-by with last item! :) An alternative could have been this 7-byter: °LŽZk>, with an implicit map for the Sine builtin; maximum without popping; and getting the index+1 of this maximum in the list. Too bad 05AB1E doesn't use 1-based indexing in this case. ;p \$\endgroup\$ May 11, 2020 at 15:06
  • \$\begingroup\$ Including 10**n could be problematic (as well as inluding numbers less than 10**(n-1) - as noted on the OEIS page). \$\endgroup\$ May 11, 2020 at 18:17
5
\$\begingroup\$

R 30 27 bytes

Following the same thread as @Dingus' Ruby answer, as indicated in the entry to A308879, i.e. looking at the maximum value of \$\sin(k)\$ over \$1,\ldots,10^n\$:

which.max(sin(1:10^scan()))

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ an alternative (which comes out to the same length, I think) is to use which.max. \$\endgroup\$
    – JDL
    May 12, 2020 at 7:42
  • \$\begingroup\$ @JDL: thanks. This was my first guess (see TIO) but it adds one byte. I am wondering why which.max(sin(1:10^scan())) alone does not work... \$\endgroup\$ May 12, 2020 at 10:13
  • 1
    \$\begingroup\$ it does work for me (though with scan you need to enter an empty line after the n) \$\endgroup\$
    – JDL
    May 12, 2020 at 10:18
  • \$\begingroup\$ Yes thank you, I just realised I had left the f= header in my tio code! I thus corrected my answer. \$\endgroup\$ May 12, 2020 at 10:21
4
\$\begingroup\$

Java 8, 91 bytes

n->{double r=0,m=0,s,k=Math.pow(10,n);for(;k-->1;)if((s=Math.sin(k))>m){m=s;r=k;}return r;}

Port of @Dingus' Ruby answer, so make sure to upvote him!

Try it online. (It's barely able to reach up to \$n=9\$ on TIO before it times out.)

Explanation:

n->{                           // Method with integer parameter and double return-type
  double r=0,                  //  Result-double, starting at 0
         m=0,                  //  Maximum `m`, starting at 0
         s,                    //  Integer `s` for the Sine calculation, uninitialized
  k=Math.pow(10,n);for(;k-->1; //  Loop `k` in the range (10^input, 1]:
    if((s=Math.sin(k))         //   Set `s` to the Sine of `k`
       >m){                    //   If this `s` is larger than the current maximum `m`:
      m=s;                     //    Replace the maximum with this `s`
      r=k;}                    //    And replace the result with `k`
  return r;}                   //  Return the result after the loop
\$\endgroup\$
2
  • 1
    \$\begingroup\$ @JonathanAllan I am? (Although I must admit it's coincidentally to be completely honest.) It currently loops in the range (10^n, 1] (exclusive on the left; inclusive on the right) or as notation that's inclusive on both side: [10^n-1, 1]. Dunno if the same applies to the other answers though, since I'm not too familiar with those other languages. To clarify: it starts k at \$10^n\$, but in the loop-check it uses k-->1 (check if \$k>1\$, and decrease it by 1 right after that with k--. So in the body of the very first iteration, k will be \$10^n-1\$. \$\endgroup\$ May 11, 2020 at 18:09
  • 1
    \$\begingroup\$ Oh, so you are, my bad! \$\endgroup\$ May 11, 2020 at 18:15
3
\$\begingroup\$

JavaScript (Node.js), 64 63 bytes

n=>[...Array(t=10**n)].map(_=>[9-Math.sin(--t),t]).sort()[0][1]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Japt -h, 10 bytes

ApU õ ñ!sM

Try it

\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog Extended), 9 bytes

⊃⍒1○⍳10*⎕

-7 bytes from ngn and Adám.

Try it online!

APL (Dyalog Extended), 20 16 bytes

{i[⊃⍒1○i←⍳10*⍵]}

-4 bytes from Bubbler.

Try it online!

Implements Dingus's algorithm.

Explanation

{i[⊃⍒1○i←⍳10*⍵]}
{              } function body
 i     i←⍳10*⍵   assign to i the range of 1 to 10^n
     1○          find the sine of each value in i
     ⊃⍒          Grade(sort) by descending value, select index of first(maximum) value
 i[           ]  return k in i where sin k is maximum
\$\endgroup\$
2
\$\begingroup\$

Python 3, 51 bytes

import math
lambda n:max(range(10**n),key=math.sin)

Try it online!

Uses Dingus's observation about maximizing sine.

\$\endgroup\$
2
\$\begingroup\$

Fortran (GFortran), 53 51 bytes

read*,n
print*,maxloc([(sin(1d0*k),k=1,10**n)])
end

Try it online!

Port of my own Ruby answer. Because why not?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.