Oblicz A (N) / B (N) za pomocą cyfr C (N)

15

Rozważmy trzy sekwencje liczb, A, Bi C:

  • A: Sekwencja oparta na relacjach powtarzalności f(n) = f(n-1)+f(n-2), zaczynająca się od f(1) = 3, f(2) = 4. Sekwencja zaczyna się w ten sposób:3 4 7 11 18 29 47 76 ...
  • B: Liczby zespolone , czyli wszystkie liczby całkowite, które nie są liczbami pierwszymi (lub 1):4 6 8 9 10 12 14 15 16 ...
  • C: Cyfry Pi: 3 1 4 1 5 9 2 6 5 ...

Biorąc pod uwagę dodatnią liczbę całkowitą N < 50, jako argument funkcji lub STDIN, zwraca wartość dziesiętną ułamka A(N)/B(N)z C(N)cyframi po przecinku. Obowiązują normalne zasady zaokrąglania (zaokrąglić w górę, jeśli N + 1 cyfra to 5 lub więcej). Jeśli N-ta cyfra pito zero, należy wypisać liczbę całkowitą. notacja naukowa / standardowy formularz jest akceptowany dla liczb wyższych niż 1000.

To jest kod golfowy, więc wygrywa najkrótsza odpowiedź w bajtach.

Kilka przykładów:

N = 1: 0.750
N = 2: 0.7
N = 3: 0.8750
N = 4: 1.2
N = 6: 2.416666667
N = 10: 11.056
N = 20: 764.8750

Oczywiście obowiązują standardowe zasady gry w golfa.

Funkcja musi zakończyć się w mniej niż dwie minuty na każdym nowoczesnym laptopie.

Stewie Griffin
źródło
Kiedy mówisz C(n)cyfry, czy musimy uwzględniać końcowe zera?
Maltysen
Do którego wkładu obowiązuje termin?
Dennis,
@Dennis, masz na myśli, do którego N? Jeśli tak, to do N = 49. Czy coś jeszcze?
Stewie Griffin,
JavaScript ma ograniczoną dokładność zmiennoprzecinkową wynoszącą 16. W przeszłości zaczniesz uzyskiwać niedokładne wyniki. Czy to w porządku?
Downgoat
1
@vihan Moje rozwiązanie (niepublikowany bankomat) przechowuje pierwsze 49 cyfr pi w ciągu. W rezultacie nie potrzebujesz więcej niż 9 cyfr dokładności, jeśli się o to martwisz.
ETHprodukcje

Odpowiedzi:

9

Pyth, 60 57 58 bajtów

.[K`.Rchu,eGsGQjT7e.ftPZQ)Je/u+/*GHhyHy^TQr^T3ZZT\0+xK\.hJ

Uprząż testowa

Jest to dość proste - oblicz pi, serię Fibonacciego i kompozyty, zaokrąglaj do C (n) cyfr, pad do C (n) cyfr i lokalizację cyfr dziesiętnych, gotowe.

Na): hu,eGsGQjT7

B (n): e.ftPZQ)

C (n): e/u+/*GHhyHy^TQr99ZZT

60 -> 57: Usunięto przypadek specjalny n = 1 w obliczeniach liczby pi.

57 -> 58: Nie stosowałem wystarczająco wysokiej precyzji dla pi dla całego zakresu wejściowego - zwiększono 99 iteracji do 1000 iteracji.

Uwaga na temat zaokrąglania: używa systemu zaokrąglania „najbliższego parzystego” Pythona, a nie systemu „podanego w nieskończoność” określonego przez OP. Różnica ma jednak znaczenie tylko wtedy, gdy cyfry bezpośrednio po punkcie zaokrąglenia są 5000..., np. 1,25 zaokrąglone do 1 cyfry. Sprawdziłem zakres wejściowy i to się nigdy nie zdarza, więc zawsze zwracany jest prawidłowy wynik.

isaacg
źródło
2

PowerShell, 420 bajtów (ayyyyyyyy) 378 bajtów

param($n);[int[]]$p="03141592653589793238462643383279502884197169399375"-Split'';$a=@(0,3,4);for($i=3;$i-lt50;$i++){$a+=$a[$i-1]+$a[$i-2]};$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111";$b=@(0);for($i=4;$i-le70;$i++){if($c[$i]-eq'1'){$b+=$i}};[double]$r=$a[$n]/$b[$n];$q=$p[$n+1];$s="";(0..($q-1))|%{$s+="0"};([math]::Round($r,$q,[MidpointRounding]::AwayFromZero)).ToString("0.$s")

Dzięki isaacg za zaoszczędzenie 41 bajtów, za obliczenie, jak pytanie się zaokrągla. Oznacza, że ​​nie musiałem uwzględniać horrendous [MidpointRounding]::AwayFromZeroi nie musiałem jawnie rzucać jako [double].

To była świetna zabawa!

Rozszerzony:

# Take input N
param($n)

# First digits of pi, stored as integer array
[int[]]$p="03141592653589793238462643383279502884197169399375"-Split''

# Fibonacci sequence A(N)
$a=@(0,3,4)
for($i=3;$i-lt50;$i++){
  $a+=$a[$i-1]+$a[$i-2]
}

# Zero-indexed bitmask for if the n-th integer is composite (1) or not (0)
$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111"

# Populate B(N) as an array using the $c mask
$b=@(0)
for($i=4;$i-le70;$i++){
  if($c[$i]-eq'1'){
    $b+=$i
  }
}

# Calculation Time!
$r=(a($n))/$b[$n]

# A small golf, as $p[$n+1] gets used a couple times
$q=$p[$n+1]

# Need to generate a string of zeroes for padding
$s=""
(0..($q-1))|%{$s+="0"}

# Round the number, then send it to a string so we get the necessary number of zeroes
([math]::Round($r,$q)).ToString("0.$s")

Rekurencja w PowerShell jest ... powolna, powiedzmy, więc musimy zbudować A(N)drugi kierunek i zapisać go w tablicy, a następnie zindeksować.


STARY

Święta krowa, czy wymagania dotyczące mocy zabiły to. Domyślnie PowerShell stosuje zaokrąglanie do najbliższego zaokrąglania a / k / a bankiera, co wymaga użycia wyjątkowo szczegółowego [MidpointRounding]::AwayFromZeroprzełączania stylów zaokrąglania . Ponadto musimy uzupełnić końcowe zera, jeśli takie istnieją. Te dwa wymagania łącznie zmieniły ostatnią parę linii z 20 bajtów [math]::Round($r,$q) do 102 bajtów (od $s=""do +$s)) ... wow.

AdmBorkBork
źródło
Świetny opis / komentowanie! 32 znaki dla [MidpointRounding]::AwayFromZerosamego jest prawie zbyt dobre / złe, aby mogło być prawdziwe ... =)
Stewie Griffin
1
Zobacz moją notatkę dotyczącą zaokrąglania w mojej odpowiedzi. Domyślne zaokrąglanie PowerShell powinno być w porządku.
isaacg
1

JavaScript (ES6), 302 bajty

Jedno słowo: niedokończone.

x=>{a=[0,3,4],b=[0],c='03141592653589793238462643383279502884197169399375';for(i=1;i<x;a[i+2]=a[i]+a[++i]);for(i=1,p=[];++i<70;v=p.every(x=>i%x),(v?p:b).push(i));r=''+Math.round(a[x]/b[x]*(l=Math.pow(10,c[x])))/l;if(x==33)return r;r.indexOf`.`<0&&(r+='.');while(!r[r.indexOf`.`+ +c[x]])r+='0';return r}

Pierwsze 49 cyfr pi jest przechowywanych w ciągu, a pozostałe dwie sekwencje są generowane automatycznie. Zostało to zagrane w golfa w połowie drogi; Jestem (prawie) pewien, że mógłbym wycisnąć z niego kolejne 50 bajtów.

Działa dla wszystkich przypadków testowych i powinien działać dla reszty. Awarie na czymkolwiek większym niż 49 lub mniejszym niż 0 (i tak nigdy nie powinno się z nimi spotkać). Szczególnie podoba mi się jego wynik dla 0:

NaN.
ETHprodukcje
źródło
Dlaczego to jest niedokończone?
Beta Decay
@BetaDecay Miałem na myśli, że jeszcze nie skończyłem grać w golfa. Będę, jak tylko będę miał czas.
ETHprodukcje
1

Oktawa, 276 236 bajtów

Przede wszystkim pomyślałem, że fajnie byłoby skorzystać z pewnej nieograniczonej dokładności w tych narzędziach matematycznych (i odświeżyć trochę wiedzę na ten temat), więc zacząłem pisać algorytmy, a potem w końcu dowiedziałem się, że piwartość nie jest tak dokładna, że ​​ja będzie musiał ponownie użyć tablicy. Więc znowu nie ma wielkiego sukcesu:

function c(A)p="3141592653589793238462643383279502884197169399375";f=ones (1,50);f(1)=3;f(2)=4;for i=3:53f(i)=f(i-1)+f(i-2);end
i=0;x=1;while i<A
x++;for j=2:x/2
if mod(x,j)==0 i++;break;end end end
printf(["%." p(A) "f\n"],f(A)/x);end

Nadal dość czytelny, prawda?

Stosowanie

skopiuj i wklej funkcję do oktawy, wywołaj funkcję cz argumentem wymaganej wartości:

>>> c(1)
0.750
>>> c(49)
407880480.04348

Optymalizacje:

  • Zastępca endif, endfora podobna end, który działa w ten sam sposób
  • zmniejszanie zmiennej io jeden zapis o jeden bajt
  • usuń num2str(str2num(p(A)))bzdury :)
Jakuje
źródło
Podoba mi się, że opublikowałeś rozwiązanie Octave (sam jestem facetem MATLAB!). Pamiętaj, że ten kod jest tylko oktawą, a nie MATLAB. MATLAB używa endnie endiftyle zapisanych bajtów. Jeśli zdarzy się, że również symboliczne Toolbox dla MATLAB, można użyć vpa, aby uzyskać wystarczającą ilość punktów dziesiętnych do p: vpa(sym(pi),49). Nie mam go na tym laptopie, więc nie jestem pewien, czy symjest to konieczne, ale i tak powinien zaoszczędzić sporo bajtów =) A czytelność niekoniecznie jest dobra w kodzie golfa =)
Stewie Griffin
x ++ nie jest także poleceniem MATLAB. Nie wiedziałem, że między nimi są tak duże różnice ... IMO, nie powinno tak być. Myślę, że cały kod napisany w Octave powinien być przenośny dla MATLAB (ale niekoniecznie na odwrót, ponieważ MATLAB ma więcej opcji).
Stewie Griffin,
Zatwierdziłem Twoją edycję. Nie mam tutaj Matlaba, więc nie mogłem go przetestować. Szukałem rozwiązania, aby uzyskać więcej miejsc po przecinku w oktawie, ale niestety nic nie było krótsze niż tylko tablica, niestety. Ale ommiting whileod endwhilei podobnych działa dobrze, więc jestem aktualizowania odpowiedź z kilku mniejszych znaków :)
Jakuje