Calculez A (N) / B (N) avec C (N) chiffres

15

Considérons trois séquences de nombres A, Bet C:

  • A: Une séquence basée sur les relations de récurrence f(n) = f(n-1)+f(n-2), en commençant par f(1) = 3, f(2) = 4. Ainsi, la séquence commence comme ceci:3 4 7 11 18 29 47 76 ...
  • B: Les nombres composites , c'est-à-dire tous les entiers qui ne sont pas des nombres premiers (ou 1):4 6 8 9 10 12 14 15 16 ...
  • C: Les chiffres de Pi: 3 1 4 1 5 9 2 6 5 ...

Étant donné un entier positif N < 50, comme argument de fonction ou STDIN, renvoyer la valeur décimale de la fraction A(N)/B(N)avec des C(N)chiffres après le point décimal. Les règles normales d'arrondi s'appliquent (arrondir si le N + 1ème chiffre est égal ou supérieur à 5). Si le Nième chiffre de piest zéro, un entier doit être imprimé. notation scientifique / La forme standard est acceptée pour les nombres supérieurs à 1000.

C'est le golf de code, donc la réponse la plus courte en octets l'emporte.

Quelques exemples:

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

Bien sûr, les règles de golf standard sont applicables.

La fonction doit se terminer en moins de deux minutes sur tout ordinateur portable moderne.

Stewie Griffin
la source
Lorsque vous dites des C(n)chiffres, devons-nous inclure des 0 à la fin?
Maltysen du
À quelle entrée le délai s'applique-t-il?
Dennis
@ Dennis, tu veux dire à quoi N? Si oui, jusqu'à N = 49. Ou autre chose?
Stewie Griffin du
JavaScript a une précision limitée en virgule flottante de 16. Passé, vous commencerez à obtenir des résultats inexacts. Est-ce correct?
Downgoat
1
@vihan Ma solution (ATM non publié) stocke les 49 premiers chiffres de pi dans une chaîne. Et vous n'avez pas besoin de plus de 9 chiffres de précision dans le résultat, si cela vous inquiète.
ETHproductions

Réponses:

9

Pyth, 60 57 58 octets

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

Harnais de test

C'est assez simple - calculer pi, la série de fibonacci et les composites, arrondir aux chiffres C (n), remplir les chiffres C (n) plus l'emplacement des chiffres du point décimal, c'est fait.

Un): hu,eGsGQjT7

B (n): e.ftPZQ)

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

60 -> 57: nettoyé le cas spécial n = 1 dans le calcul pi.

57 -> 58: n'utilisait pas une précision suffisamment élevée pour pi pour toute la plage d'entrée - augmentation de 99 itérations à 1000 itérations.

Remarque sur l'arrondi: Ceci utilise le système d'arrondi "le plus proche" de Python, plutôt que le système "vers l'infini" spécifié par l'OP. Cependant, la différence n'a d'importance que si les chiffres qui suivent immédiatement le point d'arrondi sont 5000..., par exemple, 1,25 arrondis à 1 chiffre. J'ai vérifié la plage d'entrée, et cela ne se produit jamais, donc le résultat correct est toujours retourné.

isaacg
la source
2

PowerShell, 420 octets (ayyyyyyyy) 378 octets

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")

Merci à isaacg pour avoir économisé 41 octets, pour avoir calculé comment la question arrondit. Cela signifie que je n'ai pas eu à inclure les horribles [MidpointRounding]::AwayFromZeroet que je n'avais pas besoin de les exprimer explicitement en tant que [double].

Celui-ci était très amusant!

Étendu:

# 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")

La récursivité dans PowerShell est ... lente, dirons-nous, nous devons donc construire A(N)l'autre direction et la stocker dans un tableau, puis l'indexer.


VIEUX

Aussi, vache sacrée, les exigences de sortie ont-elles tué cela? Par défaut, PowerShell arrondit au arrondi d'un / k / un banquier le plus proche, ce qui nécessite d'utiliser l'extraordinairement verbeux [MidpointRounding]::AwayFromZeropour changer de style d'arrondi . En plus de cela, nous devons ensuite remplir les zéros de fin, le cas échéant. Ces deux exigences se sont combinées pour faire passer les deux dernières lignes de 20 octets [math]::Round($r,$q) à 102 octets (du $s=""au +$s)) ... wow.

AdmBorkBork
la source
Grande description / commentaire! 32 caractères [MidpointRounding]::AwayFromZeroseuls est presque trop beau / mauvais pour être vrai ... =)
Stewie Griffin
1
Voir ma note sur l'arrondi dans ma réponse. L'arrondi par défaut de PowerShell devrait être correct.
isaacg
1

Javascript (ES6), 302 octets

Un mot: inachevé.

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}

Les 49 premiers chiffres de pi sont stockés dans une chaîne et les deux autres séquences sont générées automatiquement. Cela a été joué au golf à mi-chemin; Je suis (presque) sûr de pouvoir en extraire 50 octets supplémentaires.

Fonctionne pour tous les cas de test et devrait fonctionner pour le reste. Crashes sur quelque chose de plus de 49 ou de moins de 0 (il ne devrait jamais rencontrer ces situations de toute façon). J'aime particulièrement son résultat pour 0:

NaN.
ETHproductions
la source
Pourquoi est-ce inachevé?
Beta Decay
@BetaDecay, je voulais dire que je n'ai pas encore fini de jouer au golf. Je le ferai dès que j'aurai le temps.
ETHproductions
1

Octave, 276 236 octets

Tout d'abord, je pensais que ce serait cool d'utiliser une précision illimitée dans ces outils mathématiques (et de rafraîchir certaines connaissances à ce sujet) alors j'ai commencé à écrire des algorithmes et j'ai finalement fini par découvrir que la pivaleur n'était pas si précise que devra réutiliser le tableau. Encore une fois, pas de grand succès:

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

Encore assez lisible, non?

Usage

fonction copier-coller en octave, appeler la fonction cavec un argument de la valeur requise:

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

Optimisations:

  • Substitut endif, endforet similaire avec endqui fonctionne de la même manière
  • variable décroissante id'une sauvegarde d'un octet
  • supprimer les num2str(str2num(p(A)))bêtises :)
Jakuje
la source
J'aime que vous ayez posté une solution Octave (je suis moi-même MATLAB!). Notez que ce code est uniquement Octave, pas MATLAB. MATLAB utilise end, non endif, autant d'octets enregistrés. Si vous arrive aussi d'avoir la boîte à outils symbolique pour Matlab, vous pouvez utiliser vpapour obtenir suffisamment de points de décimales pour pi: vpa(sym(pi),49). Je ne l'ai pas sur cet ordinateur portable, donc je ne suis pas sûr que ce symsoit nécessaire, mais je dois quand même économiser pas mal d'octets =) Et la lecture n'est pas nécessairement une bonne chose dans le code golf =)
Stewie Griffin
x ++ n'est pas non plus une commande MATLAB. Je ne savais pas qu'il y avait de si grandes différences entre les deux ... OMI, ça ne devrait pas l'être. Je pense que tout le code écrit en Octave devrait être portable sur MATLAB (mais pas nécessairement l'inverse car MATLAB a plus d'options).
Stewie Griffin du
Approuvé votre modification. Je n'ai pas de matlab ici donc je n'ai pas pu le tester. Je cherchais une solution pour obtenir plus de décimales pi en octave, mais rien n'était plus court qu'un simple tableau, malheureusement. Mais ommiter whilede endwhileet travaux similaires fonctionne bien, donc je mets à jour la réponse avec quelques caractères de moins :)
Jakuje