Created
April 30, 2016 18:36
-
-
Save jackmott/bec1e4c7e84904702bac1dae97c25ae8 to your computer and use it in GitHub Desktop.
Solving https://mikesmathpage.wordpress.com/2016/04/29/a-strange-problem-i-overheard-bjorn-poonen-discussing/ with fs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Learn more about F# at http://fsharp.org | |
// See the 'F# Tutorial' project for more help. | |
open MathNet.Numerics | |
open System.Numerics | |
//create a fractional approximation of pi | |
let rec series n q = | |
seq { | |
yield q * 4N / n | |
yield! series (n + 2N) (q * -1N) } | |
let pi = series 1N 1N |> Seq.take 100 |> Seq.reduce (+) | |
printf "pi: %s \n\n" (pi.ToString()) | |
//caluclate a sqrt for BigRationals | |
let BrSqrt (x:BigRational) = | |
if x.IsOne || x.IsZero then | |
x | |
else | |
let mutable temp = BigRational.FromInt(1) | |
let precision = 100 | |
while temp.Numerator.ToString().Length < precision do | |
temp <- ((x / temp) + temp) / BigRational.FromInt(2) | |
temp | |
let rec factorial n = | |
match n with | |
| 0 -> BigInteger(1) | |
| 1 -> BigInteger(1) | |
| _ -> BigInteger(n) * factorial (n - 1) | |
let rec doubleFactorial n = | |
if n % 2 = 0 then | |
match n with | |
| 0 -> BigInteger(1) | |
| 2 -> BigInteger(2) | |
| _ -> BigInteger(n) * doubleFactorial (n - 2) | |
else | |
match n with | |
| 1 -> BigInteger(1) | |
| _ -> BigInteger(n) * doubleFactorial (n - 2) | |
//get volume of n-ball | |
let volumeSphere radius dimension = | |
if dimension % 2 = 0 then | |
let ik = dimension/2 | |
let result = (BigRational.Pow(pi,ik) / BigRational.FromBigInt(factorial ik)) * BigRational.Pow(radius,2*ik) | |
result | |
// ((pi ** (float)k) / (float)(factorial k)) * (radius ** (float)(2 * k)) | |
else | |
let ik = (dimension - 1) / 2 | |
let k = BigRational.FromInt((dimension - 1) / 2) | |
let twok1 =2*ik+1 | |
let two = BigRational.FromInt( 2) | |
let one = BigRational.FromInt(1) | |
let kp1 = ik+1 | |
let top = (BigRational.Pow (two,kp1)) * (BigRational.Pow (pi, ik) ) | |
let bottom = BigRational.FromBigInt( doubleFactorial twok1) | |
let r = top / bottom | |
let result = r * (BigRational.Pow(radius,twok1)) | |
result | |
// hypercube volume | |
let volumeCube length dimension = | |
BigRational.Pow(length, dimension) | |
// hypercube diagonal | |
let diagonalOfCube length dimension = | |
length * BrSqrt(dimension) | |
[<EntryPoint>] | |
let main argv = | |
//dimensions to check | |
[ 1205 .. 1207 ] | |
|> List.iter(fun e -> | |
//volume of smaller cubes | |
let vcube = volumeCube (BigRational.FromInt(1)) e | |
//colume of outter spheres | |
let vsphere = volumeSphere (BigRational.Parse("1/2")) e | |
//diagonal of smaller cubes | |
let diagcube = diagonalOfCube (BigRational.FromInt(1)) (BigRational.FromInt(e)) | |
//inner cricle radius | |
let innercircleradius = (diagcube - BigRational.FromInt(1)) / BigRational.FromInt(2) | |
//inner circle volume | |
let innercirclevolume = volumeSphere innercircleradius e | |
//large cube volume | |
let bigcubev = volumeCube (BigRational.FromInt(2)) e | |
//diff between circle and cube | |
let diff = innercirclevolume - bigcubev | |
let vsphereint = BigRational.ToBigInt(vsphere) | |
let diffint = BigRational.ToBigInt(diff) | |
let innervint = BigRational.ToBigInt(innercirclevolume) | |
let radint = BigRational.ToBigInt(innercircleradius) | |
printf "dim: %i " e | |
printf "incircrad: %s " (BigRational.ToBigInt(innercircleradius).ToString()) | |
printf "bigcube: %s " (BigRational.ToBigInt(bigcubev).ToString()) | |
printf "inv: %s " (innervint.ToString()) | |
printf "diff: %s\n" (diffint.ToString()) | |
) | |
System.Console.ReadLine() |> ignore | |
1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment