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\$ Commented May 11, 2020 at 14:34
  • 2
    \$\begingroup\$ I tried searching for it and didn't find anything, thanks for finding me this :) \$\endgroup\$ Commented May 11, 2020 at 15:01
  • \$\begingroup\$ Can the C code in OEIS really compute the answer for 12 digit \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented May 11, 2020 at 18:09
  • 1
    \$\begingroup\$ Oh, so you are, my bad! \$\endgroup\$ Commented 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\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.