21
\$\begingroup\$

Inspired by Bake a slice of Pi

Challenge

Given input 3 <= n <= 100 and 3 <= y <= n, construct an n x n matrix of the decimal portion of pi (14159...), starting in the top left. Then, take the upper-right triangle of size y x y and concatenate it together. Output the resulting number.

For example, for input n = 5, y = 3, the following matrix is constructed

14159
26535
89793
23846
26433

Then, the upper-right 3 x 3 triangle would be

159
 35
  3

so 159353 is the output.

Input

Two integers -- n representing the size of the square matrix of the digits of pi, and y representing the upper-right triangle -- in any convenient format.

Output

  • The resulting sliced and concatenated number, either printed/displayed to the screen, returned as a string, etc.
  • Trailing/leading whitespace is optional, so long as there's no whitespace in the output (i.e., 159 35 3 or the like would be invalid).
  • Note that since we're explicitly looking for the digits of pi, and not an approximation or mathematical calculation, answers should not round the final digit of the matrix.

Rules

  • This is so all the usual rules for golfing apply, and the shortest code (in bytes) wins.
  • Either a full program or function are acceptable.
  • Standard loopholes are forbidden.

Examples

 n  y  output
-------------
 3  3  141923
 5  3  159353
 6  4  1592589383
 6  6  141592535893238643794
20 12  358979323846950288419715820974944628620899211706792306647223172745025559196615
\$\endgroup\$
2
  • \$\begingroup\$ Thanks. Also, can the last digit be rounded? Some answers seem to do that, and it could be really difficult to avoid it \$\endgroup\$
    – Luis Mendo
    Commented Oct 13, 2016 at 21:10
  • 1
    \$\begingroup\$ @LuisMendo That's a good point. No, there should not be rounding of the last digit, since we're looking for the actual digits of pi, not an approximation or calculation. I'll clarify that and verify with the answerers. \$\endgroup\$ Commented Oct 14, 2016 at 12:23

6 Answers 6

7
\$\begingroup\$

05AB1E, 19 bytes

Uses CP-1252 encoding.

nžs¦¦¹ôI£íRvyN>£J}R

Try it online!

Explanation

n=5, y=3 used for example

nžs                  # push pi to n^2 digits
                     # STACK: 3.1415926535897932384626433
   ¦¦                # remove the first 2 chars
                     # STACK: 1415926535897932384626433
     ¹ô              # split into n*n matrix
                     # STACK: ['14159', '26535', '89793', '23846', '26433']
       I£            # keep the first y rows
                     # STACK: ['14159', '26535', '89793']
         íR          # reverse the list of rows and each individual row
                     # STACK: ['39798', '53562', '95141']
           v     }   # for each y,N (row, index) in the list
            yN>£J    # keep the first index+1 digits of the row and join to string
                     # STACK: 353951
                  R  # reverse the string
                     # STACK: 159353
                     # implicit print
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Congrats for 10k! \$\endgroup\$ Commented Oct 15, 2016 at 13:03
5
\$\begingroup\$

Python 2 (with sympy), 100 bytes

from sympy import*
lambda n,y:''.join(c for i,c in enumerate(`pi.round(n*n+1)`[2:])if i%n-i/n>n-y-1)

No sympy, 260 246 244 233 231 218 bytes

p=lambda n,y,a=-30,b=10,c=3,d=2,e=0,f=5,s='',i=0:i<n*n and p(n,y,*[((2*b+a)*f,b*d,c*f,d+1,(b*(7*d)+2+(a*f))/(c*f),f+2,s,i),(10*(a-e*c),10*b,c,d,((10*(3*b+a))/c)-10*e,f,s+(str(e)[:i%n-i/n>n-y-1]),i+1)][4*b+a-c<e*c])or s

This employs "The Spigot Algorithm For Pi" of Stanley Rabinowitz and Stan Wagon.

The standard arguments would be a,b,c,d,e,f=0,1,1,1,3,3 to yield the first digit of pi, 3, since that is not required the algorithm is initialised to the point before 1 is yielded, which saves two bytes even though a and b are longer as the result does not require slicing and i can start at 0 rather than -1.

Hits default recursion limit for last test case
Uses // for the first of the divisions so that str(v) may be replaced by `v` (otherwise it would end in L for a long).
repl.it


A non-recursive version for 232 bytes which evaluates the last test case too:

def p(n,y):
 a,b,c,d,e,f,i,s=-30,10,3,2,0,5,0,''
 while i<n*n:
    if 4*b+a-c<e*c:s+=`e`[:i%n-i/n>n-y-1];g=10*(a-e*c);e=((10*(3*b+a))//c)-10*e;b*=10;i+=1
    else:g=(2*b+a)*f;h=(b*(7*d)+2+(a*f))/(c*f);b*=d;c*=f;f+=2;d+=1;e=h
    a=g
 print s

repl.it (first indent is one space, second indent is one tab)

\$\endgroup\$
3
  • \$\begingroup\$ That "no sympy" version is impressive :) \$\endgroup\$
    – Emigna
    Commented Oct 13, 2016 at 16:35
  • 1
    \$\begingroup\$ I added a link, it's not my algorithm! \$\endgroup\$ Commented Oct 13, 2016 at 16:36
  • \$\begingroup\$ ...but if you want to "memorise" Pi to a million digits, this is probably easier \$\endgroup\$ Commented Oct 13, 2016 at 16:43
