(KevinC's) Triangular DeciDigits Sequence


19

Contribution:

Un entier positif n qui est 1 <= n <= 25000.

Production:

  1. Dans cette séquence, nous commençons par le nombre décimal 1 / n .
  2. Ensuite , nous prenons la somme des chiffres jusqu'à la n ième chiffre après la virgule ( commençant à 1); suivi de la somme des chiffres jusqu'au ( n -1) ème, puis ( n -2) ème, etc. Continuez jusqu'à ce que n soit 1.
  3. La sortie est la somme de tous ces éléments combinés.

Par exemple:

n = 7
1/7 = 0.1428571428...
7th digit-sum = 1+4+2+8+5+7+1 = 28
6th digit-sum = 1+4+2+8+5+7 = 27
5th digit-sum = 1+4+2+8+5 = 20
4th digit-sum = 1+4+2+8 = 15
3rd digit-sum = 1+4+2 = 7
2nd digit-sum = 1+4 = 5
1st digit     = 1
Output = 28+27+20+15+7+5+1 = 103

Règles du défi:

  • Si la décimale de 1 / n n'a pas n chiffres après la virgule, ceux manquants seront comptés comme 0 (c'est-à-dire 1/2 = 0.50 => (5+0) + (5) = 10).
  • Vous prenez les chiffres sans arrondir (c'est-à-dire que les chiffres de 1/6sont 166666et non 166667)

Règles générales:

  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés, des programmes complets. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • Veuillez également ajouter une explication si nécessaire.

1 - 50 premiers de la séquence:

0, 10, 18, 23, 10, 96, 103, 52, 45, 10, 270, 253, 402, 403, 630, 183, 660, 765, 819, 95, 975, 1034, 1221, 1500, 96, 1479, 1197, 1658, 1953, 1305, 1674, 321, 816, 2490, 2704, 4235, 2022, 3242, 2295, 268, 2944, 3787, 3874, 4097, 1980, 4380, 4968, 3424, 4854, 98

24990 - 25000 derniers dans la séquence:

1405098782, 1417995426, 1364392256, 1404501980, 1408005544, 1377273489, 1395684561, 1405849947, 1406216741, 1142066735, 99984

8
Quelqu'un a-t-il mentionné mon nom?
Kevin

Réponses:


6

Gelée , 9 octets

R⁵*:%⁵+\S

Plutôt lent, mais court. Essayez-le en ligne! ou vérifiez les 50 premiers cas de test .

Comment ça fonctionne

R⁵*:%⁵+\S  Main link. Argument: n

R          Range; yield [1, ..., n].
 ⁵*        10 power; yield [10**1, ..., 10**n].
   :       Divide each power by n.
    %⁵     Take each quotient modulo 10.
           This yields all desired decimal digits.
      +\   Take the cumulative sum of the digits.
        S  Take the sum.

15

Mathematica, 42 octets

#&@@RealDigits[1/#,10,#,-1].(#-Range@#+1)&

ou

#&@@RealDigits[1/#,10,#,-1].Range[#,1,-1]&

ou

Tr@Accumulate@#&@@RealDigits[1/#,10,#,-1]&

Explication

Prenez l'exemple de la spécification de défi. Nous voulons calculer:

  1+4+2+8+5+7+1
+ 1+4+2+8+5+7
+ 1+4+2+8+5
+ 1+4+2+8
+ 1+4+2
+ 1+4
+ 1

Réarranger, c'est:

  1*7 + 4*6 + 2*5 + 8*4 + 5*3 + 7*2 + 1*1
= (1, 4, 2, 8, 5, 7, 1) . (7, 6, 5, 4, 3, 2, 1)

.est le produit scalaire de deux vecteurs.

C'est à peu près tout ce que fait la solution.

#&@@RealDigits[1/#,10,#,-1]

Cela nous donne les premiers Nchiffres décimaux de 1/N(le #&@@extrait le premier élément du RealDigitsrésultat car cela renvoie également l'offset du premier chiffre qui nous importe peu).

Ensuite, nous obtenons la liste de Nbas en 1utilisant (#-Range@#+1)ou Range[#,1,-1], qui sont tous deux plus courts que Reverse@Range@#, et prenons le produit scalaire.

La solution alternative utilise Accumulateà la place pour calculer une liste de toutes les sommes de préfixe, puis additionne ces sommes de préfixe avec Tr.

Étant donné que cela est vraiment rapide, même pour les grandes entrées, voici un nuage de points de la séquence jusqu'à N = 100,000( tout faire et les tracer a pris du temps cependant):

entrez la description de l'image ici
Cliquez pour une version plus grande.

La ligne bleue est la limite supérieure naïve de 9 N (N+1) / 2(si tous les chiffres décimaux étaient 9) et la ligne orange en est exactement la moitié. Sans surprise, c'est juste à l'intérieur de la branche principale de l'intrigue car, statistiquement, nous nous attendrions à ce que le chiffre moyen soit de 4,5.

La fine ligne de points de tracé que vous pouvez voir sous la branche principale sont des fractions qui se terminent ...3333..., car elles se trouvent toutes très près 3 N (N+1) / 2.


Très belle réponse, et j'adore le graphique-plot! Il est presque dommage que ce ne soit pas le plus court et je ne peux pas l'accepter comme réponse. :) Si je n'oublie pas, je pourrais faire une petite prime en deux jours pour avoir répondu bien plus que la simple mission que j'ai donnée.
Kevin Cruijssen du

1
@KevinCruijssen Merci! :)
Martin Ender

6

05AB1E , 12 11 octets

Di<ë°¹÷.pSO

Essayez-le en ligne! ou une suite de tests pour les 50 premiers numéros.

Explication

              # implicit input n
Di<           # if n == 1 then 0
   ë          # else
    °¹÷       # 10^n // n
       .p     # get prefixes
         SO   # sum digits

Une version plus efficace pour essayer de grands nombres sur TIO

La différence par rapport à la version plus courte est que nous additionnons ici le produit des chiffres et l'inversion de leur index basé sur 1 au lieu de sommer les chiffres dans les préfixes.

Di<ë°¹÷SDgLR*O

Essayez-le en ligne!


5

Java 8, 181 169 166 166 153 142 octets

import java.math.*;n->{int m=n+2,r=0,i;for(;m>2;)for(i=m--;i-->2;r+=(BigDecimal.ONE.divide(new BigDecimal(n),n,3)+"").charAt(i)-48);return r;}

Explication:

Essayez-le ici.

import java.math.*;   // Required import for BigDecimal

n->{                  // Method with integer as both parameter and return-type
  int m=n+2,          //  Copy of the input-integer plus 2
      r=0,            //  Result-integer, starting at 0
      i;              //  Index-integer
  for(;m>2;)          //  Loop (1) as long as `m` is larger than 2
    for(i=m--;        //   Set index `i` to `m`, and decrease `m` by one afterwards
        i-->2;        //   Inner loop (2) from `m` down to 2 (inclusive)
      r+=             //    Add to the result-sum:
         (BigDecimal.ONE.divide(
                      //     1 divided by,
           new BigDecimal(n),
                      //     the input
           n,3)       //     With the minimal required precision
          +"")        //     Convert this to a String
          .charAt(i)  //     Take the character of this String at index `i`
          -48         //     And convert it to a number
     );               //   End of inner loop (2)
                      //  End of loop (1) (implicit / single-line body)
  return r;           //  Return result
}                     // End of method

4

PHP, 66 65 octets

for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;

Adapté de cette réponse (également par moi): Division des nombres pas si petits et modification suggérée par Jörg Hülsermann. Utilisez comme:

php -r "for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;" 7

edit: correction d'un bug pour +1 octet et repliement de l'affectation de $ a dans $ argv [1] pour -2 octets pour un net 1 octet de moins.


3

Scala, 84 octets

val b=BigDecimal
def?(& :Int)=1 to&map(x=>(""+b(1)/b(&))slice(2,x+2)map(_-48)sum)sum

Non golfé:

def f(n: Int)={
  val digits = ""+BigDecimal(1)/BigDecimal(n)
  (1 to n).map( x=>
    digits.slice(2, x+2).map(d => d - 48).sum
  ).sum

Explication:

val b=BigDecimal   //define an alias for BigDecimal
def?(& :Int)=      //define a method called ? with an integer & as a parameter
  1 to &           //create a range from 1 to &
  map(x=>          //for each number x...
    (""+b(1)/b(&))   //calculate the fraction
    slice(2,x+2)     //and take the slice starting from the third element,
                     //(dropping the "1.") and containing x elements
    map(_-48)        //for each char, subtract 48 to get the integer value
    sum              //and sum them
  )sum             //and take the sum

Je pourrais économiser quelques octets en exploitant la façon dont le compilateur tokenise: En appelant l'argument &, vous pouvez écrire à la 1 to&mapplace de 1 to n map. La même règle s'applique à def?.


3

Gelée , 11 octets

’aµR⁵*:µDFS

TryItOnline
First 50

Trop lent pour les grands cas de test.

Comment?

’aµR⁵*:µDFS - Main link: n
’           - decrement
 a          - and (to handle special case where n=1, to return 0 rather than 10)
  µ         - monadic chain separation
   R        - range: [1,2,...n]
    ⁵       - literal 10
     *      - exponentiation: [10,100,...,10^n]
      :     - integer division: [10//n,100//n,...,10^n//n]
       µ    - monadic chain separation
        D   - cast to a decimal list [[digits of 10//n],[digits of 100//n],...]
         F  - flatten into one list
          S - sum

2
Je ne pense pas avoir déjà vu une réponse de Jelly où l'explication est une ligne droite ;-)
ETHproductions

J'ai presque mis l' R⁵*équivalent de gauche à droite, mais j'ai ensuite vu la belle ligne droite :)
Jonathan Allan

3

PHP, 76 octets

(Modifier -1 octet - Merci user59178 - votre solution est encore meilleure)

for($c=substr(bcdiv(1,$a=$argv[1],$a),2);$i<$a;)$s+=($a-$i)*$c[$i++];echo$s;

vous pouvez enregistrer un octet (un point-virgule) en déplaçant le $c=blahdans la première partie dufor(;;)
user59178

2

MATL, 19 octets

li/GEY$4LQ)!UYsG:)s

Essayez-le en ligne!

Explication

l       % Push a 1 literal to the stack
i/      % Grab the input (n) and compute 1/n
GE      % Grab the input again and multiply by 2 (2n)
Y$      % Compute the first 2n digits of 1/n after the decimal
4LQ)    % Get only the digits past the decimal point
!U      % Convert to numbers
Ys      % Compute the cumulative sum
G:)     % Get the first n terms
s       % Sum the result and implicitly display

2

Groovy, 87 octets

Cela a été moins douloureux que prévu, et est basé sur ma réponse ici :

{n->(1..n).collect{x->(1.0g.divide(n, n, 1)+"")[2..x+1].getChars().sum()-48*(x)}.sum()}

Explication

1.0g - Utilisez la notation BigDecimal pour l'un.

.divide(n, n, 1)+"" - Divisez par n avec n précision (fonction BigDecimal uniquement) et convertissez en str.

(...)[2..x+1].getChars() - Récupère la sous-chaîne de l'itération courante sous forme de tableau de caractères.

.sum()-48*(x)- Additionnez les valeurs ASCII des caractères et réduisez de 48 pour chaque élément. Cela transforme la valeur d'un chiffre ASCII en un entier économisant essentiellement des octets *.toInteger().

(1..n).collect{...}.sum() - Itérer sur chacun des chiffres de la division, en faisant cette fonction, les obtenir tous dans un seul tableau et additionner.

Économie de 2 octets et efficacité sacrifiée ...

Il s'agit d'une version plus efficace qui ne recalcule pas le BigDecimal à chaque itération.

{n->i=1.0g.divide(n, n, 1)+"";(1..n).collect{x->i[2..x+1].getChars().sum()-48*(x)}.sum()}

2

J, 27 octets

1#.[:+/\-{.10#.inv%<.@*10^]

Usage

L'entrée est un entier étendu.

   f =: 1#.[:+/\-{.10#.inv%<.@*10^]
   (,.f"0) (>: i. 50x) , 24990x + i. 11
    1          0
    2         10
    3         18
    4         23
    5         10
    6         96
    7        103
    8         52
    9         45
   10         10
   11        270
   12        253
   13        402
   14        403
   15        630
   16        183
   17        660
   18        765
   19        819
   20         95
   21        975
   22       1034
   23       1221
   24       1500
   25         96
   26       1479
   27       1197
   28       1658
   29       1953
   30       1305
   31       1674
   32        321
   33        816
   34       2490
   35       2704
   36       4235
   37       2022
   38       3242
   39       2295
   40        268
   41       2944
   42       3787
   43       3874
   44       4097
   45       1980
   46       4380
   47       4968
   48       3424
   49       4854
   50         98
24990 1405098782
24991 1417995426
24992 1364392256
24993 1404501980
24994 1408005544
24995 1377273489
24996 1395684561
24997 1405849947
24998 1406216741
24999 1142066735
25000      99984

Les performances sont bonnes et ne nécessitent qu'environ 3 secondes pour calculer les grands cas de test.

   timex 'f 7x'
0.000119
   timex 'f 24999x'
3.8823
   timex 'f 25000x'
3.14903

Explication

1#.[:+/\-{.10#.inv%<.@*10^]  Input: n
                          ]  Get n
                       10^   Raise 10 to the nth power
                  %          Get the reciprocal of n
                      *      Multiply (1/n) with (10^n)
                   <.@       Floor it
           10#.inv           Convert it to a list of base 10 digits
        -                    Negate n
         {.                  Take the last n values from the list of digits
                             (This is to handle the case for n = 1)
   [:  \                     For each prefix of the list of digits
     +/                        Reduce it using addition to get the sum
1#.                          Convert those sums as base 1 digits and return
                             (This is equivalent to taking the sum)

2

Gelée , 10 octets

⁵*:⁸D+\_ỊS

Pas l'approche la plus courte , mais assez efficace. Essayez-le en ligne!ou vérifiez tous les cas de test .

Comment ça fonctionne

⁵*:⁸D+\_ỊS  Main link. Argument: n (integer)

⁵*          Yield 10**n.
  :⁸        Divide 10**n by n (integer division).
    D       Convert the quotient to base 10.
     +\     Take the cumulative sum of the digits.
        Ị   Insignificant; yield (abs(n) <= 1).
       _    Subtract the resulting Boolean from each decimal digit.
            This takes care of edge case n = 1, which would return 2 otherwise.
         S  Take the sum.

1

Python 2, 90 octets

lambda o:sum([sum([int(i)for i in s])for s in map(lambda x:str(1.0/o)[2:x],range(3,3+o))])

Pas joli, mais fait à travers la division flottante puis la conversion en chaîne et ensuite la sélection itérative d'index de chaîne pour obtenir le triangle de nombres, puis effectuer la compréhension de la liste et convertir chaque caractère en entier et enfin les additionner tous.


1

JavaScript (ES6), 47 octets

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

Comment ça fonctionne

Cette réponse illustre une technique pour calculer c chiffres décimaux de a / b :

f=(a,b,c,d=".")=>~c?(a/b|0)+d+f(a%b*10,b,c-1,""):d

Cela constituera un excellent point de départ pour ce défi. Tout d'abord, nous pouvons le modifier légèrement pour qu'il calcule b chiffres décimaux de 1 / b , en réorganisant les paramètres et en définissant les valeurs par défaut:

f=(b,a=1,c=b,d=".")=>~c?(a/b|0)+d+f(b,a%b*10,c-1,""):d

Ensuite, nous pouvons changer cela pour qu'il calcule la somme des b premiers chiffres décimaux, au lieu de les concaténer (cela supprime le dparamètre):

f=(b,a=1,c=b)=>~c?(a/b|0)+f(b,a%b*10,c-1):0

Nous sommes presque à une solution; il suffit maintenant de multiplier chaque chiffre par c + 1 :

f=(b,a=1,c=b)=>~c?(a/b|0)*-~c+f(b,a%b*10,c-1):0

Hmm, cela semble un peu long. Et si on augmentait d'abord c de 1?

f=(b,a=1,c=b+1)=>c?(a/b|0)*c+f(b,a%b*10,c-1):0

Cela économise un octet. Et voici un moyen d'en sauver un de plus:

f=(b,a=1,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

Et maintenant, nous avons notre réponse. f(7)est 103, f(11)est 270, f(1)est ... 2? Oh, nous avons oublié de tenir compte du cas où a / b est 1 lors de la première itération (c.-à-d. B est 1). Faisons quelque chose à ce sujet:

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

1 mod b est toujours 1 , sauf si b est 1 , auquel cas il sera égal à 0 . Notre programme est maintenant correct pour toutes les entrées, à 47 octets .


1

Python 2, 49 octets

lambda n:sum(10**-~k/n%10*(n-k)for k in range(n))

Testez-le sur Ideone .


0

C, 53 octets

f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}

Ci-dessous le principal pour faire un test ...

//44,79
#define R return
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define L(i) for(;i-->0;)
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define M main
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue  
main()
{N  k, a=0, b=0, i;

 F(i=1;i<50;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 F(i=24990;i<=25000;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 R 0;
}

/*
f(1)=0 |f(2)=10 |f(3)=18 |f(4)=23 |f(5)=10 |f(6)=96 |f(7)=103 |f(8)=52 |f(9)=45
f(10)=10 |f(11)=270 |f(12)=253 |f(13)=402 |f(14)=403 |f(15)=630 |f(16)=183 |f(17)=660 
f(18)=765 |f(19)=819 |f(20)=95 |f(21)=975 |f(22)=1034 |f(23)=1221 |f(24)=1500
f(25)=96 |f(26)=1479 |f(27)=1197 |f(28)=1658 |f(29)=1953 |f(30)=1305 |f(31)=1674
f(32)=321 |f(33)=816 |f(34)=2490 |f(35)=2704 |f(36)=4235 |f(37)=2022 |f(38)=3242
f(39)=2295 |f(40)=268 |f(41)=2944 |f(42)=3787 |f(43)=3874 |f(44)=4097 |f(45)=1980
f(46)=4380 |f(47)=4968 |f(48)=3424 |f(49)=4854 |
f(24990)=1405098782 |f(24991)=1417995426 |f(24992)=1364392256 |f(24993)=1404501980
f(24994)=1408005544 |f(24995)=1377273489 |f(24996)=1395684561 |f(24997)=1405849947 
f(24998)=1406216741 |f(24999)=1142066735 |f(25000)=99984 
*/

Pourquoi quelqu'un vote contre cela? est-ce à cause d'un bug? est-ce parce que je ne trouve pas le bon min pour lui? Pour moi, ce nombre de caractères est suffisant et ok, n'hésitez pas à cacel cette réponse aussi que l'autre où je ne peux pas parler
RosLuP

3
Comme d'autres ont commenté d'autres réponses de votre part, le but du code golf est de rendre le code aussi court que possible , mais vous continuez à inclure un tas de macros sans raison valable. f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}ne fait que 53 octets.
Dennis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.