Передайте Пі… точно


11

Виходячи з оцінки Монте-Карло для Pi, це завдання полягає у створенні найкоротшого коду для константи Pi. Крім того, ваш код повинен виводити послідовні цифри pi назавжди.

Це кодовий гольф, тому найкоротше подання (у байтах) виграє, за винятком того, що на розумному ПК він повинен вивести перші 10000 цифр менше ніж за 10 секунд, і він ніколи не повинен закінчуватися.

Ви не можете використовувати будь-який вбудований для функцій Pi або trig.


Видалено жорсткий ліміт щодо розміру коду.


1
Під твіттом ви маєте на увазі, що код повинен містити менше 140 символів?
Ypnypn

5
Сама по собі проблема здається складною без обмеження характеру.
BobTheAwesome

1
@BobTheAwesome Видалено обмеження символів за популярним попитом.

1
@ mbomb007 Зовсім не очевидно, що десяткова крапка повинна бути надрукована або що цифри не можуть бути відокремлені пробілом. Завдання полягає лише в "виведенні послідовних цифр пі". Десяткова крапка не є цифрою. 3141...це що - послідовні цифри пі.
orlp

1
Найкраще було б, якби номер, роздрукований, був Pi, щоб між цифрами не було місця. Ще було б краще, якби вона включала десяткову точку.

Відповіді:


7

CJam - 48

3.1o{1YAZ2*:Z#*{_2$*2$2*)/@)\}h*]:+sX2*:X>X<o1}g

Це обчислює π як 2 * суму (k! / (2k + 1) !!) з більшою і більшою точністю і на кожному кроці друкує купу цифр з того місця, де вона зупинилася.

Ви можете спробувати в Інтернеті модифіковану версію, яка робить лише 8 (зовнішній цикл) ітерацій та друкує 512 цифр, або використовувати інтерпретатор Java для реальної речі. На моєму ноутбуці він отримує 16384 цифри приблизно за 6 секунд.

Примітка: ця програма дуже запам’ятовує пам'ять; краща поведінка, але трохи довша версія:

3.1o{T2AZ2*:Z#*1{@2$+@2$*2$2*)/@)1$}g;;sX2*:X>X<o1}g

Пояснення:

3.1o              print 3.1
{…1}g             repeat indefinitely
    1YA           push 1, 2 and 10 (Y=2, A=10)
    Z2*:Z         push Z*2 (Z=3 initially) and store back in Z
    #*            calculate 2*10^Z (2 from the formula and 10^Z for precision)
                  this is the term for k=0, and the earlier 1 represents k
    {…}h          do-while
                  at each iteration, the stack contains: terms, k, last-term
        _2$*      copy the previous term and k and multiply them
        2$2*)/    divide the previous number by 2*k+1
                  this is the current term of the series
        @)\       increment k and move it before the current term
                  the current term now serves as the loop condition
                  so the loop terminates when the term becomes 0
    *             multiply k and the last term (0), to get rid of k
    ]:+s          put all the terms in an array, add them and convert to string
                  we obtain an approximation of π*10^Z
    X2*:X         push X*2 (X=1 initially) and store back in X
    >X<o          print X digits starting from the X position

8

Пітон, 138 байт

q,r,t,i=1,180,60,2
while 1:u,y=27*i*(i+1)+6,(q*(27*i-12)+5*r)//(5*t);print(y,end="");q,r,t,i=10*q*i*(2*i-1),10*u*(q*(5*i-2)+r-y*t),t*u,i+1

Впровадження http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf .


Побийте мене до цього за 5 хвилин ..... :)
Мальтісен

Це чудово. Однак я сподівався, що всі цифри будуть в одному рядку. Іншими словами, щоб результат був схожий на Pi.

2
@Lembik Я змінив свою відповідь - на 7 байт довше, але тепер все в одному рядку.
orlp

5

GolfScript (81 символів)

