8
\$\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
    \$\begingroup\$ This is A308879. You know, it's fairly obvious. \$\endgroup\$ – user92069 May 11 at 14:34
  • 2
    \$\begingroup\$ I tried searching for it and didn't find anything, thanks for finding me this :) \$\endgroup\$ – Gábor Fekete May 11 at 15:01
  • \$\begingroup\$ Can the C code in OEIS really compute the answer for 12 digit \$\endgroup\$ – Anush Jul 18 at 14:58
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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -1 replacing Last@ with #&@@. \$\endgroup\$ – att Jul 18 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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This seems to work for n <= 8 for me. \$\endgroup\$ – my pronoun is monicareinstate May 11 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 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\$ – Jonathan Allan May 11 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 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
| improve this answer | |
\$\endgroup\$
  • \$\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\$ – Kevin Cruijssen May 11 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\$ – Jonathan Allan May 11 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!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ an alternative (which comes out to the same length, I think) is to use which.max. \$\endgroup\$ – JDL May 12 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\$ – Xi'an May 12 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 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\$ – Xi'an May 12 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
| improve this answer | |
\$\endgroup\$
  • 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\$ – Kevin Cruijssen May 11 at 18:09
  • 1
    \$\begingroup\$ Oh, so you are, my bad! \$\endgroup\$ – Jonathan Allan May 11 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!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Japt -h, 10 bytes

ApU õ ñ!sM

Try it

| improve this answer | |
\$\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.

| improve this answer | |
\$\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?

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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