Compute PI in Kotlin on a T-shirt












5












$begingroup$


I have written code in Kotlin with the objective of computing Pi in few enough lines so that it looks good on a t-shirt.



Can be cut and paste into http://try.kotlinlang.org under "My Programs" and run from browser - I just tested it with version 1.2.41 and it's working.





import kotlin.math.*
import java.math.BigInteger

fun main(args: Array<String>) {
val r = (4*(4*arccot(5) - arccot(239))).toString()
println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")
}

fun arccot(x:BigInteger):BigInteger {
var precision = 10.toBigInteger().pow(319) / x
var total = precision
var divisor = 1.toBigInteger()

while(precision.abs() >= divisor) {
precision = -precision / x.pow(2)
divisor += 2
total += precision / divisor
}
return total
}

fun arccot(x:Int) = arccot(x.toBigInteger())
operator fun Int.times(x: BigInteger) = this.toBigInteger() * x
operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


Currently it's longer than I'd like. I would like to shorten without making it less understandable. My vision is to have code that is readable enough it wouldn't be out of place in a production code base.



To give an idea, here's the significantly shorter Python version (which has been printed on a t-shirt and in my opinion looks good and is short enough but also quite readable). Can be run in browser here: https://repl.it/@sek/314-Digits - (there's also a link from there to the t-shirt if you are curious how that looks - the length in question isn't only the number of lines but also the width of the longest line as that determines the font size that can be used)



def pi():
r = 4*(4*arccot(5) - arccot(239))
return str(r)[0]+'.'+str(r)[1:-5]

def arccot(x):
total = power = 10**319 // x
divisor = 1
while abs(power) >= divisor:
power = -power // x**2
divisor += 2
total += power // divisor
return total

print("314 digits of Pi " + pi())









share|improve this question











$endgroup$












  • $begingroup$
    I'm sorry but that is wrong. Try this.
    $endgroup$
    – candied_orange
    May 25 '18 at 22:31


















5












$begingroup$


I have written code in Kotlin with the objective of computing Pi in few enough lines so that it looks good on a t-shirt.



Can be cut and paste into http://try.kotlinlang.org under "My Programs" and run from browser - I just tested it with version 1.2.41 and it's working.





import kotlin.math.*
import java.math.BigInteger

fun main(args: Array<String>) {
val r = (4*(4*arccot(5) - arccot(239))).toString()
println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")
}

fun arccot(x:BigInteger):BigInteger {
var precision = 10.toBigInteger().pow(319) / x
var total = precision
var divisor = 1.toBigInteger()

while(precision.abs() >= divisor) {
precision = -precision / x.pow(2)
divisor += 2
total += precision / divisor
}
return total
}

fun arccot(x:Int) = arccot(x.toBigInteger())
operator fun Int.times(x: BigInteger) = this.toBigInteger() * x
operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


Currently it's longer than I'd like. I would like to shorten without making it less understandable. My vision is to have code that is readable enough it wouldn't be out of place in a production code base.



To give an idea, here's the significantly shorter Python version (which has been printed on a t-shirt and in my opinion looks good and is short enough but also quite readable). Can be run in browser here: https://repl.it/@sek/314-Digits - (there's also a link from there to the t-shirt if you are curious how that looks - the length in question isn't only the number of lines but also the width of the longest line as that determines the font size that can be used)



def pi():
r = 4*(4*arccot(5) - arccot(239))
return str(r)[0]+'.'+str(r)[1:-5]

def arccot(x):
total = power = 10**319 // x
divisor = 1
while abs(power) >= divisor:
power = -power // x**2
divisor += 2
total += power // divisor
return total

print("314 digits of Pi " + pi())









share|improve this question











$endgroup$












  • $begingroup$
    I'm sorry but that is wrong. Try this.
    $endgroup$
    – candied_orange
    May 25 '18 at 22:31
















5












5








5





$begingroup$


I have written code in Kotlin with the objective of computing Pi in few enough lines so that it looks good on a t-shirt.



Can be cut and paste into http://try.kotlinlang.org under "My Programs" and run from browser - I just tested it with version 1.2.41 and it's working.





import kotlin.math.*
import java.math.BigInteger

fun main(args: Array<String>) {
val r = (4*(4*arccot(5) - arccot(239))).toString()
println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")
}

fun arccot(x:BigInteger):BigInteger {
var precision = 10.toBigInteger().pow(319) / x
var total = precision
var divisor = 1.toBigInteger()

while(precision.abs() >= divisor) {
precision = -precision / x.pow(2)
divisor += 2
total += precision / divisor
}
return total
}