1:i:^3{3i):i*(.(*3*.@*.5*3$27i*12-*+@^*:^5*/.print^*2$5i*2-*--\10*i*2i*(*\10*.}do

Демонстрація в Інтернеті (це набагато повільніше, ніж розумний робочий стіл, і має тривіальні зміни коду, щоб циклічно фіксувати кількість разів).

Я, звичайно, використовував алгоритм викрутки, про який я згадував у попередньому коментарі, але для того, щоб переоцінити його, мені знадобилось певний час. Алгоритм, представлений у роботі Гіббонса, є (псевдокод)

q = 1; r = 180; t = 60; i = 2
while (true) {
    u = 3*(3*i+1)*(3*i+2)
    y = (q*(27*i-12)+5*r) / (5*t)
    print y
    r += q*(5*i-2)-y*t
    r *= 10*u
    q *= 10*i*(2*i-1)
    t *= u
    i += 1
}

Наведений вище GolfScript еквівалентний (псевдокод)

t = i = q = 1; r = 3
while (true) {
    u = 3*(3*i+1)*(3*i+2)
    i += 1
    r *= u
    t *= u
    y = (q*(27*i-12)+5*r) / (5*t)
    print y
    r -= y*t - q*(5*i-2)
    q *= 10*i*(2*i-1)
    r *= 10
}

що зберігає деякі символи в ініціалізації та в управлінні стеком.


4

Pyth - 87 85 байт

Ще один переклад http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf . Я збирався зробити Python, але @orlp переміг мене до цього, тому я зробив Pyth. Досить маленький, щоб вмістити в твіт.

=H3=d1=bd=Gd#K+**hb27b6~b1=H*HK=d*dKJ/+*-*27b12G*5H*5d=H*T-H-*Jd*-*5b2G=G***GTbtybpkJ

Це дає вихід для stdout, хоча і з переривчастими кроками через буфер друку, який надходить від налаштування end=""друку. На даний момент я не друкую десяткову точку, оскільки специфікація говорить "послідовні цифри". Це завдання, які вбивають мою оцінку.

=H3                     Set H to 3
=d1                     Set d to 1
=bd                     Set b to d which is 1
=Gd                     Set G to d which is 1
#                       Infinte Loop
  K                     Set K to
    +**hb27b6           27*b*(b+1)+6
  ~b1                   b+=1
  =H*HK                 H*=K
  =d*dK                 d*=K
  J                     Set J to
    /                   Integer division
      +*-*27b12G*5H     G*(27*b-12)+5*H
      *5d               5*d
  =H                    Set H to
    *T-H-*Jd*-*5b2G     10*(H-(J*d -G*(5*b-2)))
  =G                    Set G to
    ***GTbtyb           G*10*b*(2*b-1)
  pkJ                   Print J with the end as "", not a newline

Спробуйте тут . (Примітка. Оскільки онлайн-інтерпретатор дає лише завершені результати, нескінченний цикл вийшов, тому він друкує лише перші 100, що збільшує розмір коду. Щоб випробувати нескінченний, завантажте локальний перекладач.)

Хронометраж

На мій екземпляр для обчислення хмари Google в залежності від часу, який він займав: real: 0m2.062sце, очевидно, досить швидко.


3

Скала, 599 байт

Код нижче - прямий порт коду Паскаля з Додатку 2 до алгоритму Шпіга для цифр Pi . Очевидно, що дуже мало гольфу ще зроблено. Код генерує 10000 цифр за 10 секунд, piSpigot(10000)і якщо у вас є нескінченна пам'ять, можна параметризувати для генерування багатьох цифр, але не нескінченних. Я не впевнений, чи відповідає це проблемам, тому, будь ласка, надайте зворотній зв'язок.

def piSpigot(n: Int): Unit = {
  val len=10*n/3
  var nines=0
  var predigit=0
  val a=Array.fill(len)(2)
  (1 to n).foreach {_=>
    var q=0
    (1 to n).reverse.foreach{i=>
      var x=10*a(i)+q*i
      a(i)=x%(2*i-1)
      q=x/(2*i-1)
    }
    a(1)=q%10
    q/=10
    if (q==9) {
      nines+=1
    } else if (q==10) {
      print(predigit+1)
      1.to(nines).foreach(_=>print(0))
      predigit=0
      nines=0
    } else {
      print(predigit)
      predigit=q
      if (nines!=0) {
        1.to(nines).foreach(_=>print(9))
        nines=0
      }
    }
  }
  println(predigit)
}
piSpigot(10000)

5
Я думаю, що вимога виробляти цифри ad infinitum означає, що вам потрібно використовувати алгоритм потокової передачі, а не той, який приймає параметр n. Дивіться, наприклад, cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
Пітер Тейлор

Нескінченна пам'ять і нескінченний час повинні давати нескінченну кількість цифр.

1

Befunge-98 (PyFunge), 120 байт

cf*10p'<20p11>00p1+:30p:::*+39**6+:30g39**c-00g*10gv
>:2*1-*00g*a*^
^:p02*g02p01*a*-*g02\+g01*g00-2*5g03,+*86:/*5g02+*5<

Спробуйте в Інтернеті!

Це граничне значення з точки зору часу. 10000 цифр займають близько 11 секунд на моєму ноутбуці, але я впевнений, що повинен бути "розумний" ПК, який міг би зробити це швидше.

Однак якщо ви спробуєте це в TIO, зауважте, що він нічого не поверне, доки не досягне 60-секундного обмеження, оскільки алгоритм призначений для продовження роботи. На той час у вас буде набагато більше 10 000 цифр.

Я використовую алгоритм шпигуна Джеремі Гіббонса, який, на мою думку, є таким же, як і більшість інших відповідей тут. Однак зауважте, що це покладається на інтерпретатора, що має довільну комірку пам’яті точності, і я знаю єдину реалізацію, яка підтримує, це PyFunge .

Пояснення

cf*10p                     Initialise r to 180.
      '<20p                Initialise t to 60.
           11              Initialise i and q on the stack to 1.

>                          Start of the main loop.
 00p                       Save the current value of q in memory.
    1+:30p                 Increment i and save a copy in memory.      
          :::*+39**6+      Calculate u = 27*(i*i+i)+6.
                     :     Make a duplicate, since we'll need two copies later.

       30g39**c-00g*10gv   Calculate y = (q*(27*i-12)+5*r)/(5*t).
              /*5g02+*5<
        ,+*86:             Convert y to a character so we can output it.

*a*-*g02\+g01*g00-2*5g03   Calculate r = 10*u*(q*(i*5-2)+r-y*t)

         p01               Save the updated r.
     *g02                  Calculate t = t*u
  p02                      Save the updated t.

>:2*1-*00g*a*              Calculate q = 10*q*i*(i*2-1).
^:
             ^             Return to the start of the main loop.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.