A Triangular Slice of Squared Pi

21

1

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

AdmBorkBork

Posted 2016-10-13T14:33:29.293

Reputation: 41 581

Thanks. Also, can the last digit be rounded? Some answers seem to do that, and it could be really difficult to avoid it – Luis Mendo – 2016-10-13T21:10:56.817

1@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. – AdmBorkBork – 2016-10-14T12:23:23.703

Answers

7

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

Emigna

Posted 2016-10-13T14:33:29.293

Reputation: 50 798

1Congrats for 10k! – Erik the Outgolfer – 2016-10-15T13:03:24.750

5

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)

Jonathan Allan

Posted 2016-10-13T14:33:29.293

Reputation: 67 804

That "no sympy" version is impressive :) – Emigna – 2016-10-13T16:35:44.143

1I added a link, it's not my algorithm! – Jonathan Allan – 2016-10-13T16:36:40.463

...but if you want to "memorise" Pi to a million digits, this is probably easier – Jonathan Allan – 2016-10-13T16:43:00.530

4

Mathematica, 82 bytes

Print@@Join@@Partition[RealDigits[Pi-3,10,#^2][[1]],#][[i,i-#2-1;;]]~Table~{i,#2}&

JungHwan Min

Posted 2016-10-13T14:33:29.293

Reputation: 13 290

You can use #&@@ instead of [[1]]. – Martin Ender – 2016-10-13T15:56:28.983

@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) – JungHwan Min – 2016-10-14T14:54:56.603

3

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

Suever

Posted 2016-10-13T14:33:29.293

Reputation: 10 257

@LuisMendo Ah! I knew we had a function for that but couldn't find it. Thanks! – Suever – 2016-10-13T23:04:22.500

@TimmyD Thanks for noticing. Updated. – Suever – 2016-10-14T12:49:04.303

2

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

primo

Posted 2016-10-13T14:33:29.293

Reputation: 30 891

0

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

Pete Arden

Posted 2016-10-13T14:33:29.293

Reputation: 1 151

1Nice 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. – AdmBorkBork – 2016-10-14T16:21:57.030

@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... :) – Pete Arden – 2016-10-14T16:32:05.863