fun arccot(x:Int) = arccot(x.toBigInteger())
operator fun Int.times(x: BigInteger) = this.toBigInteger() * x
operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


Currently it's longer than I'd like. I would like to shorten without making it less understandable. My vision is to have code that is readable enough it wouldn't be out of place in a production code base.



To give an idea, here's the significantly shorter Python version (which has been printed on a t-shirt and in my opinion looks good and is short enough but also quite readable). Can be run in browser here: https://repl.it/@sek/314-Digits - (there's also a link from there to the t-shirt if you are curious how that looks - the length in question isn't only the number of lines but also the width of the longest line as that determines the font size that can be used)



def pi():
r = 4*(4*arccot(5) - arccot(239))
return str(r)[0]+'.'+str(r)[1:-5]

def arccot(x):
total = power = 10**319 // x
divisor = 1
while abs(power) >= divisor:
power = -power // x**2
divisor += 2
total += power // divisor
return total

print("314 digits of Pi " + pi())









share|improve this question











$endgroup$




I have written code in Kotlin with the objective of computing Pi in few enough lines so that it looks good on a t-shirt.



Can be cut and paste into http://try.kotlinlang.org under "My Programs" and run from browser - I just tested it with version 1.2.41 and it's working.





import kotlin.math.*
import java.math.BigInteger

fun main(args: Array<String>) {
val r = (4*(4*arccot(5) - arccot(239))).toString()
println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")
}

fun arccot(x:BigInteger):BigInteger {
var precision = 10.toBigInteger().pow(319) / x
var total = precision
var divisor = 1.toBigInteger()

while(precision.abs() >= divisor) {
precision = -precision / x.pow(2)
divisor += 2
total += precision / divisor
}
return total
}

fun arccot(x:Int) = arccot(x.toBigInteger())
operator fun Int.times(x: BigInteger) = this.toBigInteger() * x
operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


Currently it's longer than I'd like. I would like to shorten without making it less understandable. My vision is to have code that is readable enough it wouldn't be out of place in a production code base.



To give an idea, here's the significantly shorter Python version (which has been printed on a t-shirt and in my opinion looks good and is short enough but also quite readable). Can be run in browser here: https://repl.it/@sek/314-Digits - (there's also a link from there to the t-shirt if you are curious how that looks - the length in question isn't only the number of lines but also the width of the longest line as that determines the font size that can be used)



def pi():
r = 4*(4*arccot(5) - arccot(239))
return str(r)[0]+'.'+str(r)[1:-5]

def arccot(x):
total = power = 10**319 // x
divisor = 1
while abs(power) >= divisor:
power = -power // x**2
divisor += 2
total += power // divisor
return total

print("314 digits of Pi " + pi())






numerical-methods kotlin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 8 mins ago







Stan Kurdziel

















asked May 25 '18 at 21:23









Stan KurdzielStan Kurdziel

1265




1265












  • $begingroup$
    I'm sorry but that is wrong. Try this.
    $endgroup$
    – candied_orange
    May 25 '18 at 22:31




















  • $begingroup$
    I'm sorry but that is wrong. Try this.
    $endgroup$
    – candied_orange
    May 25 '18 at 22:31


















$begingroup$
I'm sorry but that is wrong. Try this.
$endgroup$
– candied_orange
May 25 '18 at 22:31






$begingroup$
I'm sorry but that is wrong. Try this.
$endgroup$
– candied_orange
May 25 '18 at 22:31












1 Answer
1






active

oldest

votes


















3












$begingroup$

I noticed that you are calculating to 314 decimal places instead of 314 digits, so drop 6 instead of 5.





  • You really don't need the extra functions. You can remove



    fun arccot(x:Int) = arccot(x.toBigInteger())


    if you convert Int to BigInteger inside your arctan method.




  • You can remove



    operator fun Int.times(x: BigInteger) = this.toBigInteger() * x


    if you shl(2) instead of * 4.




  • You can remove



    operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


    if you change



    divisor += 2


    to



    divisor += BigInteger("2")



  • You can shorten



    println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")


    to



    println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")



  • Now, you can change the imports to



    import java.math.*


  • You don't have to declare the type for val r.



The final code I came up with by doing that is:



