-3
\$\begingroup\$

Introduction

In the not so distant future with the AI revolution, we will need a way to solve their captchas to prove we're not humans.

This challenge was inspired by CommitStrip.

Challenge

One such captcha is the challenge of calculating the sum of all odd digits of Pi from digit 1 to digit n, including the first digit, being 3.

Output

  • The calculated sum of all odd digits in the range 1 to n.

Rules

  • All the digits of pi must be calculated by your program at runtime, how you implement that is up to you.
  • Hard-coded constants of pi are not allowed.
  • This is , so shortest bytes win.

Example

If n = 6, we must find the sum of the odd digits in [3, 1, 4, 1, 5, 9] meaning an output of 19

Other

Since this questions keeps getting marked as a duplicate of this, allow me to explain how this is different.

This question asks for the sum of a range of numbers, not finding the nth decimal.

\$\endgroup\$
13
  • \$\begingroup\$ Does the range include the first 3? Does the count start at that three (is it the first element or is it seperate from the count, i.e, the zeroth element)? \$\endgroup\$
    – sagiksp
    Commented Jul 7, 2018 at 10:38
  • 4
    \$\begingroup\$ @Mackan90096 Even though you've specified the output "Must be Calculated", this requirement is Non-observable, meaning it's difficult and case-by-case to determine if an answer is valid. It would be easier to define your challenge in such as way that hard-coding the answer isn't a good tactic, like having variable input. \$\endgroup\$
    – ATaco
    Commented Jul 7, 2018 at 11:23
  • 2
    \$\begingroup\$ Also, I meant the three at the start, the first digit, not the first three digits like you wrote. \$\endgroup\$
    – sagiksp
    Commented Jul 7, 2018 at 12:15
  • 3
    \$\begingroup\$ All the digits of pi must be calculated by your program: does that mean no hardcoding of the first N digits of PI or no built-in at all? (Edit: apparently, this rule comes from the initial version of the challenge, where the number of digits was fixed to 31415. Now that the length is taken as input, it should probably be removed.) \$\endgroup\$
    – Arnauld
    Commented Jul 7, 2018 at 14:08
  • 11
    \$\begingroup\$ "All the digits of pi must be calculated by your program" is a non-observable requirement, so I'd recommend removing it. \$\endgroup\$ Commented Jul 7, 2018 at 15:06

7 Answers 7

3
\$\begingroup\$

Python3, 346 bytes

Based on a recursive implementation of the Chudnovsky algorithm, one of the fastest algorithms to estimate pi. For each iteration, roughly 14 digits are estimated (take a look here for further details).

