Піраціональні числа


14

Пі - ірраціональне число , що означає, що його десяткове подання ніколи не припиняється і не повторюється.

Pi усічений до 41 десяткової цифри (40 місць) є 3.1415926535897932384626433832795028841971.

Якщо ми ігноруємо десяткову точку і перераховуємо цифри як послідовність натуральних чисел, уникаючи дублікатів , отримуємо 3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 950 28 841 971( OEIS A064809 ).
(Помітьте, що 15з’являється в послідовності замість того, 1 5що 1вже відбулося.
Також зверніть увагу, що 0це не відбувається, оскільки воно не є позитивним; 950містить перший нуль.)

Для побудови першого піраціонального числа ми використовуємо цю послідовність для індексації до цифр Pi (перша цифра - 3, друга 1 тощо).

Отже, перша цифра першого пірараційного числа - це 3-я цифра Пі,
друга цифра - 1-я цифра Пі,
третя цифра - 4-та цифра Пі,
четверта - 15-та цифра Пі
та інше.
Десяткова крапка додається після першої цифри для імітації Pi.

Таким чином, перше піраціональне число - 41 цифра 4.3195195867462520687356193644029372991880.
(Зауважте, що для 30-ї цифри я повинен був пройти весь шлях до 974-ї цифри Пі.)

Для побудови другого піраціонального числа процес повторюють, використовуючи перше піраціональне число замість Pi. (Саму Pi можна назвати нульовим пірраційним числом.) Отже, нова послідовність є, 4 3 1 9 5 19 58 ...а перше піраційне число індексується для отримання другого, яке починається 9.14858....

Подальші піраціональні числа створюються таким же чином, кожне з яких створюється попереднім.

Виклик

Ваше завдання полягає в тому, щоб написати найкоротшу можливу програму, яка займає два цілих числа, Nі D, і виводить число Nпірраціонального числа, усічене до Dдесяткових цифр.

Dзавжди позитивний, але Nневід'ємний, і Dцифри Pi повинні виводитися, коли Nдорівнює 0.
Коли Dце значення 1, не має значення, присутній чи ні десяткова крапка.

Вхід повинен надходити від stdin або командного рядка, а вихід повинен переходити до stdout (або найближчих альтернатив вашої мови).

Ваша програма повинна працювати для всіх вхідних значень Nта Dнижче 2 16 , але вона не повинна бути своєчасною та ефективною.

Виграє найкоротший код у байтах .

(Зверніть увагу, що пірраціональні цифри існують в інших базах, але все, що стосується цього завдання, робиться в базі 10.)


Чи можемо ми використовувати вбудовані довільно-точні подання Pi для отримання його цифр?
Мартін Ендер

1
@ MartinBüttner Звичайно. Ви навіть можете отримати цифри пі в Інтернеті, якщо хочете, доки тільки отримуєте цифри пі.
Захоплення Кальвіна

@ Calvin'sHobbies: Ну добре, щоб я міг просто мати перші 64кі цифри пі у файлі? Чи слід додати +1 до імені файлу?
Клавдіу

Чи правильний діапазон введення? Для N=1, D=13393наприклад, вам потрібна 31 - мільйонної цифри PI
Клаудіу

Перші 1 мільярд цифр числа пі тільки отримує вас 42598 цифри 1 - го числа pirrational
Клаудіу

Відповіді:


3

Python 292 байти

Досить неефективно, мені вдалося отримати лише кілька цифр N = 3 і жодну з N = 4.

import sympy
def P(N,D,s=''):
 if N<1:return'3'+`sympy.pi.evalf(D+9)`[2:-9]
 for i in range(D):
    h=[];l='';j=i;x=0
    while-~j:
     x+=1;d=P(N-1,x)[-1];l+=d
     while'1'>P(N-1,x+1)[-1]:x+=1;l+='0'
     if(l in h)<1:h+=[l];l='';j-=1
    s+=P(N-1,int(h[i]))[-1]
 return s
s=P(*input())
print s[0]+'.'+s[1:]

Зразок введення:

0,20
3.1415926535897932384

1,20
4.3195195867462520687

2,10
9.148583196

3,5
9.9815

Гольфи: змінити =="0"на <"1". Зробіть внутрішню петлю однією лінією. Приберіть пробіли навколо x += 1. if l not in h-> if(l in h)<1: N==0->N<1
isaacg

@isaacg Спасибі за це, я трохи поспішав, коли розміщував та пропускав деякі очевидні речі. Напевно, я б не зрозумів, що ти можеш порівняти рядки, хоча if(l in h)<1це також досить розумно.
KSab

Ще дещо: ініціалізуйте sяк параметр P( def P(N,D,s=''):). str(...)можливо, можна писати із зворотними посиланнями. while'1'>...економить простір. Складіть hнабір і ініціалізуйте h=l,={''}, а потім напишіть l in hяк {l}<h.
flornquake

@flornquake Це досить розумно, особливо те, як ви ініціалізуєте його, щоб python не вважав його диктом. Поки я це робив, я зрозумів досить велику оптимізацію, яку, на жаль, потрібно hбуло замовити. І все-таки це акуратний трюк, який я спробую запам’ятати.
KSab

@KSab Це ще краще. :) while j+1:можна скоротити до while-~j, btw.
flornquake

4

Хаскелл, 431 400 369

import Data.List
g(q,r,t,k,n,l)|4*q+r-t<n*t=n:g(q#0,(r-n*t)#0,t,k,div(r#(30*q))t-n#0,l)|1<2=g(q*k,(2*q+r)*l,t*l,k+1,div(q*(7*k+2)+r*l)(t*l),l+2)
u w@(x:y:xs)=x:v y xs 0 w
v a(r:s)n w|a`elem`take n(u w)||r==0=v(a#r)s n w|1<2=a:v r s(n+1)w
m p=map(genericIndex p.pred)$u p
a#b=a*10+b
(x:s)%n=show x++'.':show(foldl1(#)$n`take`s)
f n d=print$iterate m(g(1,0,1,1,3,3))!!n%d

Треба любити нескінченні списки! Враховуючи достатньо часу та пам'яті, ця програма врешті обчислить правильну відповідь на будь-які N та D (я припускаю).

Я генерую цифри пі за gдопомогою алгоритму шпигуна (безсоромно викраденого у хлопця на ім'я Стенлі Рабіновіц), групуючи цифри / створюючи послідовність, використовуючи vта генеруючи пірраціональне число за допомогою цього m.

Ось це в дії:

λ> f 0 10
"3.1415926535"
λ> f 1 10
"4.3195195867"
λ> f 2 10
"9.Interrupted. --didn't have the time to wait for this to finish
λ> f 2 4
"9.1485"

1
Я подумав "Haskell!" коли я побачив це питання, прокрутився вниз і посміхнувся.
Soham Chowdhury
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.