Пиррационные числа

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содержит первый ноль.)

Чтобы построить первое число pirrational, мы используем эту последовательность для индексации цифр числа Pi (первая цифра - 3, вторая - 1 и т. Д.).

Таким образом, первая цифра первого пиративного числа - это третья цифра числа Пи,
вторая цифра - первая цифра числа Пи,
третья цифра - это четвертая цифра числа Пи,
четвертая цифра - пятая цифра числа Пи
и т. Д.
Десятичная точка добавляется после первой цифры, чтобы имитировать Pi.

Таким образом, первое число до 41 цифры 4.3195195867462520687356193644029372991880.
(Обратите внимание, что для 30-й цифры мне пришлось пройти весь путь до 974-й цифры Пи.)

Чтобы построить второе число pirrational, процесс повторяют, используя первое число piral вместо 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 миллиард цифр числа пи дают вам только 42 598 цифр 1-го числа
Клаудиу

Ответы:

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
KSab
источник
Гольфы: изменить =="0"на <"1". Сделайте внутренний цикл while одну строку. Удалить пробелы вокруг x += 1. if l not in h-> if(l in h)<1: N==0->N<1
Исаак
@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, кстати.
землетрясение
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помощью алгоритма spigot (бессовестно украденного у парня по имени Стэнли Рабинович), группирую цифры / создаю последовательность, используя их, 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"
Flonk
источник
1
Я подумал "Хаскелл!" когда я увидел вопрос, прокрутил вниз и улыбнулся.
Сохам Чоудхури