import java.math.*
fun main(args: Array<String>) {
val r = (acot(5).shl(2)-acot(239)).shl(2).toString()
println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")
}
fun acot(x:Int):BigInteger {
var precision = BigInteger.TEN.pow(319)/x.toBigInteger()
var total = precision
var divisor = BigInteger.ONE;
while(precision.abs() >= divisor) {
precision = -precision/(x.toBigInteger().pow(2))
divisor += BigInteger("2")
total += precision / divisor
}
return total
}


I also came up with shorter code, with decreased width, by calculating a different way:



import java.math.*
fun main(args:Array<String>) {
val b4 = BigDecimal(4)
val r = ((atan(5)*b4-atan(239))*b4).toString()
println("314 digits of Pi ${r.substring(0,315)}")
}
fun atan(xInv:Int):BigDecimal {
var x = BigDecimal(1).divide(BigDecimal(xInv),330,3)
var (numer, total) = arrayOf(x, x)
for (i in 3..450 step 2) {
numer = -numer * x * x
total += numer / BigDecimal(i)
}
return total
}





share|improve this answer











$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195181%2fcompute-pi-in-kotlin-on-a-t-shirt%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3












    $begingroup$

    I noticed that you are calculating to 314 decimal places instead of 314 digits, so drop 6 instead of 5.





    • You really don't need the extra functions. You can remove



      fun arccot(x:Int) = arccot(x.toBigInteger())


      if you convert Int to BigInteger inside your arctan method.




    • You can remove



      operator fun Int.times(x: BigInteger) = this.toBigInteger() * x


      if you shl(2) instead of * 4.




    • You can remove



      operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


      if you change



      divisor += 2


      to



      divisor += BigInteger("2")



    • You can shorten



      println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")


      to



      println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")



    • Now, you can change the imports to



      import java.math.*


    • You don't have to declare the type for val r.



    The final code I came up with by doing that is:



    import java.math.*
    fun main(args: Array<String>) {
    val r = (acot(5).shl(2)-acot(239)).shl(2).toString()
    println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")
    }
    fun acot(x:Int):BigInteger {
    var precision = BigInteger.TEN.pow(319)/x.toBigInteger()
    var total = precision
    var divisor = BigInteger.ONE;
    while(precision.abs() >= divisor) {
    precision = -precision/(x.toBigInteger().pow(2))
    divisor += BigInteger("2")
    total += precision / divisor
    }
    return total
    }


    I also came up with shorter code, with decreased width, by calculating a different way:



    import java.math.*
    fun main(args:Array<String>) {
    val b4 = BigDecimal(4)
    val r = ((atan(5)*b4-atan(239))*b4).toString()
    println("314 digits of Pi ${r.substring(0,315)}")
    }
    fun atan(xInv:Int):BigDecimal {
    var x = BigDecimal(1).divide(BigDecimal(xInv),330,3)
    var (numer, total) = arrayOf(x, x)
    for (i in 3..450 step 2) {
    numer = -numer * x * x
    total += numer / BigDecimal(i)
    }
    return total
    }





    share|improve this answer











    $endgroup$


















      3












      $begingroup$

      I noticed that you are calculating to 314 decimal places instead of 314 digits, so drop 6 instead of 5.





      • You really don't need the extra functions. You can remove



        fun arccot(x:Int) = arccot(x.toBigInteger())


        if you convert Int to BigInteger inside your arctan method.




      • You can remove



        operator fun Int.times(x: BigInteger) = this.toBigInteger() * x


        if you shl(2) instead of * 4.




      • You can remove



        operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


        if you change



        divisor += 2


        to



        divisor += BigInteger("2")



      • You can shorten



        println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")


        to



        println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")



      • Now, you can change the imports to



        import java.math.*


      • You don't have to declare the type for val r.



      The final code I came up with by doing that is:



      import java.math.*
      fun main(args: Array<String>) {
      val r = (acot(5).shl(2)-acot(239)).shl(2).toString()
      println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")
      }
      fun acot(x:Int):BigInteger {
      var precision = BigInteger.TEN.pow(319)/x.toBigInteger()
      var total = precision
      var divisor = BigInteger.ONE;
      while(precision.abs() >= divisor) {
      precision = -precision/(x.toBigInteger().pow(2))
      divisor += BigInteger("2")
      total += precision / divisor
      }
      return total
      }


      I also came up with shorter code, with decreased width, by calculating a different way:



      import java.math.*
      fun main(args:Array<String>) {
      val b4 = BigDecimal(4)
      val r = ((atan(5)*b4-atan(239))*b4).toString()
      println("314 digits of Pi ${r.substring(0,315)}")
      }
      fun atan(xInv:Int):BigDecimal {
      var x = BigDecimal(1).divide(BigDecimal(xInv),330,3)
      var (numer, total) = arrayOf(x, x)
      for (i in 3..450 step 2) {
      numer = -numer * x * x
      total += numer / BigDecimal(i)
      }
      return total
      }





      share|improve this answer











      $endgroup$
















        3












        3








        3





        $begingroup$

        I noticed that you are calculating to 314 decimal places instead of 314 digits, so drop 6 instead of 5.





        • You really don't need the extra functions. You can remove



          fun arccot(x:Int) = arccot(x.toBigInteger())


          if you convert Int to BigInteger inside your arctan method.




        • You can remove



          operator fun Int.times(x: BigInteger) = this.toBigInteger() * x


          if you shl(2) instead of * 4.




        • You can remove



          operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


          if you change



          divisor += 2


          to



          divisor += BigInteger("2")



        • You can shorten



          println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")


          to



          println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")



        • Now, you can change the imports to



          import java.math.*


        • You don't have to declare the type for val r.



        The final code I came up with by doing that is:



        import java.math.*
        fun main(args: Array<String>) {
        val r = (acot(5).shl(2)-acot(239)).shl(2).toString()
        println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")
        }
        fun acot(x:Int):BigInteger {
        var precision = BigInteger.TEN.pow(319)/x.toBigInteger()
        var total = precision
        var divisor = BigInteger.ONE;
        while(precision.abs() >= divisor) {
        precision = -precision/(x.toBigInteger().pow(2))
        divisor += BigInteger("2")
        total += precision / divisor
        }
        return total
        }


        I also came up with shorter code, with decreased width, by calculating a different way:



        import java.math.*
        fun main(args:Array<String>) {
        val b4 = BigDecimal(4)
        val r = ((atan(5)*b4-atan(239))*b4).toString()
        println("314 digits of Pi ${r.substring(0,315)}")
        }
        fun atan(xInv:Int):BigDecimal {
        var x = BigDecimal(1).divide(BigDecimal(xInv),330,3)
        var (numer, total) = arrayOf(x, x)
        for (i in 3..450 step 2) {
        numer = -numer * x * x
        total += numer / BigDecimal(i)
        }
        return total
        }





        share|improve this answer











        $endgroup$



        I noticed that you are calculating to 314 decimal places instead of 314 digits, so drop 6 instead of 5.





        • You really don't need the extra functions. You can remove



          fun arccot(x:Int) = arccot(x.toBigInteger())


          if you convert Int to BigInteger inside your arctan method.




        • You can remove



          operator fun Int.times(x: BigInteger) = this.toBigInteger() * x


          if you shl(2) instead of * 4.




        • You can remove



          operator fun BigInteger.plus(x: Int) = this + x.toBigInteger()


          if you change



          divisor += 2


          to



          divisor += BigInteger("2")



        • You can shorten



          println("314 digits of Pi ${r[0]}.${r.substring(1).dropLast(5)}")


          to



          println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")



        • Now, you can change the imports to



          import java.math.*


        • You don't have to declare the type for val r.



        The final code I came up with by doing that is:



        import java.math.*
        fun main(args: Array<String>) {
        val r = (acot(5).shl(2)-acot(239)).shl(2).toString()
        println("314 digits of Pi ${r[0]}.${r.substring(1,314)}")
        }
        fun acot(x:Int):BigInteger {
        var precision = BigInteger.TEN.pow(319)/x.toBigInteger()
        var total = precision
        var divisor = BigInteger.ONE;
        while(precision.abs() >= divisor) {
        precision = -precision/(x.toBigInteger().pow(2))
        divisor += BigInteger("2")
        total += precision / divisor
        }
        return total
        }


        I also came up with shorter code, with decreased width, by calculating a different way:



        import java.math.*
        fun main(args:Array<String>) {
        val b4 = BigDecimal(4)
        val r = ((atan(5)*b4-atan(239))*b4).toString()
        println("314 digits of Pi ${r.substring(0,315)}")
        }
        fun atan(xInv:Int):BigDecimal {
        var x = BigDecimal(1).divide(BigDecimal(xInv),330,3)
        var (numer, total) = arrayOf(x, x)
        for (i in 3..450 step 2) {
        numer = -numer * x * x
        total += numer / BigDecimal(i)
        }
        return total
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jun 24 '18 at 20:22

























        answered Jun 24 '18 at 19:58









        Zachary RudzikZachary Rudzik

        1386




        1386






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195181%2fcompute-pi-in-kotlin-on-a-t-shirt%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga