eph baum dot dev

← Back to blog

Condoning Another Pi Day

Published on 11/25/2023 01:34 PM by Eph Baum

Featured Image

11/24 wasn’t just Black Friday. It became another Pi day around here.

We had pie for breakfast, leftover from Thanksgiving. We had Quiche, an egg pie, for lunch. Finally, for dinner, we had ourselves some pizza pie from a local woodfire place that was delicious. For dessert, yep, more pie.

Pie day needed to be condoned, however.

1124

Those numbers definitely appear in Pi. I posit that all numeric sequence appear in Pi somewhere due to the nature of infinity and all.

I cheated and found them in a couple of sources that store the value of Pi to millions of places and doing a simple text search

It’s there.

But where?

I guessed it was in the first 10k to 100k places.

But I wanted to tell you, dear reader, that it was Pi day due to 1124 appearing at position n.

Calculating Pi?

Could I calculate that myself?

I could use the Chudnovsky algorithm.

There’s a python script in the Wiki page:

import decimal

def binary_split(a, b):
    if b == a + 1:
        Pab = -(6*a - 5)*(2*a - 1)*(6*a - 1)
        Qab = 10939058860032000 * a**3
        Rab = Pab * (545140134*a + 13591409)
    else:
        m = (a + b) // 2
        Pam, Qam, Ram = binary_split(a, m)
        Pmb, Qmb, Rmb = binary_split(m, b)
        
        Pab = Pam * Pmb
        Qab = Qam * Qmb
        Rab = Qmb * Ram + Pam * Rmb
    return Pab, Qab, Rab

def chudnovsky(n):
    P1n, Q1n, R1n = binary_split(1, n)
    return (426880 * decimal.Decimal(10005).sqrt() * Q1n) / (13591409*Q1n + R1n)

print(chudnovsky(2))  # 3.141592653589793238462643384

So, of course I could.

This method wouldn’t yield the precision I need.

You could do something like this to get to a certain precision:

from decimal import Decimal, getcontext
import math

def calculate_pi(precision):
"""
Calculate pi using the Chudnovsky algorithm to the specified precision.
"""
getcontext().prec = precision + 1  # Set precision
C = 426880 * Decimal(math.sqrt(10005))
M = 1
L = 13591409
X = 1
K = 6
S = L

for i in range(1, precision):
    M = (M * (K ** 3 - 16 * K)) // i ** 3 
    L += 545140134
    X *= -262537412640768000
    S += Decimal(M * L) / X
    K += 12

pi = C / S
return str(pi)[:precision]

# Calculate Pi to 100 digits
pi_100_digits = calculate_pi(100)
pi_100_digits

pi_100000_digits = calculate_pi(100000)
pi_100000_digits

It’s not the most efficient solution. I think I might have made repl.it mad when I tried to get 100,000 digits with the above. I gave up trying to even get to 10,000 digits in other 20 minutes of waiting.

It’s obviously not efficient - just look at it!

So, that didn’t seem like an easy enough path and I really didn’t want to spend all that much time / money on solving this problem. Also, I’m not a Python expert by any means.

Search a Pre-calculated Dataset

There are sources of this data around the internet, one need only do a little searching.

A couple of examples can be found here and here, so, easy enough, I have me some pi to search.

To find the digits with an existing dataset I figured I could:

So, back to repl.it I went looking to find the sequence in a pre-calculated dataset, like a chump who was too lazy to calculate Pi. Who has time to calculate Pi? I know it can be calculated but others have already done so, so I guess that’s good enough for me.

My first attempt was to whip up something in Rust because I’m always looking for excuses to use Rust. At first I used reqwest and tokio but, unfortunately, that resulted in some OpenSSL issues due to the dependency on OpenSSL that Repl.it didn’t meet and, so, I opted for a least resistant path and switched to a more simplistic blocking solution by using ureq and boom💥:

Sequence found at position: 25705

The code is simple:

fn find_sequence_in_url(url: &str, sequence: &str) -> Result<Option<usize>, Box<dyn std::error::Error>> {
    let response = ureq::get(url).call()?.into_string()?;

    Ok(response.find(sequence))
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = "https://www.mathsisfun.com/numbers/images/pi-million.txt";
    let sequence = "1124";

    match find_sequence_in_url(url, sequence)? {
        Some(position) => println!("Sequence found at position: {}", position),
        None => println!("Sequence not found"),
    }

    Ok(())
}

But it’s effective enough.

So, now I know that yesterday was another Pi day and that pattern appears only 25705 places into to Pi.

So, literally every day can be Pi day!

Enjoy your Pie!

Written by Eph Baum

← Back to blog
  • 50 Stars - Puzzle Solver (of Little Renown)

    50 Stars - Puzzle Solver (of Little Renown)

    Join Eph Baum as they recount their journey through the Advent of Code 2023. For the first time, Eph completes all puzzles, leveraging resources like GPT-4 and Code Llama. Despite the challenges and time constraints, Eph not only stays on top of the puzzles but also lands on the top 1,000 leaderboard. Dive into this post to explore the role of generative AIs in problem-solving and the joy of coding puzzles. - GitHub Co-pilot

  • Don't Trust AI - An Advent of Code Tale

    Don't Trust AI - An Advent of Code Tale

    Join Eph Baum in 'Don't Trust AI - An Advent of Code Tale' as they navigate the Advent of Code 2023. Despite the December rush, Eph is determined to complete all puzzles. This post shares an intriguing incident where an AI-generated code line proves less than helpful. Eph's journey underscores the importance of verifying AI suggestions, especially when optimizing code. Dive in to explore the challenges and triumphs of coding puzzles, and the role of AI in this process. - GitHub CoPilot

  • Condoning Another Pi Day

    Condoning Another Pi Day

    Placeholder description for imported post from Ghost Blog

  • ANSI Terminal Colors

    ANSI Terminal Colors

    Placeholder description for imported post from Ghost Blog

  • WTF is Idiomatic

    WTF is Idiomatic

    Placeholder description for imported post from Ghost Blog

  • From Early Return in OOP to Control Flow in Elixir - A Transition Guide

    From Early Return in OOP to Control Flow in Elixir - A Transition Guide

    Placeholder description for imported post from Ghost Blog