4
\$\begingroup\$

Mathematica, 82 bytes

Print@@Join@@Partition[RealDigits[Pi-3,10,#^2][[1]],#][[i,i-#2-1;;]]~Table~{i,#2}&
\$\endgroup\$
2
  • \$\begingroup\$ You can use #&@@ instead of [[1]]. \$\endgroup\$ Commented Oct 13, 2016 at 15:56
  • \$\begingroup\$ @TimmyD Nope. It truncates. (n = 10, y = 10 gives 1415926535979323846433832798841971937510749448164899259; the last 9 is the 100th digit of pi, and the 101th digit is 8 -- no rounding) \$\endgroup\$ Commented Oct 14, 2016 at 14:54
3
\$\begingroup\$

MATL, 23 22 27 bytes

1 Byte saved thanks to @Luis

UtEYPwY$IbH+&:)GetGi-&R!g)!

Try it Online

Explanation

        % Implicitly grab input (n)
Ut      % Square n and duplicate
E       % Multiply n^2 by 2
YP      % Pi literal
w       % Flip the stack
Y$      % Compute the first 2 * (n^2) digits of pi (accounts for rounding)
IbH+&:) % Grab the first n^2 digits after the decimal
Ge      % Reshape it into an n x n matrix in row-major ordering
t       % Duplicate this matrix
Gi-     % Grab the second input (y) and compute the difference between n and y
&R!     % Get the upper diagonal part and transpose to convert to lower diagonal
g)      % Convert it to a logical array and use it to select the digits of interest
!       % Transpose the result and implicitly display
\$\endgroup\$
2
  • \$\begingroup\$ @LuisMendo Ah! I knew we had a function for that but couldn't find it. Thanks! \$\endgroup\$
    – Suever
    Commented Oct 13, 2016 at 23:04
  • \$\begingroup\$ @TimmyD Thanks for noticing. Updated. \$\endgroup\$
    – Suever
    Commented Oct 14, 2016 at 12:49
2
\$\begingroup\$

Perl, 67 bytes

s/ /bpi++$_**2/e;$%=$';$%-=print/(.{$%})$/ for/\d{$`}/g

Requires the command line option -nMbignum=bpi, counted as 12. Input is taken from stdin.

Sample Usage

$ echo 3 3 | perl -nMbignum=bpi primo-square-pi.pl
141923

$ echo 5 3 | perl -nMbignum=bpi primo-square-pi.pl
159353

$ echo 6 4 | perl -nMbignum=bpi primo-square-pi.pl
1592589383

$ echo 6 6 | perl -nMbignum=bpi primo-square-pi.pl
141592535893238643794

$ echo 20 12 | perl -nMbignum=bpi primo-square-pi.pl
358979323846950288419715820974944628620899211706792306647223172745025559196615
\$\endgroup\$
0
\$\begingroup\$

C#, 232 bytes 268 bytes

Edit:

I originally used a constant string for Pi outside of the method, but it seems this was cheating. I've had to use the C# Math.PI value, which only has 14 decimal places, so the highest m value I can use is 3. Back to the drawing board...

Golfed:

IEnumerable<string>f(int m,int t){var a=new string[m, m];var b=Math.PI.ToString().Replace("3.","").Substring(0,m*m).ToArray();var c=0;for(int i=0;i<m;i++){for(int j=0;j<m;j++){a[i, j]=b[c]+"";c++;}}c=0;while(t>0){for(int i=t;i>0;i--){yield return a[c,m-i];}t--;c++;}}}

Ungolfed:

  class ATriangularSliceOfSquaredPi
  {
    //http://www.piday.org/million/
    //const string p = "1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831";

    public IEnumerable<string> f(int m, int t)
        {
          var a = new string[m, m];

          //var b = p.Substring(0, m * m).ToArray();
          var b = Math.PI.ToString().Replace("3.", "").Substring(0, m * m).ToArray();

          var c = 0;

          for (int i = 0; i < m; i++)
          {
            for (int j = 0; j < m; j++)
            {
              a[i, j] = b[c] + "";
              c++;
            }
          }

          c = 0;

          while (t > 0)
          {
            for (int i = t; i > 0; i--)
            {
              yield return a[c, m - i];
            }
            t--;
            c++;
          }
        }
      }

Not the shortest answer, but I was just happy I solved this one...

Test Output:

m   t   output
3   3   141923

5 3 159353
6 4 1592589383
6 6 141592535893238643794
20 12 358979323846950288419715820974944628620899211706792306647223172745025559196615

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice answer! Sadly, if you're using p and it's not a built-in in the language (which I'm pretty sure it isn't), you'll need to include that in your byte score. \$\endgroup\$ Commented Oct 14, 2016 at 16:21
  • \$\begingroup\$ @TimmyD Oh no! Ok, leave it with me!! If I simply paste my pi numbers in that will require 400+ more bytes, so I think a different approach is required... :) \$\endgroup\$
    – Pete Arden
    Commented Oct 14, 2016 at 16:32

Your Answer

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

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