def f(n):import decimal as d;d.getcontext().prec=n+10;q=lambda n,k=6,m=1,l=13591409,x=1,i=1:(d.Decimal(((k**3-16*k)*m//i**3)*(l+545140134))/(x*-262537412640768000)+q(n,k+12,(k**3-16*k)*m//i**3,l+545140134,x*-262537412640768000,i+1)if i<n else 13591409);return sum([ord(i)%2 and int(i)for i in str(426880*d.Decimal(10005).sqrt()/q(n//14+1))[:n+1]])

Ungolfed version

def f(n):
    import decimal as d
    d.getcontext().prec = n + 10
    q=lambda n, k=6, m=1, l=13591409, x=1, i=1:\
        (d.Decimal(((k ** 3 - 16 * k) * m // i**3) * (l + 545140134)) / (x * -262537412640768000) +
         q(n, k+12, (k ** 3 - 16 * k) * m // i**3, l + 545140134, x * -262537412640768000, i+1)if i < n else 13591409)
    return sum([ord(i) % 2 and int(i)for i in
                str(426880 * d.Decimal(10005).sqrt() / q(n // 14+1))[:n + 1]])

Function q computes the value of S(see the reference), than it is used to divide the term 426880 * d.Decimal(10005).sqrt() and get the value of the approximation of pi. The precision is controlled by setting the value of d.getcontext().prec.

A a little bit longer (372 bytes), more golfed but all-in-one version:

f=lambda n,k=6,m=1,l=13591409,x=1,i=0:not i and(exec('global d;import decimal as d;d.getcontext().prec=%d+10'%n)or sum([ord(i)%2 and int(i)for i in str(426880*d.Decimal(10005).sqrt()/f(n//14+1,k,m,l,x,1))[:n+1]]))or i<n and d.Decimal(((k**3-16*k)*m//i**3)*(l+545140134))/(x*-262537412640768000)+f(n,k+12,(k**3-16*k)*m//i**3,l+545140134,x*-262537412640768000,i+1)or 13591409

Thanks to O.O.Balance to push me to go deeper into this challenge: it was very fun and interesting.

Old answer, based on math.pi (74 bytes)

import math;f=lambda n:sum([ord(i)%2and int(i)for i in"%.*G"%(n,math.pi)])

Try it online!

N.B.: math.pi is "The mathematical constant π = 3.141592…, to available precision.", but the digits for the challenge are computed on the fly through the rounding and truncating operations. So, technically this is not a violation of the rules: "all the digits of pi must be calculated by your program at runtime."

\$\endgroup\$
5
  • \$\begingroup\$ The problem with your answer is that the maximum n it supports is way too small. repl.it/repls/WittyPoliteBug \$\endgroup\$ Commented Jul 8, 2018 at 10:17
  • \$\begingroup\$ @O.O.Balance I think I've fixed the problem. Thanks for the review. \$\endgroup\$
    – PieCot
    Commented Jul 8, 2018 at 12:47
  • \$\begingroup\$ Looks good now :-) \$\endgroup\$ Commented Jul 8, 2018 at 13:29
  • \$\begingroup\$ There's some great work here. Please vote for the question to be reopened. \$\endgroup\$
    – user15259
    Commented Jul 9, 2018 at 3:03
  • \$\begingroup\$ @YiminRong This can be trivially ported to the other challenge. \$\endgroup\$
    – user202729
    Commented Jul 9, 2018 at 3:26
1
\$\begingroup\$

Mathematica, 53 bytes

Total@DeleteCases[(RealDigits@N[Pi,#])[[1]],_?EvenQ]&

Mathematica noob, please excuse me.

\$\endgroup\$
3
  • \$\begingroup\$ I don‘t think that should count as "calculating all the digits of pi by your program". \$\endgroup\$ Commented Jul 7, 2018 at 13:47
  • 2
    \$\begingroup\$ It is frequently done in other pi-related challeanges, I don't see the problem.. Mathematica is generating pi to the number of digits requested, I believe the poster meant to not use any hardcoded constants. \$\endgroup\$
    – sagiksp
    Commented Jul 7, 2018 at 14:22
  • \$\begingroup\$ That's what I meant, @sagiksp, updated the post to clarify that. \$\endgroup\$ Commented Jul 7, 2018 at 14:31
1
\$\begingroup\$

Ruby, 78 bytes

f=->n{"#{eval'x=2*10**n+p*x/=2+p+p-=1;'*x=p=4*n}"[0,n].bytes.sum{|c|c%2*c%16}}

Computes only to necessary precision.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Husk, 7 bytes

As you can see here1 the following program, does indeed compute all the digits itself:

Σf%2↑İπ

Try it online!

Explanation

Σf%2↑İπ  -- implicit input N, eg: 8
     İπ  -- compute all digits of pi: [3,1,4,1,5,9,2,6,5,3,...
    ↑    -- take N: [3,1,4,1,5,9,2,6]
 f%2     -- filter out even ones: [3,1,1,5,9]
Σ        -- sum: 19

1: This is a link to the Haskell code which is generated by Husk, in case you're lost (it's quite long) just search for func_intseq 'π'..

\$\endgroup\$
0
\$\begingroup\$

Java 10, 275 bytes

import java.math.*;
n->{int j,t,i=0,s=3;for(;i<n-1;++i){var a=BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));var p=a;for(j=1;a.signum()>0;p=p.add(a))a=a.multiply(new BigInteger(j+"")).divide(new BigInteger((2*j+++1)+""));s+=((t=(p+"").charAt(i+1)-48)%2)*t;}return s;}

Uses the approach from this answer by Kevin Cruijssen to calculate the digits. Try it online here.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 119 bytes

y=sum([int(i)for i in str(sum([4/j if j%4%3 else-4/j for j in range(10**8)if j%2]))[0:n+1].replace('.','')if int(i)%2])

My first code-golf submit, so please be gentle ._.

This computes pi on the fly using the Gregory-Leibniz series. X may prove insufficient for big n, but be aware of the RAMifications of choosing a large x.

Explanation:

Computation of Pi:

i.e. sum( [4/i if i%4==1 else -4/i for i in range(x) if i%2==1] ) with x as large as sensible, also i%4==1 is one byte larger than i%4%3, so that's nice...

Casting a lot and eventual sum:

I'm sure there are better possibilities than all this, but I cast the float to string, take the first n*1 chars (including the dec point), replace the point, then cast each char in my string to int for the modulo check at the very end of the code, and take the sum of all i that are odd to assign them to y.

Room for improvement:

I'm sure there's lots, but I am the least happy with the series to compute pi, and also with the multiple int() casts ad the need to replace the dec point... HELP

\$\endgroup\$
7
  • \$\begingroup\$ import math y=sum([int(i) for i in str(math.atan(1)*4)[0:n+1].replace('.','') if int(i)%2]) is 91 bytes and calculates pi using math.atan - probably well within the requirements of calculating pi on the fly, and the issue of lacking precision is gone i guess. if this is indeed legal calculation of pi in this task, i will replace it. \$\endgroup\$
    – FloMei
    Commented Jul 8, 2018 at 0:45
  • \$\begingroup\$ Any solution based on floating points will be wrong after about the 17th digit. \$\endgroup\$
    – feersum
    Commented Jul 8, 2018 at 9:42
  • \$\begingroup\$ both math.pi and math.atan seem to manage 48 digits after the decimal point...same if it is casted to float. Instead of displaying the full decimal value, many languages (including older versions of Python), round the result to 17 significant digits - found that here,so maybe your reply is for python 2? \$\endgroup\$
    – FloMei
    Commented Jul 8, 2018 at 10:27
  • 1
    \$\begingroup\$ Sure, you can print out math.pi to an arbitrarily large amount of digits, but (after a point) those digits are incorrect! They are not the digits of pi. \$\endgroup\$
    – feersum
    Commented Jul 8, 2018 at 13:38
  • \$\begingroup\$ print('{:10.100f}'.format(math.pi)) yields 3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000, and for the non-zero digits, they are true to the value of pi if one looks them up. what other method would you recommend to use? if one computes them with a series (as my answer does) they will also be inaccurate after some number of digits, as is the nature of pi calculation as i understand it. if you suggest a more efficient series i am glad to consider it. \$\endgroup\$
    – FloMei
    Commented Jul 8, 2018 at 15:25
0
\$\begingroup\$

SmallTalk – 299 bytes

Relies on the identity tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., and that π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239), so no “cheats”.

|l a b c d e f g h p t s|l:=stdin nextLine asInteger. a:=1/5. b:=1/239. c:=a. d:=b. e:=a. f:=b. g:=3. h:=-1. s:=0. l timesRepeat:[c:=c*a*a. d:=d*b*b. e:=h*c/g+e. f:=h*d/g+f. g:=g+2. h:=0-h]. p:=4*e-f*4. l timesRepeat:[t:=p floor. p:=(p-t)*10. t odd ifTrue:[s:=s+t]]. Transcript show:s printString;cr

Save as pi.st. You provide the number of digits from the console when you run it, or through the <<< operator.

$ gst -q pi.st <<< 6
19
\$\endgroup\$

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